Tree Shaking
是打包软件对打包进行优化的一个技术,可以将module中export出去,但是实际上并没有任何地方import的代码(Dead Code),移出最终的打包文件中。
// math.js
export function add(a, b) {
return a + b
}
/** this is dead code, because no import for it*/
export function multipy(a,b) {
return a*b
}
//index.js
import { add } from './math.js'
add(2, 3)
Tree Shaking
技术能在打包时将multipy
函数移出。但要使用此特性需要在业务代码和webpack配置的配合
Tree-Shakable imports
使用可以Tree Shaking
的import命令,即:按需import
,不要加载整个库。
以import lodash
为例
// Import everything (NOT TREE-SHAKABLE)
import _ from 'lodash';
// Import named export (CAN BE TREE SHAKEN)
import { debounce } from 'lodash';
// Import the item directly (CAN BE TREE SHAKEN)
import debounce from 'lodash/lib/debounce';
Webpack Configuration
webpack
配置需要满足三个条件
mode: production
-
optimization.usedExports: true
production 模式下默认为 true - ‘optimization.minimize: true’ 只有在minify 代码时才会执行
tree shaking
说明: production
模式下,后两个条件自动为 true
// tree-shaking 配置
const config = {
mode: 'production',
optimization: {
usedExports: true, // production模式下默认为true
minimize: true // 默认为true
// minimizer: [ // 或指定特定的minifier时
// new TerserPlugin({...})
//]
}
};
副作用 Side Effect
在做tree shaking
时,webpack 会移出未 import 过或未使用的代码。但有些代码虽然未import, 但可能内部定义了全局变量,或者 它是全局CSS文件。如果把这些文件移出则是不期望的。
webpack
可以通过sideEffect
字段标识移除代码是否有副作用。支持以下值:
-
true
: 所有代码有副作用 -
false
: 所有代码没有副作用 - []:地址数组,指定特定有副作用的文件集合
// All files have side effects, and none can be tree-shaken
{
"sideEffects": true
}
// No files have side effects, all can be tree-shaken
{
"sideEffects": false
}
// Only these files have side effects, all other files can be tree-shaken, but these must be kept
{
"sideEffects": [
"./src/file1.js",
"./src/file2.js"
]
}
也可以通过如下方式,在特定 rule
中设置从而避免全局设置带来的风险
/ Webpack config for global CSS side effects rule
const config = {
module: {
rules: [
{
test: /regex/,
use: [loaders],
sideEffects: true
}
]
}
};
参考文章
https://medium.com/@craigmiller160/how-to-fully-optimize-webpack-4-tree-shaking-405e1c76038