webpack打包原理?如何去掉deadcode?

大家之前应该用过gulp,grunt这种代码打包工具,定义不同的打包任务和打包流程。我用的比较多的rollup这个打包工具,配置起来比较简单些。

webpack也是用来做代码打包,可以做代码分析,拆分,混淆,压缩等等,基于他的插件扩展机制可以做很多事情。分析webpack的原理,可以先从webpack配置文件说起。参考:[webpack编译代码原理介绍][20] [用webpack4和一些插件提升代码编译速度][21]

首先作为打包工具,要定义打包的输入entry和输出output;然后是定义webpack要用到的module,比如babel js loader, cssloader等等。执行编译具体的流程是:

加载webpack配置文件 -》 根据配置初始化编译器compiler -》找到入口,根据loader配置开始编译入口文件以及层层依赖 -》编译完成之后,可以得到所有编译过的文件和依赖关系结构 -》根据依赖关系将模块组装成一个个包含多个模块的chunk,然后根据配置写到输出文件。

webpack构建流程可分为以下三大阶段。

  1. 初始化:启动构建,读取与合并配置参数,加载plugin,实例化Compiler
  2. 编译:从Entry出发,针对每个Module串行调用对应的Loader去翻译文件中的内容,再找到该Module依赖的Module,递归的进行编译处理
  3. 输出:将编译后的Module组合成Chunk,将Chunk转换成文件,输出到文件系统中

分析依赖是在编译过程中完成的,从入口查找依赖,最后形成依赖关系。 为了提高效率,可以记录分析过的依赖,这样下次遇到同样的模块就不用再分析,直接引用编译过的依赖就可以了。

tree-shaking的名字原理一样,就是摇一摇大树,落下来的叶子都是冗余的部分。Tree-shaking 较早由 Rich_Harris 的 rollup 实现,后来,webpack2 也增加了tree-shaking 的功能。其实在更早,google closure compiler 也做过类似的事情。三个工具的效果和使用各不相同,使用方法可以通过官网文档去了解。

tree shaking的目的是去掉无用代码,减少代码体积。其实对于编译的编程语言对应的编译器基本都有判断哪些代码不会影响输出,从而在编译时移除这些代码的功能,称为DCE(dead code elimination)。tree shaking 是DCE的一种实现,传统的是消除没有引用不会执行的代码,tree shaking 主要是要消除没有用的代码。

Dead Code 一般具有以下几个特征

•代码不会被执行,不可到达

•代码执行的结果不会被用到

•代码只会影响死变量(只写不读)

前端代码打包处理中,最终都会有个代码压缩混淆的环节,这个环节其实会完成DCE的工作,会将这些dead code移除。

但是uglify代码是只是单个单个文件处理,并不能分析出这个代码有没有被其他文件用到,当然也不会对这些为被调用的函数做处理,如上图uglify就不会去除没用到的get函数,所以就需要tree shaking。tree shaking是有限制的,只能消除函数和import/export的变量,不会处理import/export的class(因为javascript动态语言特性使得分析比较困难,可能导致以外的错误,side effect比较大), 对于纯函数处理效果较好。



请遵守《互联网环境法规》文明发言,欢迎讨论问题
扫码反馈

扫一扫,反馈当前页面

咨询反馈
扫码关注
返回顶部