故事的结尾

从一个快要上班的BUG开始,因为原部门共事想要基于一个我的项目再拆分出几个我的项目,咱们原本用的是qiankun(基座模式)的微前端模式,再拆分其实是比较简单的

只是这次顺便在拆分之前降级了webpack5,降级也是比较简单,这里一笔带过

施行的过程没有亲自操作

问题来了,在子利用降级了webpack5当前,本地通过基座加载调试时候,忽然启动不了了

复现问题

邻近上班,这个事件要解决,先复现

发现network面板通过基座加载子利用时候,呈现了一个js文件404

这外面很蹊跷,因为子利用独自能够启动,子利用被基座家加载时候只有一个js文件404了,而且是一个异步加载的js,那么能够判断,必定是加载逻辑这块出了问题

在子利用中调试,关上public-path文件:

if (window.__POWERED_BY_QIANKUN__) {    __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;}

发现这些代码在通过微前端基座模式加载时候,居然没有运行!!!是整个代码都没有被执行

这个js文件是通过入口index.tsx文件顶部引入的

曾经定位到了问题,就不怕。

外围问题是:过后发现子利用的__webpack_publicPath__这个变量没有被批改,所以造成了申请的host不对,异步加载的js文件404了

因为在排查这个问题之前,我在群里说了一句,有问题大家要一起看,这样都能学到一些货色,还好我说了这句话,拉上几个共事一起来听。

其中一个共事说了一句,会不会是被webpack5给tree sharking了

我感觉是,而后让他们看看本人是怎么配置这块的,于是共事提出倡议

package.json中的sideEffects字段,加上这个文件

而后再次启动我的项目,就解决这个问题了,public-path失常被加载了


看似简略的解决

看似简略的解决,须要先定位问题,这会用到以下几点:

相熟微前端qiankun的原理

相熟webpack的原理以及webpack动静懒加载实现的原理

相熟webpack的__webpack_pulicPath__属性的意义

晓得tree sharking

理解webpack5的tree sharking配置

一一原理解说

微前端原理

能够看我之前的手写微前端文章+源码:https://github.com/JinJieTan/...

微前端最外围的原理就是:基座我的项目通过配置信息,发送fetch申请,将子利用的资源全副拿到后渲染成dom节点插入到容器节点中。而后劫持路由变动事件,先在基座触发,再派发给其余子利用

webpack异步代码宰割原理

同步和异步代码都会被打包成不同的js文件,因为异步加载的js文件其实是通过网络申请拿到后插入到页面中,这个异步申请的前缀,其实是能够通过__webpack__pulicPath__这个变量来设置的

这也是最早的webpack5联邦模块实现思路,能够动静加载近程js文件,只有管制这个前缀变量__webpack_pulicPath__即可

微前端+异步代码宰割,核心思想是:动静的设置__webpack__publicPath__

webpack5的tree sharking配置

tree shaking 是一个术语,通常用于形容移除 JavaScript 上下文中的未援用代码(dead-code)。它依赖于 ES2015 模块语法的 动态构造 个性,例如 import 和 export。这个术语和概念实际上是由 ES2015 模块打包工具 rollup 遍及起来的。

webpack 2 正式版本内置反对 ES2015 模块(也叫做 harmony modules)和未应用模块检测能力。新的 webpack 4 正式版本扩大了此检测能力,通过 package.json 的 "sideEffects" 属性作为标记,向 compiler 提供提醒,表明我的项目中的哪些文件是 "pure(纯正 ES2015 模块)",由此能够平安地删除文件中未应用的局部。

以上是官网文档介绍

sideEffects 和 usedExports(更多被认为是 tree shaking)是两种不同的优化形式。

sideEffects 更为无效 是因为它容许跳过整个模块/文件和整个文件子树。

usedExports 依赖于 terser 去检测语句中的副作用。它是一个 JavaScript 工作而且没有像 sideEffects 一样简略间接。而且它不能跳转子树/依赖因为细则中说副作用须要被评估。只管导出函数能运作如常,但 React 框架的高阶函数(HOC)在这种状况下是会出问题的

当初回到方才咱们被tree sharking的代码:

if (window.__POWERED_BY_QIANKUN__) {    __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;

这个代码在上下文中其实是没有被援用的,只有在代码编译后,异步的代码js文件被加载时能力用到__webpack_public_path__这个变量,所以就被革除了代码

那么为了解决这个问题,咱们须要在 package.json 中增加 "sideEffects" 属性。

它相似于 /#__PURE__/ 然而作用于模块的层面,而不是代码语句的层面。它示意的意思是(指"sideEffects" 属性):“如果被标记为无副作用的模块没有被间接导出应用,打包工具会跳过进行模块的副作用剖析评估。”。

跳过public-path文件到副作用剖析评估,间接打包它,就解决了这个问题

webpack的tree-sharking文档:https://webpack.docschina.org...

结尾

小小的一个问题,看似解决起来简略,然而对于日常的各种实现原理是都要求很相熟,能力疾速定位问题并且解决,这就是学习源码和各种原理的意义

感兴趣的敌人能够去我的gitHub,这些源码+文章都在https://github.com/JinJieTan/Peter- 记得给个star

喜爱的敌人帮Peter来一波在看/赞吧~