前言
大家好,我是海怪。最近换到了新部门,在做智能平台相关的内容。我接到的第一个任务就是把以前前端的项目重构一次。
说是重构,不如说是重写一遍。因为原来的项目是 ant-design-vue + vue 全家桶
,要切换成 ant-design + ant-design-pro + react 全家桶
。
更让人头疼的是,产品经理并不会让我们有大把大把时间专门搞重构,我们要边重构边做需求。在这样的挑战下,我想到了微前端解决方案,下面就跟大家分享这次 微前端在重构上的落地实践吧。
这次实践我简化了一下,放在 Github 上,大家可以自行 clone 来玩玩。
技术栈
首先,来讲讲技术栈,老项目主要用了下面的技术:
- 框架
- Vue
- vuex
- vue-router
- 样式
- scss
- UI
- ant-design-vue
- ant-design-pro for vue
- 脚手架
- vue-cli
新项目需要用到的技术有:
- 框架
- React
- redux + redux-toolkit
- react-router
- 新式
- less
- UI
- react-design-react
- react-design-pro for react
- 脚手架
- 团队内部自创脚手架
可以看到两个项目除了业务之外,几乎没什么交集了。
微前端策略
老项目作为主应用,通过 qiankun 去加载新项目(子应用)里的页面。
- 当没有需求时,在新项目(子应用)重写页面,重写完了之后,在老项目(主应用)中加载新项目的页面,下掉老项目的页面
- 当有需求时,也是在新项目(子应用)重写面面再做对应需求(向产品要多点时间),重写完了之后,在老项目(主应用)中加载新项目的页面
这样一来就可以避免 “我要一整个月都做重构” 的局面,而是可以做到一个页面一个页地慢慢迁移。最终等所有页面都在新项目写好之后,直接把老项目下掉,新项目就可以从幕后站出来了。相当于从重写的第一天开始,老项目就成替身了。
如果只看上面画的架构图,会觉得:啊,不就引入一个 qiankun 就完事了么?实际上还有很细节和问题需要注意的。
升级版架构
上图的架构有一个问题就是,当每次点击侧边栏的 MenuItem
时,都会加载一次微应用的子页面,也即:
微应用子页面之间的切换,其实就是在微应用里路由切换嘛,大可不需要通过重新加载一次微应用来做微应用子页面的切换。
所以,我想了一个办法:我在 <router-view>
旁边放了一个组件 Container
。进入主应用后,这个组件先直接把微应用整个都加载了。
<a-layout>
<!-- 页面 -->
<a-layout-content>
<!-- 子应用容器 -->
<micro-app-container></micro-app-container>
<!-- 主应用路由 -->
<router-view/>
</a-layout-content>
</a-layout>
当展示老页面时,把这个 Container
高度设为 0
,要展示新页面时,再把 Container
高度自动撑开。
// micro-app-container
<template>
<div class="container" :style="{ height: visible ? '100%' : 0 }">
<div id="micro-app-container"></div>
</div>
</template>
<script>
import {
registerMicroApps, start } from 'qiankun'
export default {
name: "Container",
props: {
visible: {
type: Boolean,
defaultValue: false,
}
},
mounted() {
registerMicroApps([
{
name: 'microReactApp',
entry: '//localhost:3000',
container: '#micro-app-container',
activeRule: '/#/micro-react-app',
},
])
start()
},