项目背景
技术选型
目前使用的是支付宝开源的框架 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 就可以了,没试过,可以试试看