Tree Shaking

Tree Shaking:只支持 ES Module 例如 importexport 的静态结构特性的引入。当引入一个模块时,不引入所有的代码,只引入需要的代码

你可以将应用程序想象成一棵树。绿色表示实际用到的源码和 library,是树上活的树叶。灰色表示无用的代码,是秋天树上枯萎的树叶。为了除去死去的树叶,你必须摇动这棵树,使它们落下。

添加一个通用模块

在我们的项目中添加一个新的通用模块文件 src/math.js,此文件导出两个函数:

project

1
2
3
4
5
6
7
8
9
10
webpack-demo
|- package.json
|- webpack.config.js
|- /dist
|- bundle.js
|- index.html
|- /src
|- index.js
+ |- math.js
|- /node_modules

src/math.js

1
2
3
4
5
6
7
export function square(x) {
return x * x;
}

export function cube(x) {
return x * x * x;
}

接着,更新入口脚本,使用其中一个新方法,并且为了简单,将 lodash 删除:

src/index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- import _ from 'lodash';
+ import { cube } from './math.js';

function component() {
- var element = document.createElement('div');
+ var element = document.createElement('pre');

- // lodash 是由当前 script 脚本 import 导入进来的
- element.innerHTML = _.join(['Hello', 'webpack'], ' ');
+ element.innerHTML = [
+ 'Hello webpack!',
+ '5 cubed is equal to ' + cube(5)
+ ].join('\n\n');

return element;
}

document.body.appendChild(component());

注意,我们并未从 src/math.js 模块中 import 导入 square 方法。这个功能是所谓的“未引用代码(dead code)”,也就是说,应该删除掉未被引用的 export。现在让我们运行我们的npm 脚本 npm run build,并检查输出的 bundle:

**dist/bundle.js **

1
2
3
4
5
6
7
8
9
10
11
12
13
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* unused harmony export square */
/* harmony export (immutable) */ __webpack_exports__["a"] = cube;
function square(x) {
return x * x;
}

function cube(x) {
return x * x * x;
}

注意,上面的 unused harmony export square 注释。如果你看下面的代码,你会注意到 square 没有被导入,但是,它仍然被包含在 bundle 中。

在 webpack.config.js 中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require('webpack');

module.exports = {
mode: 'development',
devtool: 'cheap-module-eval-source-map',
entry: {
main: './src/index.js'
},
devServer: {
contentBase: './dist',
open: true,
port: 8080,
hot: true,
hotOnly: true
},
module: {
rules: []
},
plugins: [],
+ optimization: { //在开发环境中加,生产环境不加
usedExports: true
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
}
}

在 package.json 中:

1
2
3
{
+ "sideEffects": ["*.css"], //对 所有的css文件 不使用Tree shaking。如果填 false,就是都需要用到Tree shaking
}

详细内容请看官网:tree-shaking