Tree Shaking
在文件或者在组件文件中引入其他模块中的代码,但实际上我们只用到其中的一部分,剩下的代码则不需要引入,然而在默认情况下,webpack仍然是全部引入并打包的。
这时,为了把多余部分剔除出去,就要用到 “ Tree Shaking ” 了,也就是摇树。
经过 Tree Shaking,不该留在代码中的多余代码,则会被摇掉,这样能减轻代码量,提高性能。
Tree Shaking 只支持 ESM 的引入方式,不支持 Common JS 的引入方式。
-
ESM: export + import
-
Common JS: module.exports + require
如果想对一段代码做 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';
Tree Shaking 配置
1.开发环境下的配置
// webpack.config.js
module.export = {
...
mode: 'development',
optimization: {
usedExports: true
}
}
2.生产环境下的配置
// webpack.config.js
module.exports = {
// ...
mode: 'production',
// ...
}
在生产环境下, Webpack 默认会添加 Tree Shaking 的配置,因此只需要写一行 mode: 'production' 即可。
3.配置 sideEffects: false,不同环境配置以后还需要再 package.json 中添加字段: sideEffects: false告诉 webpack 那些代码可以处理。
{
"name": "webpack-demo",
"sideEffects": false,
// ...
}
sideEffects
-
sideEffects 默认为 true ,告诉 webpack ,所有问价都有副作用,它们不能被 Tree Shaking。
-
sideEffects 为 false 时,告诉 webpack,没有文件是有副作用的,它们都可以 Tree Shaking。
-
sideEffects 为一个数组时, 告诉 webpack,数组中哪些文件不要进行 Tree Shaking,此外其他的可以 Tree Shaking。
// 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 have side effects, all other files can be tree-shaken, but these must be kept
{
"sideEffects": [
"./src/files1.js",
"./src/files2.js"
]
}
sideEffects 对全局CSS的影响
对那些直接引入带 js 文件的css文件,例如全局的 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 就会被当做无用diamante处理掉。
为了解决这个问题,可以在 loader 的规则配置中,添加 sideEffects: true ,告诉webpack这些文件不要 Tree Shaking 。
// webpack.config.js
module.exports = {
// ...
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
sideEffects: true
}
]
}
}
注意:这个字段在所有模块的规则都可以配置
或者在 package.json 中 配置 "sideEffects": [/\.css$/i]
,在数组列表中声明 css 类型的文件是有副作用的。