[Feature Request] qiankun 如何复用公共依赖
Background
如果主项目和子项目都用到了同一个版本的 vue/vuex/vue-router 等,主项目加载一遍之后,子项目又加载一遍,就很浪费。
要想复用公共依赖,前提条件是子项目必须配置externals,这样依赖就不会打包进chunk-vendors.js,才能复用已有的公共依赖。
按需引入公共依赖,有两个层面:
- 没有使用到的依赖不加载
- 大插件只加载需要的部分,例如
elementUI组件库的按需加载、echarts/lodash的按需加载。
Proposal
巨无霸应用的公共依赖和公共函数被太多的页面使用,导致升级和改动困难,使用微前端可以让各个子项目独立拥有自己的依赖,互不干扰。而我们想要复用公共依赖,这与微前端的理念是相悖的。
所以我的想法是:父项目提供公共依赖,子项目可以自由选择用或者不用。
这个也很好实现,父项目先加载好依赖,然后在注册子项目时,将vue/vuex/vue-router等通过 props 传过去,子项目可以选择用或者不用。
这样做不太可行,原因有两个:
- 子项目独立运行时,
VueRouter/Vuex这些依赖从哪里来?子项目是只部署一份的,既可以独立运行,也可以被qiankun集成。 - 父项目只能传递它自己已经有的依赖,如何确定子项目需要哪些依赖?不满足按需引入的需求
要想实现按需引入依赖,配置webpack 的 externals 是必须的,而配置了这个之后,子项目独立运行时,这些依赖的来源有且仅有 index.html 中的外链 script 标签。
在这个前提下,能否做到,子项目和主项目的vue版本一致的情况下,使用同一份服务器文件。即使无法共享,也是可以做http缓存的。
那么 qiankun 能否做到,某个依赖加载了之后,不再加载,直接复用呢?比如说子项目A请求了服务器上的2.6版本vue,切换到子项目B,B项目也用了这个vue文件,能否不再次加载,直接复用呢?
其实是可以的,可以看到 qiankun 将子项目的外链 script 标签,内容请求到之后,会记录到一个全局变量中,下次再次使用,他会先从这个全局变量中取。这样就会实现内容的复用,只要保证两个链接的url一致即可。
所以只要子项目配置了webpack 的 externals,并在 index.html 中使用外链 script 引入这些公共依赖,只要这些公共依赖在同一台服务器上,便可以实现子项目的公共依赖的按需引入,一个项目使用了之后,另一个项目使用不再重复加载,可以直接复用这个文件。
Additional context
虽然 qiankun 不会重复请求相同 url 的公共依赖,但是这也仅比 http 缓存强了一丢丢。
有缺陷的地方在于:
- 主项目中的公共依赖没有记录到这个缓存中,也就不会被其他的项目复用
- 只是没有重复请求,还是需要重复执行一次。能否不执行,直接复用?
js沙箱在子系统卸载时,会移除window上新增的变量,而webpack的externals恰恰是将这些公共依赖挂载在window上,能否看情况移除这些公共依赖? - 相同版本的依赖会复用,版本不同但是使用无差别,能否做到也复用?(版本不同
url也就不同,就不会复用)
Source: umijs/qiankun