项目背景
技术选型
目前使用的是支付宝开源的框架 qiankun, 主要原因是因为我们内部大部分的项目都用到了 umi, 然后 umi 有个集成框架叫 @umi/max,正好集成了 qiankun.
一键上手搭建的感觉还是很爽的
多种配置方案
主应用
顾名思义,就是应用的外框,所有的子应用都是嵌入在主应用中的存在,它可以给子应用赋能一些通用的功能,比如说:
- 聚合登录
- 权限验证
- 共有的功能性 sdk
…
主应用没有一个固定的形式,它可以是内容为空,也可以提供相应的布局。这个比较灵活,可以自由定制。
app.ts 配置
如果是在 umi 应用下,可以在 app.ts 中向外暴露一个 qiankun 的对象,内容主要是一些集成的配置。参考如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| export const qiankun = { apps: [ { name: 'app1', entry: '//localhost:30068/app1/', props: { accountInfo: { username: 'admin', password: 'test123', }, }, }, ], lifeCycles: { async afterMount(props: any) { console.log('主应用:', props); }, }, };
|
注意事项 ⚠️:如果是发布到服务器上去,entry 必须写成 对应的服务器 ip 地址,localhost.hostname 的形式,不然会获取地址失败!可以通过环境变量来区分 生产环境和本地开发环境
.umirc.ts 配置
这个文件中需要对三个模块进行配置,一个是打开 qiankun 插件这个功能,一个是应用绑定的路由 用 microApp 来作为映射,最后就是在发布 nginx 的时候的访问路径配置,如下作为参考:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| { qiankun: { master: { prefetch: false, singular: true, }, }, routes: [ { name: 'app1', path: '/app1/*', microApp: 'app1', }, ], ... }
|
子应用
相对的子应用需要修改的地方不多,它存在的意义主要是,当项目变得非常巨大,很笨重的时候,我们希望能够将它拆分模块化,分散到各个小的仓库中去,让每个人各司其职,负责独立的模块,这样的好处是:
- 项目更加垂直,一个模块,负责一个模块的业务。
- 拆分的更小也就以为着能够按模块打包,一定程度上能提升效率。
app.ts
导出微应用的三个生命周期函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| export const qiankun = { async bootstrap() { console.log('app1 bootstraped'); },
async mount(props: any) { console.log('app1 mount', props); },
async unmount(props: any) { console.log('app1 unmount', props); }, };
|
.umirc.ts
1 2 3 4 5 6 7 8 9
| { ... qiankun: { slave: { }, }, publicPath: `/${pkg.name}/` ... }
|
nginx 配置
具体配置参考(这个配置是在 windows 环境下,如果是 linux 环境需要适当的变更配置的 root 文件路径)
需要注意的几个点:
- 关于跨域的配置,主子应用都需要配置跨域
- 不建议用 root 去映射路径,用 alias(这个我之前踩过坑,详情可以去搜索 alias 和 root 的区别)
- 另外一定要注意后缀加不加 / 的区别,他们命中的规则是不一样的,切记!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| worker_processes 1;
events { worker_connections 1024; }
http { include mime.types; default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
server { listen 30058; server_name localhost; root E:\work\main\dist; index index.html;
location / { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
try_files $uri $uri/ /index.html; index index.html index.htm; }
error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
server { listen 30078;
location /app1 { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
try_files $uri $uri/ /app1/index.html; alias E:\work\app1\dist; index index.html index.htm; }
error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
|
参考文章
https://juejin.cn/post/7113871265848360997?searchId=20240308152253A3CC20142A59F31D97E3#heading-8
Q&A
localhost:XXXX err_connection_refused
我这里主要的原因是使用了 node 环境的环境变量去判断正式还是生产环境, like this:
1
| const pro = process.env - NODE_ENV;
|
千万不要用这个!打包虽然成功,但是里面逻辑判断是有问题的,绝了,卡了我一上午…
控制台报错提示,找不到其他应用 not fetch
这个是因为,qiankun 默认开启了预加载功能,在主应用中把这个功能关掉就好了。
1 2 3 4 5
| { master: { prefetch: false; } }
|
主应用中使用了 antd,页面报错
尝试在 .umirc.ts 配置中关闭 mfsu,再重启一下试试
另外一种可能性是不是配置一下 import 就可以了,没试过,可以试试看