上一篇讲到[对JS语法的处理] ,本篇将介绍 Tree Shaking 。
// math.js
const add = (a, b) => a + b;
const minus = (a, b) => a - b;
export {
add, minus
}
// main.js
const { add } from 'math.js'
console.log(add(1, 2));
我们经常会在主文件或者组件文件中引入其他模块中的代码,但实际上我们只用其中的一部分,剩下的代码则不需要引入。然而在默认情况下,仍然是全部引入并打包的。
这时,为了把多余部分剔除出去,就要用到 “Tree Shaking” 了,也就是摇树。
小时候,为了吃到树上的果子,我们会调皮地摇晃一棵树,在千般折腾下,枯叶便会纷纷落地,成熟的果子也会,这些都是不该留在树上的。同理,经过 Tree Shaking,不该留在代码中的多余代码,则会被摇掉 (例如上面代码中,math.js 模块中的 minus 就会被摇下来,不参与打包),这样就减轻了代码量,提高性能。
首先,要明确一点:Tree Shaking 只支持 ESM 的引入方式,不支持 Common JS 的引入方式。
如果想要对一段代码做 Tree Shaking 处理,那么就要避免引入整个库到一个 JS 对象上,如果你这么做了,Webpack 就会认为你是需要这整个库的,这样就不会做 Tree Shaking 处理。
下面是引入 lodash 的例子,如果引入的是 lodash 中的一部分,则可以 Tree Shaking。
// 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.config.js
module.exports = {
// ...
mode: 'development',
optimization: {
usedExports: true,
}
};
// webpack.config.js
module.exports = {
// ...
mode: 'production',
};
在生产环境下,Webpack 默认会添加 Tree Shaking 的配置,因此只需写一行 mode: 'production' 即可。
webpack.js.org/guides/tree…[2]
根据环境的不同进行配置以后,还需要在 package.json 中,添加字段:**sideEffects: false,**告诉 Webpack 哪些代码可以处理。
{
"name": "webpack-demo-1",
"sideEffects": 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"
]
}
对于那些直接引入到 js 文件的文件,例如全局的 css,它们并不会被转换成一个 CSS 模块。
/* reset.css */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
background-color: #eaeaea;
}
// main.js
import "./styles/reset.css"
这样的代码,在打包后,打开页面,你就会发现样式并没有应用上,原因在于:上面我们将 sideEffects 设置为 false 后,所有的文件都会被 Tree Shaking,通过 import 这样的形式引入的 CSS 就会被当作无用代码处理掉。
为了解决这个问题,可以在 loader 的规则配置中,添加 sideEffects: true ,告诉 Webpack 这些文件不要 Tree Shaking。
// webpack.config.js
module.exports = {
// ...
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
sideEffects: true
}
]
},
};
注意:这个字段在所有模块的规则都可以配置。
以上,是本篇的所有内容。
[1]https://juejin.cn/post/6999188157992271886: https://juejin.cn/post/6999188157992271886
[2]https://webpack.js.org/guides/tree-shaking/#minify-the-output: https://link.juejin.cn?target=https%3A%2F%2Fwebpack.js.org%2Fguides%2Ftree-shaking%2F%23minify-the-output
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8