背景
最近公司业务调整,想要对主业务添加许多较大的功能模块,考虑到多组员协作与后期维护性等因素,因此不想把所有功能模块都在主业务的工程中完成,故而尝试拆分业务模块后使用微前端技术,本文章以 Angular 作为主应用,Vue 作为微应用,写一个简易Demo,记录下集成过程.
一. Angular主应用
主应用采用 Angular18 + NG-ZORRO 脚手架
- 生成Angular项目,可以参考 NG-ZORRO
npm install -g @angular/cli
ng new angular-main
ng add ng-zorro-antd
- 安装qiankun,可以参考qiankun
npm i qiankun -S
- 主应用注册微应用
// main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, appConfig)
.catch((err) => console.error(err));
// 以下为注册微应用代码
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'vue-sub',//子应用的项目名称
entry: '//localhost:8080',// 本地调试,需同时运行子工程(发布需改为实际地址)
container: '#vue-sub-container',// html的id名
activeRule: '/vue-sub',//主应用跳转子应用的路由
},
]);
// 启动 qiankun
start();
- 主应用的主路由文件
// app.routes.ts
import { Routes } from '@angular/router';
export const routes: Routes = [
{ path: '', pathMatch: 'full', redirectTo: '/welcome' },
{ path: 'welcome', loadChildren: () => import('./pages/welcome/welcome.routes').then(m => m.WELCOME_ROUTES) },
{ path: 'monitor', loadChildren: () => import('./pages/monitor/monitor.routes').then(m => m.MONITOR_ROUTES) },
{ path: 'vue-sub', loadChildren: () => import('./pages/vue-sub/vue-sub.routes').then(m => m.VUE_SUB_ROUTES) },
{ path: 'react-sub', loadChildren: () => import('./pages/react-sub/react-sub.routes').then(m => m.REACT_SUB_ROUTES) }
];
- 主应用的子路由文件
// vue-sub.routes.ts
import { Routes } from '@angular/router';
import { VueSubComponent } from './vue-sub.component';
export const VUE_SUB_ROUTES: Routes = [
{
path: '',
component: VueSubComponent,
children: [
{
path: '**', // 此处为了实现子路由的全量匹配,否则会找不到子工程的子路由
component: VueSubComponent,
}
],
},
];
- 创建容器页面
// vue-sub.component.html
// 注意:id 要与注册时的配置项container一致
<div id="vue-sub-container" class="qiankun"></div>
二.Vue微应用
微应用采用 Vue3 + Webpack5 方案
- 生成Vue项目,可以参考 Vue
npm install -g @vue/cli
vue create vue-sub
- 修改main,js
// main.js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router'
let app = null;
function render(props = {}) {
const { container } = props;
app = createApp(App).use(router);
app.mount(container ? container.querySelector('#app') : '#app');
}
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap() {
console.log('[vue3] vue3 app bootstraped');
}
export async function mount(props) {
console.log('[vue3] props from main framework', props);
render(props);
}
export async function unmount() {
app.unmount();
app = null;
}
- 修改 vue.config.js
// vue.config.js
const { defineConfig } = require("@vue/cli-service")
module.exports = defineConfig({
transpileDependencies: true,
// 本地调试时要写配置,原因是publicPath为"/"时.会从主工程路径下发起资源请求,无法找到子工程资源,因此需要将publicPath指向当前子 工程的端口,保证子应用静态资源都是从子应用的端口请求
publicPath: "//localhost:9000",
devServer: {
headers: {
"Access-Control-Allow-Origin": "*"
},
port: 9000
},
configureWebpack: {
output: {
library: `vue-sub`,
libraryTarget: "umd", // 把微应用打包成 umd 库格式
chunkLoadingGlobal: `webpackJsonp_vue-sub` // webpack 5 需要把 jsonpFunction 替换成 chunkLoadingGlobal
}
}
})
- 调整路由文件
// router/index.js
import { createRouter, createWebHistory } from "vue-router"
import Home from "@/views/home/index.vue"
const routes = [
{
path: "/",
name: "Home",
component: Home
},
{
path: "/person",
name: "Person",
component: () => import("@/views/person/index.vue")
}
]
const router = createRouter({
history: createWebHistory(window.__POWERED_BY_QIANKUN__ ? "/vue-sub/" : "/"), // 在qiankun模式下,需要设置base与主应用的地址一致
routes
})
export default router
三.主应用与微应用传参
主应用向微应用传参
// 主应用main.js
registerMicroApps([
{
name: 'vue-sub',//子应用的项目名称
entry: '//localhost:8080',// 本地调试,需同时运行子工程(发布需改为实际地址)
container: '#vue-sub-container',// html的id名
activeRule: '/vue-sub',//主应用跳转子应用的路由
props: {
userInfo: {
id: 'xxxx',
name: 'xxxx',
},
},
},
]);
// 微应用main.js
export async function mount(props) {
console.log('[vue] props from main framework', props)
render(props)
}
四.发布线上环境配置
当发布正式环境时,需要做出配置调整,以下为示例
主应用访问地址: http://www.example.com/main/home
子应用访问地址: http://www.example.com/sub/test
主应用调整部分
// main.js
registerMicroApps([
{
name: 'vue-sub', //子应用的项目名称
entry: 'http://www.example.com/sub/test', // 实际地址
container: '#vue-sub-container', //html的id名
activeRule: `${environment.PUBLIC_PATH}vue-sub`, //主应用跳转子应用的主路径
},
]);
注意: PUBLIC_PATH 在dev环境中配置为PUBLIC_PATH = / ;在prod环境中配置为PUBLIC_PATH = /main/
子应用调整部分
// router/index.js
const router = createRouter({
history: createWebHistory(window.__POWERED_BY_QIANKUN__ ? `${process.env.VUE_APP_QIANKUN_PATH}vue-sub/`: "/"), // 在qiankun模式下,需要设置base与主应用的地址一致
routes
})
注意: VUE_APP_QIANKUN_PATH 在dev环境中配置为VUE_APP_QIANKUN_PATH = / ;在prod环境中配置为VUE_APP_QIANKUN_PATH= /main/
总结
至此配置完成后,分别运行主应用与子应用即可,后续还会继续更新此文章
347

被折叠的 条评论
为什么被折叠?



