webpack系统学习(三)Tree Shaking 概念详解

商绍元
2023-12-01

当项目达到一定体积的时候,将代码分成模块可以更加易于我们的管理,但是,当这样做时,我们可能引入了并不需要的代码,而Tree Shaking 就是一种通过消除文件中纹使用的代码来优化体积。
注意:Tree Shaking 只支持对静态引入的模块进行体积优化。
一般

观察下面的代码:

//math.js
export const add = (a, b) => {
  console.log( a + b )
}

export const minus = (a, b) => {
  console.log( a - b )
}
//index.js
import { add } from './math'

add(1,2)

现在我们对index.jsdevelopment模式下进行打包:

/*! exports provided: add, minus */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"add\", function() { return add; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"minus\", function() { return minus; });\nvar add = function add(a, b) {\n  console.log(a + b);\n};\nvar minus = function minus(a, b) {\n  console.log(a - b);\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvbWF0aC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9qcy9tYXRoLmpzPzljMzkiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IGFkZCA9IChhLCBiKSA9PiB7XHJcbiAgY29uc29sZS5sb2coIGEgKyBiIClcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IG1pbnVzID0gKGEsIGIpID0+IHtcclxuICBjb25zb2xlLmxvZyggYSAtIGIgKVxyXG59Il0sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/js/math.js\n");

/***/ })

我们查看打包后的对应代码位置,我们发现,虽然在index.js中我们只使用了math.js中的add 模块,但是打包后生成的main.js中既存在add,又存在minus,这时候的main.js明显还有体积压缩的空间。

webpack.config.js中我们添加一段代码:

  optimization: {
    usedExports: true
  }

再次执行打包,相关代码改变成一下形式:

/*! exports provided: add, minus */
/*! exports used: add */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return add; });\n/* unused harmony export minus */\nvar add = function add(a, b) {\n  console.log(a + b);\n};\nvar minus = function minus(a, b) {\n  console.log(a - b);\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvbWF0aC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9qcy9tYXRoLmpzPzljMzkiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IGFkZCA9IChhLCBiKSA9PiB7XHJcbiAgY29uc29sZS5sb2coIGEgKyBiIClcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IG1pbnVzID0gKGEsIGIpID0+IHtcclxuICBjb25zb2xlLmxvZyggYSAtIGIgKVxyXG59Il0sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/js/math.js\n");

/***/ })

分析一下重量重打包方式的不同之处:
第二个main.js增加了一行注释:/*! exports used: add */,而代码部分并没有对代码进行缩减,原因是因为我们在 development 模式下,配置了devtool: 'cheap-module-eval-source-map',为了方便我们开发,生成对应的source-map,快速定位到错误,不会将代码进行缩减。而在production打包模式下,webpack会自动帮我们开启Tree Shaking,这时候生成的打包代码就是缩减后的代码了。

//webpack.config.js
...
  mode: 'production',
  devtool: 'cheap-module-source-map',//更改production模式下的devtool
...

但是,载重情况下的代码缩减还存在一个问题,我们可以查看下面的代码:
观察下面的代码,我们有一个css样式文件,在index.js中使用,我们看其是否能改变body的样式。

//index.css
body{
  background: aquamarine;
}
//index.js
import '../style/index.css'

这里的../style/index.css能不能不引入成功呢?
Tree Shaking机制发现我们引入了样式文件之后并没有“使用”它,所以不会将该样式文件导入,但是事实上我们是需要这个样式文件的,这时候,我们需要在package.json中设置sideEffects

//package.json
...
  "sideEffects": ["@babel/poly-fill","*.css","*.scss",...]
...
 类似资料: