Webpack - Tree Shaking

1,701 阅读4分钟

1.什么是tree-shaking呢?

字面意思 树摇 针对代码的话就是如果代码在我们项目中没有存在的必要 我们就可以通过treeshaking来减少项目体积 简洁度 加载速度更快

tree shaking 是一个术语 表示消除死代码 (dead_code)

最早起源lisp 用于消除没有被调用的代码 (纯函数没有副作用) 可以放心的消除

后来tree shaking也被应用于其他语言 javascript dart

javascript进行treeshaking;来源于rollup

tree shaking依赖于es module的静态语法分析 (不执行任何代码,可以明确知道模块依赖关系)

webpack 2 就开始支持tree shaking

webpack4 正式扩展了tree shaking 通过在package.json 中配置 sideEffect

webpack5 部分commonjs 也支持 tree shaking

webpack实现 tree shaking 采用了两种不同的方案

useExports 通过标记函数是否被使用 之后通过terser来进行优化

sideEffects 跳过整个模块 直接查看改文件是否有调用副作用

***** 生产环境下默认开启tree shaking *****

所以我们需要在开发环境体验tree shaking

index.js 导入math.js中的两个函数

image.png

在index中 我们只导入其中的一个函数

image.png

webpack.config.js tree shaking 要在优化中 配置 (Optimization)

image.png

如果我们设置usedExports 为 false 的情况下 打包出来的bundle

image.png

我们在执行的时候 是在箭头函数中调用执行

image.png

此时就两个函数 都被 打包进来

如果 设置了 usedExports 为true的情况

image.png

这时候 我们只需要打包一个 sum函数就可以了, 打包之后 会有一段魔法注释 /* unused harmony export mult */ 这段注释 告诉我们到时候 我们如果做了 terser优化 可以删除掉这段代码 terser就是代码压缩 (压缩机)

usedExports 是 为了 把 没有使用的函数 告诉 Terser 让terser 来给我们处理

第二种 Tree Shaking 的方法 sideEffects

sideEffects 用于告知webpack 编译器 我们使用的哪些模块是有副作用的

1.副作用的意思是代码里面的执行任务 不能仅仅通过export 来判断这段代码的意义

在package.json 中设置 sideEffects 如果值为false 告诉我们 如果 我们是在indexjs中直接导入的全部 formatjs 那么整个模块 不具有任何副作用 打包就会被完全删除 我们先看看 如果 不设置sideEffects

什么叫做副作用

如果我们在format.js中 引用了

window.adny = 'adny';

这时我们删除 引用了format.js在index.js中 这段代码就永远不会被执行 这就是副作用 开发中 避免模块的副作用

image.png

format.js and index.js

format.js

image.png

index.js

image.png

image.png

如果我们设置 了 sideEffects 为false 我们就删除所有 不具有任何副作用的模块

package.json

image.png

这是 打包的 文件 就完全删除了 format 模块相关的代码

image.png

如果我们在模块中添加了副作用 format.js中的winodw.adny,window对象永远不会获得 模块中设置的属性 为undefined

如果我们要保留模块的副作用 我们可以在package.json中设置 sideEffects中配置一个数组 设置你需要保留副作用的相对路径

image.png

开发当中尽量使用纯模块 不适用具有副作用的模块,减少副作用代码的使用 减少包体积

对css模块进行打包

默认我们设置副作用 css模块 会被当做副作用模块 全被删除 所以我们需要 设置所有的css文件 最后要被打包

image.png

** 表示我们匹配所有的css文件

默认开发sideEffects 为false

由于不建议使用副作用代码,但是此时的问题就是如果我们遇到了css文件 那么也会被当成副作用模块全部删除 所以我们还要在rules 配置css的时候添加一个属性 sideEffects: true

{
 test: /\.css/i,
 use: ['css-loader','style-loader'],
 sideEffects: true
}

css中的Tree Shaking

以上的都是js的tree shaking 那么我们如何对css做tree shaking

安装purgeCss

帮助我们删除未使用的css

yarn add purgecss-webpack-plugin -D

我们在生产环境下 配置 plugins

image.png

还可以配置safelist 告诉代码中那些css是安全的

image.png