死代码
Webpack 跟踪整个应用程序的 import/export 语句,因此,如果它看到导入的东西最终没有被使用它会认为那是“死代码”,并会对其进行 tree-shaking
// 导入并赋值给 JavaScript 对象,然后在下面的代码中被用到// 这会被看作“活”代码,不会做 tree-shakingimport Stuff from './stuff';doSomething(Stuff);// 导入并赋值给 JavaScript 对象,但在接下来的代码里没有用到// 这就会被当做“死”代码,会被 tree-shakingimport Stuff from './stuff';doSomething();// 导入但没有赋值给 JavaScript 对象,也没有在代码里用到// 这会被当做“死”代码,会被 tree-shakingimport './stuff';doSomething();// 导入整个库,但是没有赋值给 JavaScript 对象,也没有在代码里用到// 非常奇怪,这竟然被当做“活”代码,因为 Webpack 对库的导入和本地代码导入的处理方式不同。import 'my-lib';doSomething();// 全部导入 (不支持 tree-shaking)import _ from 'lodash';// 具名导入(支持 tree-shaking)import { debounce } from 'lodash';// 直接导入具体的模块 (支持 tree-shaking)import debounce from 'lodash/lib/debounce';
配置
// Base Webpack Config for Tree Shakingconst config = {mode: 'production',optimization: {usedExports: true,minimizer: [new TerserPlugin({...})]}};
副作用
有些模块导入,只要被引入,就会对应用程序产生重要的影响。一个很好的例子就是全局样式表,或者设置全局配置的JavaScript 文件 这意味着 Webpack 的默认行为实际上是不进行 tree-shaking
// 所有文件都有副作用,全都不可 tree-shaking{"sideEffects": true}// 没有文件有副作用,全都可以 tree-shaking{"sideEffects": false}// 只有这些文件有副作用,所有其他文件都可以 tree-shaking,但会保留这些文件{"sideEffects": ["./src/file1.js","./src/file2.js"]}// 全局 CSS 副作用规则相关的 Webpack 配置const config = {module: {rules: [{test: /regex/,use: [loaders],sideEffects: true}]}};
