这篇写一半不想写了,别看了(`へ´*)ノ
介绍
什么是微前端?
微前端是一种类似于微服务的架构,它将微服务的理念应用于浏览器端,即将单页面前端应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。各个前端应用还可以独立开发、独立部署。同时,它们也可以在共享组件的同时进行并行开发——这些组件可以通过NPM
或者Git Tag
、Git Submodule
来管理。
为什么要使用微前端?
- 各个子项目的技术栈是独立的,可以使用任何技术研发。
- 独立子项也可以单独运行。
- 各个子项的状态都是隔离的。
qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。
qiankun 孵化自蚂蚁金融科技基于微前端架构的云产品统一接入平台,在经过一批线上应用的充分检验及打磨后,我们将其微前端内核抽取出来并开源,希望能同时帮助社区有类似需求的系统更方便的构建自己的微前端系统,同时也希望通过社区的帮助将qiankun
打磨的更加成熟完善。
目前qiankun
已在蚂蚁内部服务了超过2000+
线上应用,在易用性及完备性上,绝对是值得信赖的。
开始
本次的demo
项目的代码都在github,可自行查看运行。
本次项目使用umi作为基座,分别配置react
、vue
、angular
、jquery
子应用。
主项目及子项目都只是简单完成了最基础的一些配置,后续可能会继续完善。
umi主应用
version: 4.+
umi
社区有相关接入qiankun
的插件,可以使用插件(@umijs/plugin-qiankun),也可以直接使用qiankun
。
这里是选择使用插件。
- 安装插件
yarn add @umijs/plugin-qiankun -D
- 修改配置文件
.umirc.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import { defineConfig } from '@umijs/max'; import { apps } from './config/qiankun' import routes from './config/routes'
export default defineConfig({ routes, qiankun: { master: { apps } }, });
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| export default [ { name: 'react子应用', path: '/sub-react-project', microApp: 'sub-react-project' }, { name: 'vue子应用', path: '/sub-vue-project', microApp: 'sub-vue-project' }, { name: 'angular子应用', path: '/sub-angular-project', microApp: 'sub-angular-project' }, { name: 'jquery子应用', path: '/sub-jquery-project', microApp: 'sub-jquery-project' },
]
|
- 设置子应用路由配置(
./config/qiankun
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| export const apps = [ { name: 'sub-react-project', entry: '//localhost:5000', container: '#sub-react-project', activeRule: '/sub-react-project', }, { name: 'sub-vue-project', entry: '//localhost:5001', container: '#sub-vue-project', activeRule: '/sub-vue-project', }, { name: 'sub-angular-project', entry: '//localhost:5002', container: '#sub-angular-project', activeRule: '/sub-angular-project', }, { name: 'sub-jquery-project', entry: '//localhost:5003', container: '#sub-jquery-project', activeRule: '/sub-jquery-project', }, ]
|
完成上面的步骤,主应用的搭建就算是完成了。
启动项目就能看到,如下图。
React子应用
version: 18.+
cli: create-react-app 5.+
- 在
/src/packages
下新建react
子应用
yarn create react-app sub-react-project --template typescript
- 安装customize-cra和react-app-rewired扩展配置
yarn add customize-cra react-app-rewired -D
- 修改
package.json
1 2 3 4 5 6
| { "scripts": { "start": "react-app-rewired start", "build": "react-app-rewired build", }, }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| const { override, overrideDevServer, watchAll, } = require('customize-cra'); const packageName = require('./package.json').name
module.exports = { webpack: override( (config) => { config.output = { ...config.output, library: `${packageName}-[name]`, libraryTarget: 'umd', chunkLoadingGlobal: `webpackJsonp_${packageName}`, } return config }, ), devServer: overrideDevServer(config => { config.headers = config.headers || {} config.headers['Access-Control-Allow-Origin'] = '*' return config }, watchAll()) }
|
- 增加publicPath.js文件(
./src/publicPath.js
)
1 2 3 4 5 6
| if (window.__POWERED_BY_QIANKUN__) { __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| import React from 'react'; import ReactDOM from 'react-dom/client'; import { createHashRouter, RouterProvider, } from "react-router-dom"
import './publicPath' import routes from './routes'
let root: ReactDOM.Root;
if (!window.__POWERED_BY_QIANKUN__) { render() }
function render(props?: any) { root?.unmount()
root = ReactDOM.createRoot( document.getElementById('sub-react-project') as HTMLElement ); const router = createHashRouter(routes); root.render(<RouterProvider router={router} fallbackElement={<div>数据加载中...</div>} />); }
export async function bootstrap() {}
export async function mount(props: any) { render(props) }
export async function unmount(props: any) { root?.unmount() }
export async function update(props: any) {}
|
完成上面的步骤,子应用的搭建就算是完成了。
启动项目就能看到,如下图。

Vue子应用
version: 3.+
cli: 5.+
- 在
/src/packages
下新建vue
子应用
vue create sub-vue-project
跟着步骤初始化
- 同样按照上面
react
子应用的配置修改vue.config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const path = require('path') const { name: packageName } = require('./package.json')
module.exports = { configureWebpack: { output: { library: `${packageName}-[name]`, libraryTarget: 'umd', jsonpFunction: `webpackJsonp_${packageName}`, }, }, devServer: { port: 5001, headers: { "Access-Control-Allow-Origin": "*", }, }, }
|
- 同样创建
publicPath.js
- 同样在入口文件新增配置(
./src/main.js
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| import { createApp } from 'vue' import { createRouter, createWebHashHistory } from 'vue-router' import routes from './config/routes' import './publicPath' import App from './App.vue'
let root; let router
function render() { router = createRouter({ history: createWebHashHistory(), routes })
root = createApp(App) root.use(router) root.mount('#sub-vue-project') }
if (!window.__POWERED_BY_QIANKUN__) { render() }
export async function bootstrap() {}
export async function mount(props) { render(props) }
export async function unmount() { root.$destroy() root = null router = null }
export async function update(props) {}
|
完成上面的步骤,子应用的搭建就算是完成了。
启动项目就能看到,如下图。

Angular子应用
version: 15.+
Jquery子应用
version: 3.+
这里代表的是一些使用传统三剑客开发的应用。
- 将项目放置在
/src/packages/sub-jquery-project/src
目录下
- 启用应用
因为不存在webpack
编译,直接使用express
启动node
服务来进行访问。
npm init
npm install express cors
npm install nodemon -D
(nodemon可以监听文件的变化刷新node服务)
- 修改
package.json
文件
1 2 3 4 5
| { "scripts": { "start": "nodemon index.js" } }
|
- 新建启动服务脚本(
/sub-jquery-project/index.js
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const express = require("express"); const cors = require("cors"); const chalk = require('chalk')
const app = express();
app.use(cors());
app.use('/', express.static('src'));
app.listen(5003, () => { console.log(chalk.green("server is listening in http://localhost:5003")) });
|
此时cmd
启动npm run start
,访问http://localhost:5003
即可看到内容
- 接入
qiankun
脚本(/sub-jquery-project/src/js/entry.js
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| const render = ($, isSub=false) => { $('#sub-jquery-project').append(`And, I am mount in ${isSub ? 'sub' : 'self'}`); return Promise.resolve(); };
if(!window.__POWERED_BY_QIANKUN__) { render($) }
((global) => { global['sub-jquery-project'] = { bootstrap: () => { return Promise.resolve(); }, mount: () => { return render($, true); }, unmount: () => { return Promise.resolve(); }, }; })(window);
|
完成上面的步骤,子应用的搭建就算是完成了。
启动项目就能看到,如下图。

一些问题
子应用静态资源404
结束
参考链接
微前端实战 - 基于 qiankun 的最佳实践
项目实践
微前端系列讲解–应用集成方案(qiankun+umi+vue)
基于qiankun的微前端最佳实践 -(同时加载多个微应用)
Create React App无eject配置(react-app-rewired 和 customize-cra)
Angular刷新浏览器 404 问题
qiankun angular12 single-spa-angular子应用的改造