前言
公司近段时间准备将之前的一个大规模平台进行拆分,拆分成一个个小平台。因此需要采用微前端技术进行重构。调研了目前流行的微前端架构,包含阿里的Qiankun,京东的MicroApp,腾讯的Wujie。对这三个架构使用之后,发现MicroApp具有如下优势:
- 使用简单,开发成本最低。
- 对子应用的侵入最小,只需修改主应用即可。
- 默认支持vite,符合公司架构。
概念
微应用(MicroApp)
微前端是一种页面整合方案,它的核心在于将一个庞大的前端应用拆分成多个独立灵活的小型应用,每个应用都可以独立开发、独立运行、独立部署,再将这些小型应用融合为一个完整的应用,统一展示。

使用
主应用(react + vite)
- 安装依赖
css
npm i @micro-zoe/micro-app --save
- 在App.tsx初始化Micro-App
javascript
import microApp from '@micro-zoe/micro-app';
import { useEffect } from 'react';
function App() {
useEffect(() => {
microApp.start();
},[]);
}
- 嵌入子应用
javascript
import React from 'react'
export default function MicroApp() {
// 返回值会放入数组中传递给setData的回调函数
return (
<micro-app
name='children-app'
url='http://localhost:3003/'
iframe
router-mode='pure'
>
</micro-app>
)
}
url表示子应用的启动地址,name表示子应用的名字,如果子应用是vite需要将其沙箱设置为iframe
跨域
跨域(Cross-Origin)是指在 Web 开发中,浏览器的同源策略(Same-Origin Policy)限制下,一个网页的资源请求与当前页面的源(协议、域名、端口)不同。同源策略是一种安全机制,限制网页从一个源加载的资源与另一个源进行交互,以防止恶意的跨站脚本攻击。因此在实际开发过程中,主应用访问子应用会出现跨域问题。
预检请求(options)
触发条件
- 跨域的情况下,会发生预请求
- 使用了
PUT、DELETE、CONNECT、OPTIONS、TRACE、PATCH
方法 - 人为设置了非规定内的其他首部字段,参考上面简单请求的安全字段集合,还要特别注意
Content-Type
的类型 XMLHttpRequestUpload
对象注册了任何事件监听器- 请求中使用了
ReadableStream
对象
跨域问题解决
MicroApp官方解决跨域的方法是在webpack-dev-server的headers中设置跨域支持。
css
devServer: {
headers: {
'Access-Control-Allow-Origin': '*',
}
},
但在实际项目中,由于项目中的请求携带了token,由于预检请求的原因,设置了这个并不能解决跨域问题。需要对预检请求也要进行跨域处理。根据打包工具的不同,需要对其进行相应的设置。
webpack@4, webpack-dev-server@3
在webpackDevServer.config.js中进行如下配置
javascript
// webpackDevServer.config.js
// 处理访问微应用的跨域问题
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "*"
}
// 微应用请求接口的跨域问题
before(app){
app.use((req, res, next) => {
if (req.method === 'OPTIONS') {
res.header("Access-Control-Allow-Origin", "*")
res.header("Access-Control-Allow-Headers", "*")
res.sendStatus(200)
} else {
next();
}
})
}
webpack@5, webpack-dev-server@4
javascript
// 处理访问微应用的跨域问题
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "*"
}
// 处理options方法不同
onBeforeSetupMiddleware(app){
app.use((req, res, next) => {
if (req.method === 'OPTIONS') {
res.header("Access-Control-Allow-Origin", "*")
res.header("Access-Control-Allow-Headers", "*")
res.sendStatus(200)
} else {
next();
}
})
}
umi@3, express
javascript
// config.dev.ts
devServer: {
beforeMiddlewares: [
(req, res, next) => {
if (req.method === 'OPTIONS') {
res.header("Access-Control-Allow-Origin", "*")
res.header("Access-Control-Allow-Headers", "*")
res.sendStatus(200)
} else {
next();
}
}
],
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "*"
}
}
上述只针对开发环境,对于生产环境,通过nginx配置跨域即可。