qiankun微前端方案

背景

最近公司业务调整,想要对主业务添加许多较大的功能模块,考虑到多组员协作与后期维护性等因素,因此不想把所有功能模块都在主业务的工程中完成,故而尝试拆分业务模块后使用微前端技术,本文章以 Angular 作为主应用,Vue 作为微应用,写一个简易Demo,记录下集成过程.

一. Angular主应用

主应用采用 Angular18 + NG-ZORRO 脚手架

  1. 生成Angular项目,可以参考 NG-ZORRO
npm install -g @angular/cli
ng new angular-main
ng add ng-zorro-antd
  1. 安装qiankun,可以参考qiankun
npm i qiankun -S
  1. 主应用注册微应用
// 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();
  1. 主应用的主路由文件
// 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) }
];

  1. 主应用的子路由文件
// 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,
      }
    ],
  },
];
  1. 创建容器页面
// vue-sub.component.html 
// 注意:id 要与注册时的配置项container一致
<div id="vue-sub-container" class="qiankun"></div>

二.Vue微应用

微应用采用 Vue3 + Webpack5 方案

  1. 生成Vue项目,可以参考 Vue
npm install -g @vue/cli
vue create vue-sub
  1. 修改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;
}

  1. 修改 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
    }
  }
})
  1. 调整路由文件
// 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/

总结

至此配置完成后,分别运行主应用与子应用即可,后续还会继续更新此文章

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值