背景
最近来了个新项目,老系统升级。老系统本身是个很多应用混在一起的一个公众号应用。因为历史原因很杂。现在要开始一点点升级。很多子模块不能一次完成升级,所以是新老应用并行的情况,我就想到了用微前端改造。
整体架构
架构图.jpg
说明
我选择的是qiankun 这个轮子。主应用、微应用 都选择的是vue2.x(因为老项目都是vue开发,qiankun可以兼容所有框架) 。路由模式都是选择的hash。 但是history模式更优雅一点。但是需要服务器端配置。
- 主应用
a. 安装qiankun
yarn add qiankun
b. 注册微应用入口
// 修改main.js
import { registerMicroApps, start } from 'qiankun';
const getActiveRule = (hash: any) => (location: any) => location.hash.startsWith(hash);
const renderList = [{
// 个人中心
name: 'personalWork',
entry: mode === 'production' ? '/serviceall/child/service1/' : 'http://localhost:8091',
container: '#container',
activeRule: getActiveRule('#/personalWork'),
}, {
// 营销中心
name: 'picture',
entry: mode === 'production' ? '/serviceall/child/service2/' : 'http://localhost:8092',
container: '#container',
activeRule: getActiveRule('#/picture'),
}];
registerMicroApps(renderList); // 注册各个微应用
start(); // 启动qiankun
- 微应用支持独立部署,单独访问
a. 在src下添加public-path.js
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
b. 修改main.js
import './public-path';
let instance: any = null;
function render(props: any = {}) {
const { container } = props;
instance = new Vue({
router,
store,
render: (h) => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
export async function bootstrap() {
console.log('[vue] vue app bootstraped');
}
export async function mount(props: any) {
console.log('[vue] props from main framework', props);
storeTest(props);
render(props);
}
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
// router = null;
}
// 独立运行时
if (!(window as any).__POWERED_BY_QIANKUN__) {
render();
}
c. 修改webpack配置
// develpoment: VUE_APP_PUBLIC_PATH = http://localhost:8091/
// production: VUE_APP_PUBLIC_PATH = /serviceall/child/service1/
const { name } = require('./package');
module.exports = {
publicPath: process.env.VUE_APP_PUBLIC_PATH,
configureWebpack: config => {
config.output.library = `${name}-[name]`;
config.output.libraryTarget = 'umd'; // 把微应用打包成 umd 库格式
config.output.jsonpFunction = `webpackJsonp_${name}`;
}
devServer: {
port: 8091,
headers: {
'Access-Control-Allow-Origin': '*',
},
},
}
效果图
- 服务器部署结构
└── serviceall
├── child
│ └── service1
│ ├── css
│ ├── favicon.ico
│ ├── index.html
│ └── js
├── css
├── favicon.ico
├── index.html
└── js
- 运行截图
- 主应用运行
image
image
- 微应用运行
image
image
- 微应用单独运行
image
image
问题
-
如何确保主应用跟微应用之间的样式隔离
vue-router的hash模式下不支持设置路由的base,需要额外新建一个空的路由页面,将其他所有路由都作为它的children
更多问题--> 查看