写在前面
本次例子是简化版的真实项目,从零到一,包括最后的nginx配置都有。并且配上效果图,至于文件目录结构,因为和umi官网命令搭建的一样就不会贴出来了。主应用,子应用全都是用umi进行开发,没有和网上大部分例子一样嵌套了vue等其他框架。全程使用了umi全家桶开发,cv大法,若想了解微前端更多原理之类的,网上很多讲解,这里不涉及,因为本人也是一知半解。只会使用,不会搭建构造。
项目背景
公司有个C端项目,简单概括就是一个基础商城,会售卖给很多个甲方,同时会根据甲方的要求进行特殊化处理。比如每个甲方的登录方式不一样,首页布局不一样等等。项目之前的处理方式是利用git分支功能做管理,一个甲方一个分支。但这样会出现不好维护的情况,比如共有的代码出现了一个问题,我需要修改其他分支并且重新打包,这样非常不友好。并且随着业务的越来越庞大,功能模块越来越多,里面好几个业务都可以当作是一个项目来进行开发了。这时候微前端这几个字就走进了我的眼球,并且决定对项目进行重构。
开始工作
经过搜索,我把目光锁定了qiankun,并且使用umi开发,别问,问就是底层原理不会,而umi刚好有qiankun一条龙服务。具体参考文档。跟着文档,一步步生成了两个项目,main和home,main就是主应用,相当于一个容器,用于登录和通用的基础应用。而home顾名思义就是首页,相当于一个子应用。如下图:
然后根据文档所写,安装qiankun 两个应用都要:
yarn add @umijs/plugin-qiankun
main/.umirc.ts 下的 defineConfig 增加
// 注册主应用
qiankun: {
master: {},
},
home/.umirc.ts 下的defineConfig增加
// 注册子应用
qiankun: {
slave: {},
},
main/src/app.ts的配置加上:
export const qiankun = () => {
return {
apps: [
{
name: 'home', // 唯一 id
entry: '//xxx.xxx.xx.xxx:8000', // home的运行地址
},
// 若有多个子应用往下增加
],
lifeCycles: {
afterMount: (props: any) => {
console.log('qiankun---', props)
},
},
}
}
经过这一波操作,再次重启项目发现竟然ok,如下截图:
看到这我心里只有两个字,芜湖~但是!但是!但是!到这里还没完,因为真正用于开发上线还有几个问题:
- 如何隔离
- 如何数据传递
- 怎么在子应用跳转主应用的路由,比如子应用/home 要跳去/mine 页面(mine属于父级应用路由)
- 如何使用公共的组件,方法等
- 怎么打包通过正式的url访问
如何隔离
这点其实很好办,官网本身有给出沙盒api,而且再不济就不要用重名咯~(半开玩笑)
如何数据传递
这点也很好解决,官网也有例子,但不得不吐槽一下,使用官网的例子,主应用注册不能写在.umirc.ts,需写在app.ts里(按照我上面的配置就好),不多说,上代码:
// main app.ts
import { history } from 'umi'
export function useQiankunStateForSlave() {
const [qiankunGlobalState, setQiankunGlobalState] = useState<any>({
masterHistory: history,
test:'hello',
})
// 可以挂载到window下 这里需要注意,如果window获取,修改内容时需要及时修改window
window.masterHistory = history
window.qiankunGlobalState = qiankunGlobalState
return {
qiankunGlobalState,
setQiankunGlobalState,
}
}
这时候不管主应用还是子应用,都可以使用useModel获取qiankunGlobalState,并且通过setQiankunGlobalState来对数据进行更新,修改等
// 主/子应用的test.tsx 不一定test.tsx哈,哪里想用就去哪里
import { IRouteComponentProps, useModel } from 'umi'
import React, { useEffect } from 'react'
export default function Text() {
const { setQiankunGlobalState, qiankunGlobalState } = useModel(
'@@qiankunStateForSlave',
)
console.log('qiankunGlobalState', qiankunGlobalState)
useEffect(() => {
setTimeout(() => {
setQiankunGlobalState({
...qiankunGlobalState,
userName: '我是js',
})
}, 2000)
}, [])
}
到这里一部分涨的帅/漂亮的同志就会说,怎么我ts一使用window.xxx就会报红线呀
这时候需要在目录下增加window.d.ts 名字任意哈,.d.ts结尾即可。内容如下:
// window.d.ts
import { History } from 'umi'
declare global {
interface Window {
masterHistory: History
qiankunGlobalState: {
projectName: string
}
}
}
如何维护公共的组件,方法
一开始我是想到npm这种方式,但是开发阶段各种改很不方便,于是后面使用了git submodel,创建一个libs的项目进行管理维护。
- 首先创建一个libs文件,里面存放各种公用的方法,组件,图片等,并且同步到gitlab上
2.各应用到src下关联该模块
// main home src目录
git submodule add 项目git地址/libs.git src/
// 执行完后会发现目录下多了个.gitmodules,并且src下有libs的文件了,这时候不管是哪个应用,都可以对libs进行开发维护,而libs维护和普通项目git一样。 记得libs切换到分支再进行开发!!!因为一开始默认是某次提交
怎么打包,通过正式的url访问
我司是用k8s进行项目打包的,经百度在ci文件加上以下配置:
.gitlab-ci.ymi文件
variables:
GIT_SUBMODULE_STRATEGY: recursive # 拉取 Submodule 内容
正当我兴致勃勃准备开瓶82年的旺仔牛奶庆祝的时候,发现后台打包显示报错,报错信息如下
通过报错信息大体得知,下载失败,但是为什么失败呢,怎么成功呢,我一脸懵逼,百度查了好久好久都没有答案,自己也折腾了无数遍,换账号,ssh等等都没折腾成功,后来想起,git submodule gitlab介绍中的配置于是我屁颠屁的修改.gitmodules里的url路径为相对路径,果然成功了!
nginx配置
这里的配置各项目大同小异,具体根据实际来即可。
配置完后兴致勃勃的打开,效果不错
最后打包成功后,记得修改以下app.ts里的entry值,目前我是配合cross-env配置了本地开发环境local、测试环境dev、生产环境prod,分别对应不同的url。这样就方便多了。到这里还有两个小问题目前暂未解决,
未解决的小问题
- 主应用的路由不能动态生成,每有一个页面,需要手动到.umirc.ts的router里增加,挺不方便的
- .gitmodules打包时候需要用相对路径,这样的话本地初始化开发就不太方便了
若有知道的大神希望告诉下解决方案。
总结
到这里可能会有疑问,怎么在子应用跳转主应用的路由 这个问题还没解决呀。对于这个问题一些细心的朋友就发现了,我把 main 的 history 当作参数传进了 qiankunGlobalState ,那么只要在子应用调用 qiankunGlobalState.masterHistory 这个方法就可以跳转main组件的路由,其他子应用路由同理。
总体来说开发还是相对顺滑的,果然是前人栽树后人乘凉。不得不佩服开发这些框架的大佬们真的强。目前我花费最多时间就是公共模块的维护与开发,总体打包,以及nginx配置那一块。但是目前来说,对于移动端项目,网上好像没有微前端例子公布。我这个真实的项目目前也在最后开发阶段,准备进入提测环节,并未真正发布使用,所以微前端合适不合适移动端,暂时未知,发布投入使用后,我会抽空再总结一下。
另外本人是个离开了百度、谷歌就活不下去的cv菜鸡,写的不好不对的地方欢迎指正~
感谢大家!
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!