1. 簡介
tree shaking 是一個術語官帘,通常用于描述移除 JavaScript 上下文中的未引用代碼(dead-code)。它依賴于 ES2015 模塊系統(tǒng)中的靜態(tài)結構特性,例如 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);
};
打包后如下:
可以看到辖所,雖然 minus 方法未被使用惰说,但是確被打包在最終的 index.js 文件中,增大了包體缘回。
3. 使用 tree-shaking 搖晃掉多余的代碼
現(xiàn)在我們嘗試利用 tree shaking 方法來搖晃掉未被使用的代碼吆视。
首先,我們要找出未被使用的模塊:
module.exports = {
//...
optimization: {
usedExports: true
}
};
打包后如下
可以看到此時輸出代碼中仍然有 minus 方法酥宴,但是該方法已經(jīng)被標記為未使用啦吧。那么如何在最終代碼中刪除掉該方法了,需要使用如下插件:
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
...
plugins: [
new UglifyJsPlugin(),
new HtmlWebpackPlugin({
template: "./src/index.html"
}),
new CleanWebpackPlugin()
],
打包后如下:
可以看到 minus 方法被抖掉了拙寡。
3. 將文件標記為無副作用
在一個純粹的 ESM 模塊世界中授滓,識別出哪些文件有副作用很簡單。然而,我們的項目無法達到這種純度般堆,所以在孝,此時有必要向 webpack 的 compiler 提供提示哪些代碼是“純粹部分”。
這種方式是通過 package.json 的 "sideEffects" 屬性來實現(xiàn)的淮摔。
{
"sideEffects": false
}
如同上面提到的私沮,如果所有代碼都不包含副作用,我們就可以簡單地將該屬性標記為 false和橙,來告知 webpack仔燕,它可以安全地刪除未用到的 export 導出。
「副作用」的定義是魔招,在導入時會執(zhí)行特殊行為的代碼晰搀,而不是僅僅暴露一個 export 或多個 export。舉例說明办斑,例如 polyfill外恕,它影響全局作用域,并且通常不提供 export俄周。
注意吁讨,任何導入的文件都會受到 tree shaking 的影響。這意味著峦朗,如果在項目中使用類似 css-loader 并導入 CSS 文件建丧,則需要將其添加到 side effect 列表中,以免在生產(chǎn)模式中無意中將它刪除:
{
"name": "your-project",
"sideEffects": [
"./src/some-side-effectful-file.js",
"*.css"
]
}
4. 使用 production 模式
上述其實是描述如何在 development 模式下開啟 tree-shaking波势,但其實在 development 模式下翎朱,為了開發(fā)和調(diào)試方便,我們是不會開啟壓縮的尺铣,而 production 下拴曲,會自動為我們開啟 tree-shaking。去掉 usedExports 和 uglifyjs-webpack-plugin 相關配置凛忿,將 mode 修改為 production:
mode: 'production',
另外澈灼,注意文章開頭所說的,tree-shaking 依賴于 ES2015 模塊系統(tǒng)中的靜態(tài)結構特性店溢,例如 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