qiankun-前端微服务化搭建
创建vue项目 vue create qiankun-base
安装qiankun 插件 $ yarn add qiankun # 或者 npm i qiankun -S
只需要在主应用安装qiankun 即可,最重要的是webpack版本必须在4.0.0,不然会报jsonpfunction 错误。
主应用 首先在主应用的 main.js里边只做了两件事,就是注册子应用和启动qiankun
import { registerMicroApps, start, setDefaultMountApp } from "qiankun" //当匹配到 activeRule 的时候,请求获取 entry 资源,渲染到 container 中 const apps = [{ name: 'vueApp', entry: '//localhost:8081', //子应用的html入口 container: '#container', //渲染入口节点 activeRule: '/app-vue', //路由匹配规则 props: { msg: "我是子应用app-vue" } }, { name: 'reactApp', entry: '//localhost:8082', container: '#container', activeRule: '/app-react', props: { msg: "我是子应用app-react" } }, ] //微前端运行原理类似于SPA registerMicroApps(apps); // 启动 qiankun start(); //默认渲染的子应用 // setDefaultMountApp("/app-vue");
主应用的app.vue 文件
<template> <div> <el-menu :router="true" mode="horizontal"> <!-- 子应用 --> <el-menu-item index="/">home</el-menu-item> <el-menu-item index="/app-vue">vue</el-menu-item> <el-menu-item index="/app-react">react</el-menu-item> </el-menu> <!-- 主应用路由出口 --> <router-view /> <div id="container"></div> </div> </template>
vue子应用
main.js
按如下修改import './public-path'; import Vue from 'vue' import App from './App.vue' import VueRouter from 'vue-router'; import routes from './router' import store from './store' Vue.config.productionTip = false let router = null; let instance = null; function render(props = {}) { const { container } = props; router = new VueRouter({ base: window.__POWERED_BY_QIANKUN__ ? '/app-vue/' : '/', mode: 'history', routes, }); instance = new Vue({ router, store, render: (h) => h(App), }).$mount(container ? container.querySelector('#app') : '#app'); } // 独立运行时 加载的是当前文档的节点 if (!window.__POWERED_BY_QIANKUN__) { render(); } //生命周期函数必须返回promise export async function bootstrap() { console.log('初始化 只执行一次'); } export async function mount(props) { console.log('渲染函数', props); render(props); } export async function unmount() { console.log("卸载函数"); instance.$destroy(); instance.$el.innerHTML = ''; instance = null; router = null; }
项目根目录中添加
vue.config.js
let { name } = require('./package'); module.exports = { devServer: { port: 8081, //允许跨域 headers: { 'Access-Control-Allow-Origin': '*', }, }, configureWebpack: { output: { library: `${name}-[name]`, libraryTarget: 'umd', // 把微应用打包成 umd 库格式 jsonpFunction: `webpackJsonp_${name}`, }, }, };
src目录下添加public-path.js
//webpack 在运行时生成的路径会自动拼接上这个全局变量(如果有的话) if (window.__POWERED_BY_QIANKUN__) { __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__; }
package.json
中添加 目的是暴漏
__webpack_public_path__
//暴漏全局变量
{ "eslintConfig": { "globals": { "__webpack_public_path__": true } } }
路由文件中 index.js
//history模式 const router = new VueRouter({ mode: 'history', base: '/vue', routes }) //hash模式 const router = new VueRouter({ mode: "hash", base: window.__POWERED_BY_QIANKUN__ ? "/child/" : "/", routes, });
react 子应用
创建react项目 npx create-react-app qiankun-react
重写webpack配置 yarn add react-app-rewired
修改 package.json 文件
"scripts": { "start": "react-app-rewired start", "build": "react-app-rewired build", "test": "react-app-rewired test", "eject": "react-app-rewired eject" },
react 子应用 index.js 文件配置
import './index.css'; import './public-path'; import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; function render(props) { const { container } = props; ReactDOM.render( < App / > , container ? container.querySelector('#root') : document.querySelector('#root')); } if (!window.__POWERED_BY_QIANKUN__) { render({}); } export async function bootstrap() { console.log('[react16] react app bootstraped'); } export async function mount(props) { console.log('[react16] props from main framework', props); render(props); } export async function unmount(props) { const { container } = props; ReactDOM.unmountComponentAtNode(container ? container.querySelector('#root') : document.querySelector('#root')); }
index.js 同级目录下添加public-pathpath.js文件
if (window.__POWERED_BY_QIANKUN__) { __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__; }
根目录下 手动添加 config-overrides.js
const { name } = require('./package'); module.exports = { webpack: (config) => { config.output.library = `${name}-[name]`; config.output.libraryTarget = 'umd'; // config.output.jsonpFunction = `webpackJsonp_${name}`; config.output.globalObject = 'window'; config.output.publicPath = 'http://localhost:8082/'; return config; }, devServer: (_) => { const config = _; config.headers = { 'Access-Control-Allow-Origin': '*', }; config.historyApiFallback = true; config.hot = false; config.watchContentBase = false; config.liveReload = false; return config; }, };
根目录 创建 .env 文件 配置端口
PORT=8082 WDS_SOCKET_PORY=8082 //默认的端口是3000