## 背景
先来讲下本篇文章的背景,我在自己搭建脚手架的时候,使用css-loader 和 style-loader 处理样式,打包后,插入 style 的代码可以在打包后的js文件中找到,但是html文件中插入style标签的代码并没有生效,相应的,我的css代码也并没有生效
## 原因
后来查了一下,因为我设置的模式(mode)是production,在webpack4.0以后,production模式下是自动开启tree shacking 的,关于tree shacking 对css的处理,可以参考官方文档的一段话(v 4.42.1)
> 注意,任何导入的文件都会受到 tree shaking 的影响。这意味着,如果在项目中使用类似 css-loader 并导入 CSS 文件,则需要将其添加到 side effect 列表中,以免在生产模式中无意中将它删除:
```
{
"name": "your-project",
"sideEffects": [
"./src/some-side-effectful-file.js",
"*.css"
]
}
```
## Tree Shacking 的一些概念
### Tree Shacking是什么
顾名思义,摇树,你可以将应用程序想象成一棵树。绿色表示实际用到的源码和 library,是树上活的树叶。灰色表示无用的代码,是秋天树上枯萎的树叶。为了除去死去的树叶,你必须摇动这棵树,使它们落下。
tree shaking 就是这样一个术语,用于描述移除 JavaScript 上下文中的未引用代码(dead-code)。它依赖于 ES2015 模块系统中的静态结构特性,例如 import 和 export。这个术语和概念实际上是兴起于 ES2015 模块打包工具 rollup。
- 在不使用 Tree Shacking 的情况下,一个文件中,只要有一个方法被使用到了,整个文件都会被打包到bundle中去,使用后,只会把用到的那个方法打包进去
- 依赖于 ES2015 模块系统中的静态结构特性,只有使用ES6的语法才支持
### Tree Shacking 机制
首先了解一个概念,DCE(dead-code elimination),无用代码擦除,如以下几种代码:
- 代码不可到达,永远不会被执行
- 代码执行的结果不会被用到
- 代码只会影响到死变量(只写不读)
- ...
识别无用代码是利用的ES6模块的特点:
- (import时)只能作为模块顶层的语句出现
- import的模块名只能是字符串常量
- import binding是无法擦除的
识别出后,使用 uglifyjs 压缩插件在压缩阶段 在 bundle 中删除它们。
### 副作用
在纯ES6代码中,我们做到这些是很容易的,然而,我们的项目无法达到这种纯度,所以,此时有必要向 webpack 的 compiler 提供提示哪些代码是“纯粹部分”。
> 所谓纯粹部分,是与副作用代码相对,副作用这个概念来源于函数式编程(FP),纯函数是没有副作用的,也不依赖外界环境或者改变外界环境。纯函数的概念是:接受相同的输入,任何情况下输出都是一样的。
> 非纯函数存在副作用,副作用就是:相同的输入,输出不一定相同(像是http请求函数)。或者这个函数会影响到外部变量、外部环境。
> 函数如果调用了全局对象或者改变函数外部变量,则说明这个函数有副作用。
> 在webpack的官方解释是:
> 「副作用」的定义是,在导入时会执行特殊行为的代码,而不是仅仅暴露一个 export 或多个 export。举例说明,例如 polyfill,它影响全局作用域,并且通常不提供 export。
有多种方法可以设置让一些文件避免Tree Shacking 的影响
1、通过 package.json 的 "sideEffects" 属性来实现
```
{
"name": "your-project",
"sideEffects": false
}
```
如同上面提到的,如果所有代码都不包含副作用,我们就可以简单地将该属性标记为 false,来告知 webpack,它可以安全地删除未用到的 export 导出,默认是这样设置的。
如果你的代码确实有一些副作用,那么可以改为提供一个数组:
```
{
"name": "your-project",
"sideEffects": [ // 标记为有副作用
"./src/some-side-effectful-file.js",
"*.css"
]
}
```
方法二:
```
rules: [
{
test: /\.css$/,
use: [
‘style-loader‘,
‘css-loader‘
],
sideEffects: true // 标记为有副作用
},
],
```
还有其他通过插件标记的,感兴趣的可以了解一下
参考文档: tree shaking 官方文档
原文:https://www.cnblogs.com/jiumengmeng/p/12835493.html