微前端框架之qiankun 怎么用?vue3+vite+qiankun 和 react + qiankun
1、什么是微前端微前端是一种前端架构模式核心思想是——把后端微服务的理念搬到前端将一个庞大的巨石单体应用拆成多个独立开发、独立构建、独立部署、运行时聚合的小型前端应用子应用/微应用再由一个主应用基座/Shel负责统一加载和组合。特点就是微前端并不微可以使用多个技术栈独立开发部署2、创建项目1、main-app使用vue3 作为基座pnpm create vuelatest一步步往下走2、app1react 作为子应用npx create-react-app app1一步步往下走3、app2vue3vuecil作为子应用vue create app2使用上面的命令一步步往下走好了 一个主应用两个子应用 创建完成接下来配置main-app 主应用主应用先装个qiankun框架pnpm add qiankun先建个index.jsexport default { microApp: [ { name: app1, entry: //127.0.0.1:8002, activeRule: /app-react, container: #container, props: { parent: base }, }, { name: app2, entry: //127.0.0.1:8003, activeRule: /app-vue, container: #container, props: {}, }, ], }#container 是需要显示的容器id/app-vue 是地址栏的路由路径接下来编写app.vuescript setup import { RouterLink, RouterView } from vue-router import { registerMicroApps, start, addGlobalUncaughtErrorHandler } from qiankun; import config from ./index; const { microApp } config; // 初始化乾坤 const initQiankun () { if (microApp.length) { registerMicroApps(microApp, { beforeLoad(app) { console.log(app, app); }, beforeMount: [() console.log(before mount)], afterMount: () console.log(****afterMount*****), beforeUnmount: () console.log(****beforeUnmount *****), afterUnmount: () console.log(-------afterUnmount *********---) }); } }; if (!window.qiankunStarted) { window.qiankunStarted true; initQiankun(); start({ sandbox: { experimentalStyleIsolation: true, // 样式隔离 }, }); } // 全局的未捕获异常处理器 addGlobalUncaughtErrorHandler(event { console.log(异常, event) }) /script template div nav RouterLink to/首页/RouterLink | RouterLink to/about关于/RouterLink /nav RouterView / div idcontainer/div /div /template style scoped nav { padding: 20px; } nav a { color: #42b883; text-decoration: none; } nav a.router-link-active { font-weight: bold; } /styleregisterMicroApps 这个方法重要需要注册一下你的子应用然后配置app1app1是react 项目需要有个注意点qiankun 必须通过 UMD 全局变量才能“拿到”你的子应用并调用它的生命周期。app1 的package.json 配置修改下端口是8002 启动使用react-app-rewired 进行webpack5改写之后新建下config-overrides.js这个文件const { name } require(./package.json) module.exports { webpack: (config) { config.output.library ${name}-[name] config.output.libraryTarget umd config.output.globalObject window // ✅ webpack 5 专用 config.output.chunkLoadingGlobal webpackJsonp_${name} return config }, devServer: (configFunction) { return (proxy, allowedHost) { const devConfig configFunction(proxy, allowedHost) devConfig.headers { Access-Control-Allow-Origin: *, } devConfig.historyApiFallback true return devConfig } }, }让qiankun框架可以进行跨域拉取app1这个应用的资源不配置浏览器会拦截掉然后新建一下public-path.js这样一个文件if (window.__POWERED_BY_QIANKUN__) { // eslint-disable-next-line no-undef __webpack_public_path__ window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__ }写这一段让主应用可以访问到子应用的资源文件比如图片视频什么的不写的话http://localhost:3001/static/js/main.xxx.jpg 这个会拿不到然后修改index.jsimport ./public-path.js import React from react; import ReactDOM from react-dom/client; import ./index.css; import App from ./App; import reportWebVitals from ./reportWebVitals; let root null async function render(props) { const {container} props root root || ReactDOM.createRoot( container ? container.querySelector(#root):document.getElementById(root) ) root.render( React.StrictMode App / /React.StrictMode ); } // const root ReactDOM.createRoot(document.getElementById(root)); if(!window.__POWERED_BY_QIANKUN__){ render({}) } export async function bootstrap() { console.log([app2] bootstrap) } export async function mount(props) { console.log([app2] mount, props) render(props) } export async function unmount() { console.log([app2] unmount) if (root) { root.unmount() root null } } // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals();这个导入一下重要需要让上面的写法生效这三个是qiankun的生命周期后续需要和主应用通信什么的的可以用到好了接下来配置app2 子应用app2是一个vue3项目首先对vue.config.js 配置下const { defineConfig } require(vue/cli-service) module.exports defineConfig({ transpileDependencies: true, devServer: { port: 8003, headers: { Access-Control-Allow-Origin: *, }, }, configureWebpack: { output: { library: app2, libraryTarget: umd, chunkLoadingGlobal: webpackJsonp-app2, }, }, })端口改8003 使用umd输出然后就是main.js 配置import { createApp } from vue import App from ./App.vue let app null function render(props {}) { const { container } props app createApp(App) app.mount(container ? container.querySelector(#app) : #app) } if (!window.__POWERED_BY_QIANKUN__) { render({}) } export async function bootstrap() { console.log([app2] bootstrap) } export async function mount(props) { console.log([app2] mount, props) render(props) } export async function unmount() { console.log([app2] unmount) if (app) { app.unmount() app null } }最后就是进入 main-apppnpm dev启动应用进入app1和app2 启动应用效果如下http://localhost:5173/app-vue