小知识,大挑战!本文正在参与「程序员必备小知识」创作活动
本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。
【序】微前端是什么?
微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。
微前端核心
- 技术栈无关
- 主框架不限制接入应用的技术栈,微应用具备完全自主权。
- 独立开发、独立部署
- 微应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新。
- 增量升级
- 在面对各种复杂场景时,我们通常很难对一个已经存在的系统做全量的技术栈升级或重构,而微前端是一种非常好的实施渐进式重构的手段和策略。
- 独立运行时
- 每个微应用之间状态隔离,运行时状态不共享。
微前端解决了什么
微前端架构旨在解决单体应用在一个相对长的时间跨度下,由于参与的人员、团队的增多、变迁,从一个普通应用演变成一个巨石应用后,随之而来的应用不可维护的问题。这类问题在企业级 Web 应用中尤其常见。
一、了解微前端方案之 qiankun
qiankun 是什么?
qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。
特点
- 简单:任意 js 框架均可使用。微应用接入像使用接入一个 iframe 系统一样简单,但实际不是 iframe。
- 完备:几乎包含所有构建微前端系统时所需要的基本能力,如样式隔离、js 沙箱、预加载等等。
- 生产可用:已在蚂蚁内外经受过足够大量的线上系统的考验及打磨,健壮性值得信赖。
特性
- 基于 single-spa
- 技术栈无关
- HTML Entry 接入方式
- 样式隔离
- JS 沙箱
- 资源预加载
- umi 插件系统
安装 qiankun
npm i qiankun -S
二、开始搭建微前端项目
1. 项目环境搭建
- 先创建一个 vue2.0 项目作为基座
vue create qiankun-base
- 然后创建一个 vue2.0 项目作为子项目1
vue create qiankun-vue
- 再创建一个 react 项目作为子项目2
npx create-react-app qiankun-react
- 在 qiankun-base 目录下安装 element-ui 作为项目 ui
npm i element-ui -S
2. 配置主应用 qiankun-base
- 配置导航栏
引入 element 样式后使用其菜单栏,并配置相应路由。
<!-- app.vue 页面 -->
<template>
<div>
<!-- 使用 element 菜单栏 -->
<el-menu :router="true" mode="horizontal">
<!-- 基座中可以放自己的路由 -->
<el-menu-item index="/">Home</el-menu-item>
<!-- 也可以引用其它子应用 -->
<el-menu-item index="/vue">vue 应用</el-menu-item>
<el-menu-item index="/react">react 应用</el-menu-item>
</el-menu>
<!-- 页面渲染 -->
<router-view></router-view>
<div id="vue"></div>
<div id="react"></div>
</div>
</template>
页面效果
- 引入并配置 qiankun
安装好 qiankun 后再 main.js 中进行配置子应用
// 引入 qiankun
import { registerMicroApps, start } from 'qiankun'
// 配置子应用
const apps = [
// 子应用1:qiankun-vue
{
// 子应用名称
name: 'vueAPP',
// 子应用入口;默认会加载这个 html
// 并解析里里面的 js 然后动态的执行(子应用必须支持跨域)
entry: '//localhost:1001',
// 将子应用挂载到 #vue 元素上
container: '#vue',
// 激活规则:访问 /vue 时将子应用挂载到 #vue 上
activeRule: '/vue'
},
// 子应用2:qiankun-react
{
// 子应用名称
name: 'reactAPP',
// 子应用入口;默认会加载这个 html
// 并解析里里面的 js 然后动态的执行(子应用必须支持跨域)
entry: '//localhost:1002',
// 将子应用挂载到 #react 元素上
container: '#react',
// 激活规则:访问 /react 时将子应用挂载到 #react 上
activeRule: '/react'
}
]
// 注册子应用
registerMicroApps(apps)
// 启动 qiankun 微前端
start()
3. 配置子应用1 qiankun-vue
这里需要注意,在配置子应用时是不需要再去额外安装任何包了,qiankun 内部已经自动处理好了。我们子需要进行配置就成。
- router 配置
- main.js 配置
// 存放子应用渲染状态
let instance = null;
// 子应用正常渲染
function render() {
instance = new Vue({
router,
render: (h) => h(App),
}).$mount("#app"); // 挂载到自己的 html 中,然后基座会拿到这个挂在后的 html,并将其插入到主应用当中
}
// 判断当前应用是否不在 qiankun 中渲染
if (!window.__POWERED_BY_QIANKUN__) {
// 如果不在 qiankun 中,则直接渲染
render();
}
// 需要导出 qiankun 内部的三个生命周期钩子,以供主应用在合适的时机调用。
// 第一次进入时;props 包含主应用传递的参数,也包括为子应用创建的节点信息。
export async function bootstrap() {
console.log("微前端加载完成");
}
// 每次进入子应用时
export async function mount(props) {
// 每次进入子应用,渲染子应用
render(props);
}
// 每次退出子应用时
export async function unmount() {
// 卸载子应用
instance.$destroy();
}
- vue.config.js 配置打包环境
新建 vue.config.js 文件进行配置
module.exports = {
// 配置跨域
devServer: {
// 监听端口
port: 1000,
// 配置头信息
headers:{
// 设置任何网站域名都可以访问此项目
'Access-Control-Allow-Origin' : '*'
}
},
// 配置打包结果
configureWebpack:{
output: {
library: 'vueApp',
libraryTarget: 'umd'
}
}
}
- 效果
4. 配置子应用2 qiankun-react
- 安装 react-app-rewired
// 得先安装 yarn
npm i yarn -g
// 再安装 react-app-rewired
yarn add react-app-rewired
- 安装好后将启动项都改为 react-app-rewired
- 新建 config-overrides.js 配置文件
module.exports = {
webpack:(config) => {
config.output.library = 'reactApp'
config.output.libraryTarget = 'umd'
config.output.publicPath = 'http://localhost:1002'
return config
},
devServer:(configFunction) => {
return function(proxy, allowedHost){
const config = configFunction(proxy, allowedHost)
config.port = '1002'
config.headers = {
"Access-Control-Allow-Origin" : '*'
}
return config
}
}
}
- 配置 indx.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
function render() {
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
}
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
// 导出三个声明周期
export async function bootstrap() {}
export async function mount() {
render();
}
export async function unmount() {
ReactDOM.unmountComponentAtNode(document.getElementById("root"));
}
- 效果
三、报错合集
1. qiankun:application ‘vueApp‘ died in status NOT_MOUNTED: [qiankun]: Target container with #vue not
vue2 中将最外层的
改为vue3 中直接将最外层的 div 删除即可
2.'webpack_public_path' is not defined no-undef
不知道为什么会出现这个 BUG,我看其他教程文章都不会出现,不知道有没有人和我一样遇上了这个 BUG。