1. 简介
tree shaking 是一个术语,通常用于描述移除 JavaScript 上下文中的未引用代码(dead-code)。它依赖于 ES2015 模块系统中的静态结构特性,例如 import
和 export
。这个术语和概念实际上是兴起于 ES2015 模块打包工具 rollup。
新的 webpack 4 正式版本,扩展了这个检测能力,通过 package.json
的 "sideEffects"
属性作为标记,向 compiler 提供提示,表明项目中的哪些文件是 "pure(纯的 ES2015 模块)",由此可以安全地删除文件中未使用的部分。
2. 使用场景
我们看如下使用场景,主模块 index.js 中引用了一个辅助模块 math.js 中的一个方法。
// index.js
import { add } from './math';
add(1, 2);
// math.js
export const add = (a, b) => {
console.log(a + b);
};
export const minus = (a, b) => {
console.log(a - b);
};
打包后如下:
image.png
image.png
可以看到,虽然 minus 方法未被使用,但是确被打包在最终的 index.js 文件中,增大了包体。
3. 使用 tree-shaking 摇晃掉多余的代码
现在我们尝试利用 tree shaking 方法来摇晃掉未被使用的代码。
首先,我们要找出未被使用的模块:
module.exports = {
//...
optimization: {
usedExports: true
}
};
打包后如下
image.png
image.png
可以看到此时输出代码中仍然有 minus 方法,但是该方法已经被标记为未使用。那么如何在最终代码中删除掉该方法了,需要使用如下插件:
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
...
plugins: [
new UglifyJsPlugin(),
new HtmlWebpackPlugin({
template: "./src/index.html"
}),
new CleanWebpackPlugin()
],
打包后如下:
image.png
image.png
可以看到 minus 方法被抖掉了。
3. 将文件标记为无副作用
在一个纯粹的 ESM 模块世界中,识别出哪些文件有副作用很简单。然而,我们的项目无法达到这种纯度,所以,此时有必要向 webpack 的 compiler 提供提示哪些代码是“纯粹部分”。
这种方式是通过 package.json 的 "sideEffects" 属性来实现的。
{
"sideEffects": false
}
如同上面提到的,如果所有代码都不包含副作用,我们就可以简单地将该属性标记为 false,来告知 webpack,它可以安全地删除未用到的 export 导出。
「副作用」的定义是,在导入时会执行特殊行为的代码,而不是仅仅暴露一个 export 或多个 export。举例说明,例如 polyfill,它影响全局作用域,并且通常不提供 export。
注意,任何导入的文件都会受到 tree shaking 的影响。这意味着,如果在项目中使用类似 css-loader 并导入 CSS 文件,则需要将其添加到 side effect 列表中,以免在生产模式中无意中将它删除:
{
"name": "your-project",
"sideEffects": [
"./src/some-side-effectful-file.js",
"*.css"
]
}
4. 使用 production 模式
上述其实是描述如何在 development 模式下开启 tree-shaking,但其实在 development 模式下,为了开发和调试方便,我们是不会开启压缩的,而 production 下,会自动为我们开启 tree-shaking。去掉 usedExports 和 uglifyjs-webpack-plugin 相关配置,将 mode 修改为 production:
mode: 'production',
另外,注意文章开头所说的,tree-shaking 依赖于 ES2015 模块系统中的静态结构特性,例如 import
和 export
。所以只有 es-module 才可以被 tree-shaking。
参考
webpack-tree-shaking
https://webpack.js.org/configuration/optimization/#optimizationusedexports
https://segmentfault.com/a/1190000016767989?utm_source=tag-newest
网友评论