前言
這是webpack打包優(yōu)化【下】篇。前幾篇針對性能要求高的項目從加快打包速度晴圾、減小資源體積方面入手,提出了一些優(yōu)化政策墙牌,然后測試都可起到一定優(yōu)化效果。本篇描述死代碼的檢測與去除
暗甥。
tree shaking
1 死代碼檢測去除
首先拋出問題,什么是死代碼捉捅?
工程中沒有被引用過的模塊撤防,這部分代碼將永遠無法被執(zhí)行,稱為“死代碼”棒口。
那知道了什么是死代碼寄月,如何檢測去除呢?
在前面我們介紹過无牵,ES6 module 依賴關系的構建是在代碼編譯時而非運行時漾肮。基于這項特性webpack提供了tree shaking功能茎毁。這個功能便可以在打包過程中幫助我們檢測沒有被引用的模塊克懊,然后對這部分代碼進行標記,并在資源壓縮時將它們從最終的bundle中去掉七蜘。
例:
// index.js
import { foo } from './util';
foo();
// util.js
export function foo() {
console.log('this is foo');
}
export function bar() { // 沒有被任何其他模塊引用谭溉,因此屬于死代碼
console.log('this is bar');
}
那么在webpack打包時就會對bar()添加一個標記,在正常本地開發(fā)環(huán)境下它依然會存在橡卤,但是在生產環(huán)境壓縮資源那一環(huán)節(jié)則會被移除掉扮念。
tree shaking有時可以使得bundle資源體積顯著減小,但需要一些前提條件碧库。
2 ES6 Module
tree shaking 只對ES6 Module生效柜与。 有時候我們發(fā)現(xiàn)算只引用了某個庫中的一個接口,卻把整個庫都加載了進來嵌灰,使得bundle體積并沒有什么變化弄匕,可能原因是該庫是用CommonJS導出的,而不是ES6 Module伞鲫。當然粘茄,為了更好地向下兼容,自然是使用CommonJS形式是庫依然很多秕脓。而排開第三方庫柒瓣,在我們自己書寫模塊或者庫時,可以盡可能的選擇ES6 Module形式導出吠架,這樣tree shaking的效率會更高芙贫。
3 使用webpack進行依賴關系構建
一般我們都會在工程中使用到babel-loader,如果我們有使用到傍药,那么一定要通過禁止它的模塊依賴解析磺平。原因是如果我們使用babel-loader來做依賴解析魂仍,那么webpack接收到的一般都是轉化過的CommonJS形式的模塊,那就無法對其進行tree shaking拣挪。
禁用babel-loader模塊依賴解析配置如下:
// webpack.config.js
module.exports = {
...
module: {
ryles: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: [
// 在這里加上modules: false
[@babel/preset-env, { modules: false }]
]
}
}
]
}
]
}
}
4. 使用壓縮工具去除死代碼
tree shaking本身只是為死代碼添加上標記擦酌,而真正意義上去除死代碼則是通過壓縮工具來進行的,而此工具之前介紹過:terser-webpack-plugin
菠劝。在此不再贅述赊舶。
小結
通過【上】【中】【下】三篇描述,介紹的一些打包優(yōu)化的方案均可以對項目有不同程度的優(yōu)化赶诊,無論是打包速度還是減小資源體積笼平,都有涉及。然而我們更需要清楚地了解到每一種優(yōu)化策略都有其使用場景舔痪,并不是任何一個點放在一切項目中都有效寓调。
當然,我們更需要不斷培養(yǎng)自己的能力锄码,當發(fā)現(xiàn)性能問題時夺英,根據現(xiàn)有情況自己多加思考,分析出原因滋捶,然后對癥下藥秋麸。
下一篇介紹更多的JavaScript打包工具。