公司的一个巨石应用需要改造成为微前端架构,在调研了市场现有微前端框架之后,最后使用了京东出品的micro-app
,想比较于qiankun
,micro-app
具有以下优势:
- 对现有项目改动很小,不需要改造入口文件和导出特定的生命周期,项目侵入性基本等于没有。
- 完整的沙箱机制和样式隔离
- 完整的通信系统,包括主应用和基座应用互相通信,全局通信等。
- 支持多个框架,包括
vite
、nuxt
、next
等。 - 官网教程非常详细,包括手把手教学和示例项目。
qiankun
坑太多,网上看了一圈文章,全是踩坑的。
以下是自己配置项目的一些心得,欢迎大家讨论交流。
项目主应用和基座应用均是vue3
。
- 安装micro-app
在主应用安装,基座应用无需安装
pnpm i @micro-zoe/micro-app -S
- 在主应用入口文件引入
import microApp from '@micro-zoe/micro-app'
microApp.start()
- 为基座应用配置路由,在路由对应组件内引用
<micro-app name="warehouse" :url="url" :baseroute="baseroute" keep-alive></micro-app>
import config from '@/config';
import { computed } from 'vue';
const isPro = process.env.NODE_ENV === 'production';
const baseroute = computed(() => (isPro ? '/main' : '/'));
const url = config.warehouse;
// config配置
const isPro = process.env.NODE_ENV === 'production'
const config = {
warehouse: isPro ? window.location.origin + '/warehouse' : 'http://localhost:5001/'
}
- 主应用和基座应用都采用
history
模式,其余路由配置不变 - 基座应用在
src
目录下添加public-path.js
if (window.__MICRO_APP_ENVIRONMENT__) {
// eslint-disable-next-line
__webpack_public_path__ = window.__MICRO_APP_PUBLIC_PATH__
}
- 主应用
vue.config.js
配置
const isPro = process.env.NODE_ENV === 'production'
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
publicPath: isPro ? '/main/' : '/',
chainWebpack: (config) => {
config.module
.rule('vue')
.use('vue-loader')
.tap((options) => {
options.compilerOptions = {
...(options.compilerOptions || {}),
isCustomElement: (tag) => /^micro-app/.test(tag),
}
return options
})
},
// 其余配置
}
- 基座应用
vue.config.js
配置
const { defineConfig } = require('@vue/cli-service');
const isPro = process.env.NODE_ENV === 'production';
module.exports = defineConfig({
publicPath: isPro ? '/warehouse/' : '/',
transpileDependencies: true,
devServer: {
port: 5001,
headers: {
'Access-Control-Allow-Origin': '*',
},
// 其余配置
}
// 其余配置
nginx
配置
#主应用main
location /main {
alias /usr/share/nginx/html/main;
add_header Access-Control-Allow-Origin *;
proxy_set_header Connection "";
proxy_buffering off;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
if ( $request_uri ~* .*\.(js|css|jpg|pnglgif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)){
add_header Access-Control-Allow-Origin *;
add_header Cache-Control max-age=7776080;
}
try_files $uri $uri/ /main/index.html;
}
#子应用
location /warehouse {
alias /usr/share/nginx/html/warehouse;
add_header Access-Control-Allow-Origin *;
proxy_set_header Connection "";
proxy_buffering off;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
if ( $request_uri ~* .*\.(js|css|jpg|pnglgif|tif|dpg|jpeg|eot|svg|ttf|woff|json|mp4|rmvb|rm|wmv|avi|3gp)){
add_header Access-Control-Allow-Origin *;
add_header Cache-Control max-age=7776080;
}
try_files $uri $uri/ /warehouse/index.html;
}