#627·qiankun

[Feature Request] qiankun 如何复用公共依赖

Author: gongshunCreated Jun 2, 2020Updated Sep 17, 2026

Background

如果主项目和子项目都用到了同一个版本的 vue/vuex/vue-router 等,主项目加载一遍之后,子项目又加载一遍,就很浪费。

要想复用公共依赖,前提条件是子项目必须配置externals,这样依赖就不会打包进chunk-vendors.js,才能复用已有的公共依赖。

按需引入公共依赖,有两个层面:

  1. 没有使用到的依赖不加载
  2. 大插件只加载需要的部分,例如 elementUI 组件库的按需加载、echarts/lodash的按需加载。

Proposal

巨无霸应用的公共依赖和公共函数被太多的页面使用,导致升级和改动困难,使用微前端可以让各个子项目独立拥有自己的依赖,互不干扰。而我们想要复用公共依赖,这与微前端的理念是相悖的。

所以我的想法是:父项目提供公共依赖,子项目可以自由选择用或者不用。

这个也很好实现,父项目先加载好依赖,然后在注册子项目时,将vue/vuex/vue-router等通过 props 传过去,子项目可以选择用或者不用。

这样做不太可行,原因有两个:

  1. 子项目独立运行时,VueRouter/Vuex这些依赖从哪里来?子项目是只部署一份的,既可以独立运行,也可以被 qiankun 集成。
  2. 父项目只能传递它自己已经有的依赖,如何确定子项目需要哪些依赖?不满足按需引入的需求

要想实现按需引入依赖,配置webpackexternals 是必须的,而配置了这个之后,子项目独立运行时,这些依赖的来源有且仅有 index.html 中的外链 script 标签。

在这个前提下,能否做到,子项目和主项目的vue版本一致的情况下,使用同一份服务器文件。即使无法共享,也是可以做http缓存的。

那么 qiankun 能否做到,某个依赖加载了之后,不再加载,直接复用呢?比如说子项目A请求了服务器上的2.6版本vue,切换到子项目B,B项目也用了这个vue文件,能否不再次加载,直接复用呢?

其实是可以的,可以看到 qiankun 将子项目的外链 script 标签,内容请求到之后,会记录到一个全局变量中,下次再次使用,他会先从这个全局变量中取。这样就会实现内容的复用,只要保证两个链接的url一致即可。

所以只要子项目配置了webpackexternals,并在 index.html 中使用外链 script 引入这些公共依赖,只要这些公共依赖在同一台服务器上,便可以实现子项目的公共依赖的按需引入,一个项目使用了之后,另一个项目使用不再重复加载,可以直接复用这个文件。

Additional context

虽然 qiankun 不会重复请求相同 url 的公共依赖,但是这也仅比 http 缓存强了一丢丢。

有缺陷的地方在于:

  1. 主项目中的公共依赖没有记录到这个缓存中,也就不会被其他的项目复用
  2. 只是没有重复请求,还是需要重复执行一次。能否不执行,直接复用?js沙箱在子系统卸载时,会移除 window上新增的变量,而webpackexternals恰恰是将这些公共依赖挂载在 window上,能否看情况移除这些公共依赖?
  3. 相同版本的依赖会复用,版本不同但是使用无差别,能否做到也复用?(版本不同url也就不同,就不会复用)