目录
前言
简介
分离
修改基座
子应用修改
修改vite.config.js编辑
修改index.html
基座修改
处理子应用静态资源
效果
基座与子应用传值
在基座的MicroApp的index页面修改
在子应用的App.tsx文件进行useEffect的监听
效果编辑
去掉菜单栏头部
效果编辑
总结
前言
该文章用的技术栈是React+Vite+Ts,他的microApp配置相对于React和vue配置相对复杂一些,如果您没有了解基础可以看看(2条消息) 新星微前端MicroApp的基础教程_强壮的糙汉子的博客-CSDN博客这篇文章
简介
这个是我们公司所有后台的管理系统,大家可以看大非常非常的复杂,而我在的部门在分销部门,我们只开发这个部分
可是就会发现有两个问题:
1、虽然我们已经在项目中使用vite,但是它启动的时候还是速度不够理想
2、我们有很多部门在一起开发,每次提交拉去的时候都可能会面临冲突问题
基于以上这几点,我们调研现在比较火的微前端,经过了一系列的技术选型最后定了微前端中的新星京东的microApp
分离
我们把项目复制一份,
然后把分销作为子应用,原有项目作为基座
我们把分销的路由进行注释一下,把其全部分离出来(我们先把分离出来,随后分离成功在去删除依赖,以及删除页面,减轻打包负担,从而可以起服务更快)
然后就会发现这个项目被单独分离出来了
修改基座
我们需要创建一个页面,在src文件下,创建一个MicroApp文件,并创建index.tsx文件!
写入如下代码
import React, { useEffect } from 'react'
import microApp from '@micro-zoe/micro-app'
export default function Distribution() {
return (
<micro-app
name='distribution'
url='http://localhost:8001/'
inline // 使用内联script模式
disableSandbox // 关闭沙箱
/>
)
}
我们把子应用分离出来了,但是我们的基座还有页面,我们把基座关于分销的页面路由的element都指向
然后就会看到页面
这一步我们就是分离成功!
以上就是关于个人项目的私有配置,可以进行参考,如下是一些官方的配置!
子应用修改
如上只是分离成功了,但是并没有,达到我们想要的效果,
如果有需要可以看下官方的配置Vite (jd.com)
修改vite.config.js
这是官方给的例子我们进行修改
上面位置可以直接复制,但是需要配置跨域问题
/* eslint-disable import/extensions */
import { writeFileSync } from 'fs'
import path from 'path'
import { join } from 'path'
...
const env = process.env.ENV
...
export default defineConfig({
base: process.env.NODE_ENV === 'production' ? cmsPath[env] : '/distribution',
plugins: [
....
(function () {
let basePath = ''
return {
name: "distribution",
apply: 'build',
configResolved(config) {
basePath = `${config.base}${config.build.assetsDir}/`
},
writeBundle(options, bundle) {
for (const chunkName in bundle) {
if (Object.prototype.hasOwnProperty.call(bundle, chunkName)) {
const chunk = bundle[chunkName]
if (chunk.fileName && chunk.fileName.endsWith('.js')) {
chunk.code = chunk.code.replace(/(from|import\()(\s*['"])(\.\.?\/)/g, (all, $1, $2, $3) => {
return all.replace($3, new URL($3, basePath))
})
const fullPath = join(options.dir, chunk.fileName)
writeFileSync(fullPath, chunk.code)
}
}
}
},
}
})(),
],
...
},
server: {
headers: {
'Access-Control-Allow-Origin': '*',
},
....
},
})
修改index.html
由于我们关闭了沙箱模式
我们的顶级作用于就会泄露为全局作用域
所以我们把index.html中的id="root"换成
<div id="distribution-root"></div>
并且在mian.tsx文件中进行修改
这个原因是,基座的项目id是root,我们子应用的id要为root的话,可能会造成一些无法预知的问题
基座修改
处理子应用静态资源
官方例子
我们进行修改,
注意是在基座的mian.tsx文件下,进行修改!
// entry
// eslint-disable-next-line import/order
import microApp from '@micro-zoe/micro-app'
microApp.start({
plugins: {
modules: {
// appName即应用的name值
distribution: [
{
loader(code) {
if (process.env.NODE_ENV === 'development') {
// 这里 basename 需要和子应用vite.config.js中base的配置保持一致
code = code.replace(/(from|import)(\s*['"])(\/distribution\/)/g, all => {
return all.replace('/distribution/', 'http://localhost:8001/distribution/')
})
}
return code
},
},
],
},
},
})
效果
随后我们就可以看到这个样式!也就是我们成功了4分之三了!
基座与子应用传值
我们会发现,上面的基座路由与子应用路由并不拼配,我们需要用传值的方式让子应用实例去操作子应用路由
在基座的MicroApp的index页面修改
import React, { useEffect } from 'react'
import microApp, { EventCenterForMicroApp } from '@micro-zoe/micro-app'
import { useLocation } from 'react-router-dom'
export default function Distribution() {
const location = useLocation()
console.log(location.pathname) //distribution/goodsPromotion/list
// 注意:每个vite子应用根据appName单独分配一个通信对象 创建实例
window.eventCenterForDistribution = new EventCenterForMicroApp('distribution')
useEffect(() => {
//基座发送数据
microApp.setData('distribution', { path: location.pathname })
}, [location.pathname])
return (
<micro-app
name='distribution'
url='http://localhost:8001/'
inline // 使用内联script模式
disableSandbox // 关闭沙箱
/>
)
}
在子应用的App.tsx文件进行useEffect的监听
const navigate = useNavigate()
useEffect(() => {
if(window.eventCenterForDistribution) {
window.eventCenterForDistribution.addDataListener((data) => {
// 当基座下发跳转指令时进行跳转
if (data.path) {
navigate(data.path)
}
})
}
效果
我们会发现子应用会随着基座路由跳转而跳转了!
去掉菜单栏头部
我们发现子应用全部嵌套早基座上,包含已经有了的菜单栏,以及头部
我们找到子应用的layou页面进行判断
window.__MICRO_APP_BASE_APPLICATION__
这个是,如果在基座环境为true,不再基座为false
我们就可以判断
效果
总结
这个microApp对于新手还是很友好的,官方文档写的蛮详细的,但是对于vite配置,可能会出现一些问题,但是不敢巧,我们公司用的vite,所以,发布了这篇文章。希望大家多多点赞支持!谢谢