Tree Shaking
从字面上理解就是树摇晃
。就是当我们在一个js文件中写入了多个导出的方法,但是引用时只使用了一部分,其他方法不应该被打包进来。
1.举例
文件结构
myProject
|-dist
|-node_modules
|-src
+ |-util
+ |-math.js
|-assets
|-css
|-index.css
|-less
|-index.less
|-sass
|-index.scss
|-images
|-wali_logo.png
|-index.html
|-index.js
|-package.json
|-webpack.config.js
|-postcss.config.js
|-.babelrc
src/util/math.js
export const add = (x,y) =>{
return x + y;
}
export const minus = (x,y) =>{
return x - y;
}
src/index.js
import { add } from "./util/math";
add(1,2)
运行webpack
打开dist/main.js文件
...
...
/***/ "./src/util/math.js":
/*!*********************************!*\
!*** ./src/util/math.js ***!
\*********************************/
/*! 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; });\n/**\r\n * Created by Administrator on 2019/5/28.\r\n */\nconst add = (x, y) => {\n return x + y;\n};\nconst minus = (x, y) => {\n return x - y;\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvYXNzZXRzL3V0aWwvbWF0aC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9hc3NldHMvdXRpbC9tYXRoLmpzPzAwNWYiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIENyZWF0ZWQgYnkgQWRtaW5pc3RyYXRvciBvbiAyMDE5LzUvMjguXHJcbiAqL1xuZXhwb3J0IGNvbnN0IGFkZCA9ICh4LCB5KSA9PiB7XG4gIHJldHVybiB4ICsgeTtcbn07XG5leHBvcnQgY29uc3QgbWludXMgPSAoeCwgeSkgPT4ge1xuICByZXR1cm4geCAtIHk7XG59OyJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/util/math.js\n");
/***/ })
...
...
上面这段代码就是webpack打包生成的代码,我们看到在math.js
中将add,minus
方法都打包进来。这样就会导致我们最终生成的文件特别大。tree shaking概念可以帮助我们将没有用的代码给摇晃掉。
2.配置webpack
package.json
{
"name": "webpack",
"version": "1.0.0",
"description": "webpack测试",
+ "sideEffects":[
+ "*.css"
+ ],
"main": "index.js",
"author": "wali",
"private": true,
"license": "MIT",
"scripts": {
"dev": "npx webpack-dev-server --mode=development --colors",
"dist": "npx webpack --mode=production",
"build": "npx webpack --mode=development --colors"
},
"dependencies": {
"@babel/core": "^7.4.5",
"@babel/plugin-transform-runtime": "^7.4.4",
"@babel/preset-env": "^7.4.5",
"@babel/runtime": "^7.4.5",
"@babel/runtime-corejs2": "^7.4.5",
"autoprefixer": "^9.5.1",
"babel-loader": "^8.0.6",
"clean-webpack-plugin": "^2.0.2",
"css-loader": "^2.1.1",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^3.0.1",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"image-webpack-loader": "^4.6.0",
"less": "^3.9.0",
"less-loader": "^5.0.0",
"lodash": "^4.17.11",
"node-sass": "^4.12.0",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"webpack": "^4.32.0",
"webpack-cli": "^3.3.2",
"webpack-dev-server": "^3.4.1"
}
}
webpack.config.js
module.exports = {
...
+ optimization: {
+ usedExports: true
+ }
...
};
这里需要特别强调下,...
是说之前webpack.config.js的代码还在,只是添加了几行代码。随着功能越来越多,webpack.config.js文件的代码会越来越长,全部贴出来实在是太费篇幅了,后面小菜就都采用这种方式。
运行webpack
打开dist/main.js
文件
...
...
/***/ "./src/util/math.js":
/*!*********************************!*\
!*** ./src/util/math.js ***!
\*********************************/
/*! 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 */\n/**\r\n * Created by Administrator on 2019/5/28.\r\n */\nconst add = (x, y) => {\n return x + y;\n};\nconst minus = (x, y) => {\n return x - y;\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvYXNzZXRzL3V0aWwvbWF0aC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9hc3NldHMvdXRpbC9tYXRoLmpzPzAwNWYiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIENyZWF0ZWQgYnkgQWRtaW5pc3RyYXRvciBvbiAyMDE5LzUvMjguXHJcbiAqL1xuZXhwb3J0IGNvbnN0IGFkZCA9ICh4LCB5KSA9PiB7XG4gIHJldHVybiB4ICsgeTtcbn07XG5leHBvcnQgY29uc3QgbWludXMgPSAoeCwgeSkgPT4ge1xuICByZXR1cm4geCAtIHk7XG59OyJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./src/util/math.js\n");
/***/ }),
...
...
我们发现exports used: add
说明webpack已经知道在index.js文件只引用了add
方法,但是没有删除,没有删除的原因是因为我们开发模式,开发模式下如果删除就会对代码行数产生影响不利定位错误,当我们把webpack模式改为生产模式,minus
方法就会删除掉。
webpack.config.js
module.exports = {
...
- devtool:'cheap-eval-source-map',
+ devtool:'cheap-source-map',
...
};
运行生产webpack
我们看到在生成环境下,就只有add
方法被引入进来,而minus
方法就会被摇晃掉
3.代码回滚
测试完后,我们将代码回滚下,以便后续我们继续演示。
webpack.config.js
module.exports = {
...
+ devtool:'cheap-eval-source-map',
- devtool:'cheap-source-map',
...
};