來,教你一個前端代碼優(yōu)化的新方法,好使!
??點擊“博文視點Broadview”,獲取更多書訊

搖樹優(yōu)化Tree Shaking是Webpack里非常重要的優(yōu)化措施,它的優(yōu)化效果在Webpack 5中又得到了進一步的提升。
Tree Shaking可以幫我們檢測模塊中沒有使用到的代碼塊,并在Webpack打包時將沒有用到的代碼塊移除掉,減小打包后的資源體積大小。
它的名字也非常形象,通過搖晃樹把樹上干枯無用的葉子搖掉。

使用Tree Shaking的原因
我們來看一個例子。
b.js文件的內(nèi)容如下:
var name = 'Jack';var year = 2022;export {name, year};
a.js文件的內(nèi)容如下:
import {name} from './b.js';console.log(name);
webpack.config.js文件的內(nèi)容如下:
var path = require('path');module.exports = {entry: './a.js',output: {path: path.resolve(__dirname, ''),filename: 'bundle.js'},mode: 'none'};
執(zhí)行npx webpack命令進行打包,打包完成后我們觀察生成的bundle.js文件,如圖1所示。

圖1 ?生成的bundle.js文件
我們發(fā)現(xiàn),變量year的值2022被打包到了最終代碼里,但其實我們的代碼a.js和b.js里并沒有真正使用到該變量。這時就需要使用Tree Shaking,來移除這部分代碼。

使用Tree Shaking
使用Tree Shaking一共分兩個步驟:
1)標注未使用的代碼。
2)對未使用的代碼進行刪除。
我們修改配置文件webpack.config.js。
webpack.config.js文件的內(nèi)容如下:
var path = require('path');module.exports = {entry: './a.js',output: {path: path.resolve(__dirname, ''),filename: 'bundle.js'},optimization: {usedExports: true,},mode: 'none'};
重新執(zhí)行npx webpack命令進行打包并觀察打包生成的資源,可以看到對未使用到的變量year進行了標注,即在第11行中有注釋“unused harmony export year”,如圖2所示。

圖2??對未使用到的變量進行標注
進行標注后,若需要對未使用的代碼進行刪除,使用Webpack 5自帶的TerserPlugin即可完成該操作。
接下來,我們使用TerserPlugin。
webpack.config.js文件的內(nèi)容如下:
var path = require('path');var TerserPlugin = require("terser-Webpack-plugin");module.exports = {entry: './a.js',output: {path: path.resolve(__dirname, ''),filename: 'bundle.js'},optimization: {usedExports: true,minimize: true,minimizer: [new TerserPlugin()],},mode: 'none'};
執(zhí)行npx webpack命令進行打包并觀察打包結果,bundle.js文件里的代碼被壓縮成一行,我們分別搜索代碼里的year和2022,已經(jīng)無法找到,說明它們在被Tree Shaking標注后被刪除了。

生產(chǎn)環(huán)境的優(yōu)化配置
通常,我們在本地開發(fā)環(huán)境中不會使用Tree Shaking,因為它會降低構建速度并且沒有太大意義。
我們需要在生產(chǎn)環(huán)境打包時開啟Tree Shaking,生產(chǎn)環(huán)境下我們只需要配置參數(shù)項mode為production,即可自動開啟Tree Shaking。
開啟了Tree Shaking后,Webpack會在打包時刪除大部分沒有使用到的代碼,但有一些代碼沒有被其他模塊導入使用,如polyfill.js,它主要用來擴展全局變量,這類代碼是有作用的代碼,我們需要告訴Webpack在Tree Shaking時不能刪除它們。
要告訴Webpack在Tree Shaking時不能刪除某些文件,可以在package.json文件里使用sideEffects配置,示例代碼如下:
{"sideEffects": ["./polyfill.js"]}

Webpack?5中對Tree Shaking的改進
在Webpack 4及之前的版本中,Tree Shaking對嵌套的導出模塊未使用代碼無法很好地進行Tree Shaking,往往需要借助webpack-deep-scope-plugin這一類的插件進行深層次的Tree Shaking。Webpack 5對此做出了改進,能夠對嵌套屬性進行Tree Shaking。
我們先觀察一個使用Webpack 4打包的例子。
a.js文件的內(nèi)容如下:
import * as person from './b.js';export {person};
b.js文件的內(nèi)容如下:
var name = 'Jack';var year = 2022;export {name, year};
index.js文件的內(nèi)容如下:
import * as moduleA from './a.js';console.log(moduleA.person.name);
webpack.config.js文件的內(nèi)容如下:
var path = require('path');module.exports = {entry: './index.js',output: {path: path.resolve(__dirname, ''),filename: 'bundle.js'},mode: 'production'};
我們使用Webpack 4進行打包,安裝Webpack 4的命令如下:
npm install --save-dev Webpack@4.43.0 Webpack-cli@3.3.12 現(xiàn)在執(zhí)行npx webpack命令打包,因為b.js文件里的變量year最終沒有使用到,按道理打包后其通過Tree Shaking會被刪除,但我們觀察打包后的資源文件bundle.js,如圖3所示,發(fā)現(xiàn)Webpack 4打包后的代碼里仍然有year和2022,這就是Webpack 4里Tree Shaking不足的地方。

圖3 ?Webpack?4打包后的文件
現(xiàn)在換成用Webpack 5打包。
打包后生成的bundle.js代碼如圖4所示,我們發(fā)現(xiàn)未使用的year和2022順利被刪除了,另外也可以看到Webpack 5打包后的文件非常簡潔。

圖4 ?Webpack?5打包后的文件
綜上,就是在代碼優(yōu)化方面Webpack5帶來的Tree Shaking使用上的新體驗。
本文摘自《Webpack+Babel入門與實例詳解》一書,歡迎閱讀此書了解更多相關內(nèi)容!


▊《Webpack+Babel入門與實例詳解》
姜瑞濤 著
適用于Webpackv5.0.0和Babelv7.0.0之后的版本
是針對零基礎前端開發(fā)者的Webpack與Babel圖書
這是一本針對零基礎前端開發(fā)者講解Webpack與Babel使用方法的圖書。隨著前端工程的不斷發(fā)展,Webpack與Babel已成為前端開發(fā)的兩大核心工具。目前,Webpack是前端開發(fā)的主流構建工具,Babel是轉譯ES6代碼的通用解決方案。
本書由兩大部分構成,第一部分介紹Webpack,第二部分介紹Babel。Webpack部分講解了Webpack的安裝、資源入口與出口、預處理器與插件的配置、開發(fā)環(huán)境與生產(chǎn)環(huán)境的配置、性能優(yōu)化及構建原理等。Babel部分講解了Babel入門知識、Babel的配置文件、預設與插件的選擇、babel-polyfill的使用方法,以及@babel/preset-env和@babel/plugin-transform-runtime這兩個核心配置項的使用方法,這一部分還會講解Babel的原理及Babel插件的開發(fā)。最后,在附錄中介紹了Module Federation與微前端,以及Babel 8前瞻等內(nèi)容。
(掃碼了解本書詳情!)

?熱文推薦??
