理解 sideEffects是什么 ,需要有一些前置知识, 那就是 webpack 的 tree shaking 以及 ESM 模块的 import , export
webpack 4添加了 sideEffects , 在 package.json 中添加这个属性, 表示, 哪些模块是 纯的ES6 模块, 当代码未被使用, webpack可以被删除
基于 ESM 模块的项目, 很轻松的能分析到, 哪些文件是未使用的, 可以轻松 树摇掉的, 但是项目中没办法达到这种纯度, 所以,可以通过如下的方式,告知 webpack 怎么处理未使用的代码
1、 直接在 package.json 中配置 sideEffects 为 false ,告知webpack 所有代码都没有副作用, 可以安全的删除
{
"name": "webpack 测试sideEffects 删除未使用的代码",
"sideEffects": false
}
2、如果代码里有副作用, 不希望webpack 比较果断的tree shaking , 我们通过给 sideEffects 配置一个数组, 告知webpack 哪些文件是 有副作用的, 不要tree shaking 掉
{
"name": "webpack 测试sideEffects 删除未使用的代码",
"sideEffects": [
"./src/some-side-effectful-file.js",
"/src/main.js",
"/\.css$/"
]
}
数组支持: 相对路径, 绝对路径, 还有 glob 模式
场景
webpack.config.js
const path = require("path")
const {CleanWebpackPlugin} = require("clean-webpack-plugin")
module.exports = {
mode: "production",
entry: {
app: path.resolve("./src/main.js")
},
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
publicPath: "/"
},
plugins: [
new CleanWebpackPlugin()
]
}
package.json
{
"main": "index.js",
"scripts": {
"build": "webpack"
},
"devDependencies": {
"clean-webpack-plugin": "^4.0.0",
"webpack": "^5.72.0",
"webpack-cli": "^4.9.2"
}
}
目录结构
- src
- lib.js
- main.js
- package.json
- webpack.config.js
场景1
main.js
这里只引入一个, 看看打包后的结果
import {add} from "./lib"
/**
* 场景1:这里只引入一个, 看看打包后的结果
* 结果: 只有打包后的运行结果 console.log(3) 直接给静态分析出来了
*/
console.log(add(1, 2))
lib.js
/**
* 导出2个工具函数
*/
export function add (a, b) {
return a + b
}
export function div (a, b) {
return a / b
}
npm run build 查看打包结果
(()=>{"use strict";console.log(3)})();
只有打包后的运行结果 console.log(3) 直接给静态分析出来了 , div 被 tree shaking 了
场景2
main.js
import {add} from "./lib"
/**
* 场景2:这里只引入一个,add 但是不调用, add 在 lib中执行过
* 结果: console.log(3) 也是直接执行了
*/
lib.js
/**
* 导出2个工具函数
*/
export function add (a, b) {
return a + b
}
export function div (a, b) {
return a / b
}
// 场景2: 在这里执行了, 看打包后的产物
console.log(add(1, 2))
npm run build 打包后的产物
(()=>{"use strict";console.log(3)})();
场景3
{
"name": "webpack 测试sideEffects 删除未使用的代码",
"sideEffects": false
}
main.js
import {add} from "./lib"
/**
* 场景3:这里只引入一个,add 但是不调用, add 在 lib中执行过, 在 package.json中添加了sideEffects: false
* 结果:打包后的产物, 什么都没有, 认为 add 是无副作用的,直接给 tree shaking 了
*/
lib.js
/**
* 导出2个工具函数
*/
export function add (a, b) {
return a + b
}
export function div (a, b) {
return a / b
}
// 不管这里执行还是不执行, 由于在 main.js 中只引入没有执行,所以webpack 认为是无副作用
// 直接移除了
console.log(add(1, 2))
app.bundle.js 中什么都没有, 空的
场景4
css文件通过 import 的方式引入, 应该是当做有副作用的文件, 不能被 tree shaking 的, 所有要指定package.json
文件结构
- src
- app.css
- lib.js
- main.js
- webpack.config.js
- package.json
main.js
import {add} from "./lib"
import "./app.css"
webpack.config.js
const path = require("path")
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
module.exports = {
mode: "production",
entry: {
app: path.resolve("./src/main.js")
},
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
publicPath: "/"
},
module: {
rules: [
{
test: /\.css$/,
use: "css-loader"
}
]
},
plugins: [
new CleanWebpackPlugin()
]
}
package.json
{
"main": "index.js",
"scripts": {
"build": "webpack"
},
"sideEffects": [
"./src/app.css"
],
"devDependencies": {
"clean-webpack-plugin": "^4.0.0",
"css-loader": "^6.7.1",
"webpack": "^5.72.0",
"webpack-cli": "^4.9.2"
}
}
打包后的产物,包含 css 符合期望, 如果不设置 sideEffects , 会导致 webpack 认为 css 无副作用, 直接被 tree shaking 掉
结语
sideEffects 就是为 tree shaking 服务的, 所以
- 使用 ES2015 模块语法 - 写你的项目
- 在项目的package.json 文件中,添加 sideEffects