MicroApp部署(父子均是vite+vue3)
父应用:
首先在父应用中安装microApp
npm i @micro-zoe/micro-app --save
-
main.js
配置🚀 特别需要注意的是:为了兼容vite,需要在启动中配置对应的插件,注意第一处注释中examcenter为中的name值,第二处见注释。
import microApp from '@micro-zoe/micro-app'
microApp.start({
plugins: {
modules: {
// 此处examcenter即应用的name值
examcenter: [{
loader(code) {
if (process.env.NODE_ENV === 'development') {
// 这里 examcenter 需要和子应用vite.config.js中base的配置保持一致
code = code.replace(/(from|import)(\s*['"])(\/examcenter\/)/g, all => {
return all.replace('/examcenter/', 'http://localhost:8020/examcenter/')
})
}
return code
}
}]
}
}
})
view
配置
<micro-app name='examcenter' url='http://localhost:8020/' inline disableSandbox ></micro-app>
-
route.js
配置🐼 需要注意父应用提供一个动态路由留给子应用!
{
path: '/examcenter:page*',
name: 'examcenter',
component: () => import('/@/views/exam/index.vue'),
}
子应用
- vite.config.js (注意两处核心配置注释)
import { defineConfig, loadEnv } from 'vite'
import path from 'path'
import createVitePlugins from './vite/plugins'
// https://vitejs.dev/config/
export default defineConfig(({ mode, command }) => {
const env = loadEnv(mode, process.cwd())
return {
base: '/examcenter',
plugins: [createVitePlugins(env, command === 'build'),
/**
* 核心配置 自定义插件!
*/
(function () {
let basePath = ''
return {
name: "vite:micro-app",
apply: 'build',
configResolved(config) {
basePath = `${config.base}${config.build.assetsDir}/`
},
writeBundle (options, bundle) {
for (const chunkName in bundle) {
if (Object.prototype.hasOwnProperty.call(bundle, chunkName)) {
const chunk = bundle[chunkName]
if (chunk.fileName && chunk.fileName.endsWith('.js')) {
chunk.code = chunk.code.replace(/(from|import\()(\s*['"])(\.\.?\/)/g, (all, $1, $2, $3) => {
return all.replace($3, new URL($3, basePath))
})
const fullPath = join(options.dir, chunk.fileName)
writeFileSync(fullPath, chunk.code)
}
}
}
},
}
})(),
],
resolve: {
// https://cn.vitejs.dev/config/#resolve-alias
alias: {
// 设置路径
'~': path.resolve(__dirname, './'),
// 设置别名
'@': path.resolve(__dirname, './src')
},
// https://cn.vitejs.dev/config/#resolve-extensions
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
},
// vite 相关配置
server: {
port: 8020,
host: true,
open: true,
/**
* 核心配置 应用之间跨域访问!
*/
headers: {
'Access-Control-Allow-Origin': '*',
},
},
}
})
-
入口main.js
🎨 封装挂载和销毁函数,注意window[‘micro-app-xxx’] 中 ‘xxx’ 要与前面设定的name一致
let app = null;
function mount() {
app = createApp(App);
// 全局方法挂载
// app.XXX
directive(app);
app.mount("#my-vite-app");
console.log("微应用child-vite渲染了")
}
// 将卸载操作放入 unmount 函数
function unmount() {
app?.unmount();
// 卸载所有数据监听函数
window.eventCenterForAppNameVite?.clearDataListener();
app = null;
console.log("微应用child-vite卸载了");
}
// 微前端环境下,注册mount和unmount方法
if (window.__MICRO_APP_BASE_APPLICATION__) {
// @ts-ignore
window['micro-app-examcenter'] = { mount, unmount }
} else {
// 非微前端环境直接渲染
mount()
}
注明:
(历史原因)MicroApp并未对vite有较多的支持,其中样式隔离,js沙箱等特性均失效!此外qiankun框架对vite的支持度更低,不使用插件基本无法使用vite。介于此种原因,故采用京东的MicroApp框架,人为干涉样式隔离!
🎄 父子通信方式暂未加入,后续补充;样式无法会进行相互污染,暂未隔离