这是我参与「第四届青训营」笔记创作活动的的第13天
微前端
原因:团队成员使用不同的技术栈,考虑到时间紧、任务重,没有时间成本去学习新的技术,因此采用微前端技术确保团队能合作开发,且项目各模块能正常运行。
优点:
- 技术栈无关
主框架不限制接入应用的技术栈,微应用具备完全自主权 - 独立开发、独立部署
微应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新 - 增量升级
在面对各种复杂场景时,我们通常很难对一个已经存在的系统做全量的技术栈升级或重构,而微前端是一种非常好的实施渐进式重构的手段和策略 - 独立运行时
每个微应用之间状态隔离,运行时状态不共享
使用 qiankun 开发微前端。
实践过程
基座配置
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'reactApp',
entry: '//localhost:3000',
container: '#container',
activeRule: '/app-react',
},
{
name: 'vueApp',
entry: '//localhost:8080',
container: '#container',
activeRule: '/app-vue',
},
{
name: 'angularApp',
entry: '//localhost:4200',
container: '#container',
activeRule: '/app-angular',
},
]);
// 启动 qiankun
start();
子应用配置
- 在
src目录新增public-path.js,解决子应用挂载时,访问静态资源冲突
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
- 入口文件
index.js修改,为了避免根 id#root与其他的 DOM 冲突,需要限制查找范围。
import './public-path';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
function render(props) {
const { container } = props;
ReactDOM.render(<App />, container ? container.querySelector('#root') :
document.querySelector('#root'));
}
if (!window.__POWERED_BY_QIANKUN__) {
render({});
}
export async function bootstrap() {
console.log('[react16] react app bootstraped');
}
export async function mount(props) {
console.log('[react16] props from main framework', props);
render(props);
}
export async function unmount(props) {
const { container } = props;
ReactDOM.unmountComponentAtNode(container ? container.querySelector('#root') :
document.querySelector('#root'));
}
- 修改
webpack配置
安装插件 @rescripts/cli,当然也可以选择其他的插件,例如 react-app-rewired。
npm i -D @rescripts/cli`
- 根目录新增
config-overrides.js
const { name } = require('./package');
module.exports = {
webpack: (config) => {
config.output.library = `${name}-[name]`;
config.output.libraryTarget = 'umd';
config.output.jsonpFunction = `webpackJsonp_${name}`;
config.output.globalObject = 'window';
return config;
},
devServer: (_) => {
const config = _;
config.headers = {
'Access-Control-Allow-Origin': '*',
};
config.historyApiFallback = true;
config.hot = false;
config.watchContentBase = false;
config.liveReload = false;
return config;
},
};
启动
配置完子应用和基座后,需要将各个项目都 启动 ,否则会报错。
实践问题
Uncaught TypeError: application 'qiankun-micro-app1' died in status LOADING_SOURCE_CODE: Failed to fetch
解决方法:来自 github 的提醒:
Uncaught Error: application 'qiankun-micro-app1' died in status LOADING_SOURCE_CODE: [qiankun]: You need to export lifecycle functions in qiankun-micro-app1 entry
- 启动服务时报错:
Uncaught TypeError: application 'micro-app4' died in status SKIP_BECAUSE_BROKEN: vue_router__WEBPACK_IMPORTED_MODULE_5__.default is not a constructor