Open super-fool opened 3 years ago
想象一下, 有一棵树(项目), 树上有新鲜的绿叶, 也有着枯萎的红叶(dead-code), 当我们想去掉枯萎的树叶,就必须摇晃tree-shaking.
tree-shaking
一个术语: 用于描述移除JS上下文中未引用的代码(dead-code), 这个术语源起于Rollup. 有时候也被称为usedExports. 参考Webpack文档
Rollup
usedExports
dead-code: 通常指import一个文件时, 只使用了其中几个模块, 那么其他unused的代码就是死代码.
sideEffects
tree shaking
sideEffects更为有效, 它的检测程度在模块层面, 它允许跳过整个模块及模块子树.
tree shaking 更依赖于 terser 去检测语句中的副作用. 但是语句的检测并不能保证正确性, 因为JS属于动态语言.
terser
举一个例子:
import * as utils from './utils'; // 引入所有的utils if(){ utils.add(); // 使用了add } else if() { utils.remove(); // 使用了remove }
上述代码中, 我们只引用了utils中的add和remove, 但是我们却import所有的方法, 那么我们就需要进行tree-shaking: import {add, remove} from './utils'
import {add, remove} from './utils'
Tip: 如果想查看打包情况的话,可以使用webpack-bundle-analyzer 和 source-map-explorer, 当然这只是在开发情况下需要的.
webpack-bundle-analyzer
source-map-explorer
如果我们确定某些语句是纯函数时, 可以使用以下注释来标注:
// one module var nested = true; // 开启optimization innerGraph时, 对于未引用的变量则会标注为dead-code var Button$1 = /*#__PURE__*/somePureFunc(Button); //保证somePureFunc为纯函数,如果没有模块去引用Button$1时, 该语句会terser被作为dead-code. export { Button$1 }
上述代码中, 我们可以发现:
optimization.innerGraph
module.exports = { // ... optimization: { innerGraph: true } }
/*#__PURE__*/
在webpack中, mode: production会默认开启tree-shaking. 如果在开发模式时, 可以使用命令行--optimize-minimize来启用TerserPlugin.
mode: production
--optimize-minimize
TerserPlugin
Tree Shaking
想象一下, 有一棵树(项目), 树上有新鲜的绿叶, 也有着枯萎的红叶(dead-code), 当我们想去掉枯萎的树叶,就必须摇晃
tree-shaking
.一个术语: 用于描述移除JS上下文中未引用的代码(dead-code), 这个术语源起于
Rollup
. 有时候也被称为usedExports
. 参考Webpack文档sideEffects
和tree shaking
sideEffects
更为有效, 它的检测程度在模块层面, 它允许跳过整个模块及模块子树.tree shaking
更依赖于terser
去检测语句中的副作用. 但是语句的检测并不能保证正确性, 因为JS属于动态语言.tree shaking
举一个例子:
上述代码中, 我们只引用了utils中的add和remove, 但是我们却import所有的方法, 那么我们就需要进行tree-shaking:
import {add, remove} from './utils'
如果我们确定某些语句是纯函数时, 可以使用以下注释来标注:
上述代码中, 我们可以发现:
optimization.innerGraph
/*#__PURE__*/
, 该标记表示该函数中无副作用. 对于函数的参数是无法被标记的.在webpack中,
mode: production
会默认开启tree-shaking
. 如果在开发模式时, 可以使用命令行--optimize-minimize
来启用TerserPlugin
.