常见面试题:Tree-Shaking 实现原理,web培训开发

本文详细阐述了Webpack如何通过FlagDependencyExportsPlugin和FlagDependencyUsagePlugin收集模块导出信息,并根据使用情况生成和删除DeadCode,实现TreeShaking。同时讨论了避免无意义赋值、纯函数声明、Babel配置和优化导出值粒度的重要性。
摘要由CSDN通过智能技术生成
  1. 被任意模块使用到的导出值,调用 exportInfo.setUsedConditionally 方法将其标记为已被使用。

  2. exportInfo.setUsedConditionally 内部修改 exportInfo._usedInRuntime 属性,记录该导出被如何使用

  3. 结束

上面是极度简化过的版本,中间还存在非常多的分支逻辑与复杂的集合操作,我们抓住重点:标记模块导出这一操作集中在 FlagDependencyUsagePlugin 插件中,执行结果最终会记录在模块导出语句对应的 exportInfo._usedInRuntime 字典中。

2.3 生成代码


经过前面的收集与标记步骤后,Webpack 已经在 ModuleGraph 体系中清楚地记录了每个模块都导出了哪些值,每个导出值又没那块模块所使用。接下来,Webpack 会根据导出值的使用情况生成不同的代码,例如:

重点关注 bar.js 文件,同样是导出值,barindex.js 模块使用因此对应生成了 __webpack_require__.d 调用 "bar": ()=>(/* binding */ bar),作为对比 foo 则仅仅保留了定义语句,没有在 chunk 中生成对应的 export。

关于 W ebpack 产物的内容及 __webpack_require__.d 方法的含义,可参考 Webpack 原理系列六:彻底理解 Webpack 运行时 一文。

这一段生成逻辑均由导出语句对应的 HarmonyExportXXXDependency 类实现,大体的流程:

  1. 打包阶段,调用 HarmonyExportXXXDependency.Template.apply 方法生成代码

  2. apply 方法内,读取 ModuleGraph 中存储的 exportsInfo 信息,判断哪些导出值被使用,哪些未被使用

  3. 对已经被使用及未被使用的导出值,分别创建对应的 HarmonyExportInitFragment 对象,保存到 initFragments 数组

  4. 遍历 initFragments 数组,生成最终结果

基本上,这一步的逻辑就是用前面收集好的 exportsInfo 对象未模块的导出值分别生成导出语句。

2.4 删除 Dead Code


经过前面几步操作之后,模块导出列表中未被使用的值都不会定义在 __webpack_exports__ 对象中,形成一段不可能被执行的 Dead Code 效果,如上例中的 foo 变量:

<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值