死代码
Webpack 跟踪整个应用程序的 import/export 语句,因此,如果它看到导入的东西最终没有被使用它会认为那是“死代码”,并会对其进行 tree-shaking

  1. // 导入并赋值给 JavaScript 对象,然后在下面的代码中被用到
  2. // 这会被看作“活”代码,不会做 tree-shaking
  3. import Stuff from './stuff';
  4. doSomething(Stuff);
  5. // 导入并赋值给 JavaScript 对象,但在接下来的代码里没有用到
  6. // 这就会被当做“死”代码,会被 tree-shaking
  7. import Stuff from './stuff';
  8. doSomething();
  9. // 导入但没有赋值给 JavaScript 对象,也没有在代码里用到
  10. // 这会被当做“死”代码,会被 tree-shaking
  11. import './stuff';
  12. doSomething();
  13. // 导入整个库,但是没有赋值给 JavaScript 对象,也没有在代码里用到
  14. // 非常奇怪,这竟然被当做“活”代码,因为 Webpack 对库的导入和本地代码导入的处理方式不同。
  15. import 'my-lib';
  16. doSomething();
  17. // 全部导入 (不支持 tree-shaking)
  18. import _ from 'lodash';
  19. // 具名导入(支持 tree-shaking)
  20. import { debounce } from 'lodash';
  21. // 直接导入具体的模块 (支持 tree-shaking)
  22. import debounce from 'lodash/lib/debounce';

配置

  1. // Base Webpack Config for Tree Shaking
  2. const config = {
  3. mode: 'production',
  4. optimization: {
  5. usedExports: true,
  6. minimizer: [
  7. new TerserPlugin({...})
  8. ]
  9. }
  10. };

副作用

有些模块导入,只要被引入,就会对应用程序产生重要的影响。一个很好的例子就是全局样式表,或者设置全局配置的JavaScript 文件 这意味着 Webpack 的默认行为实际上是不进行 tree-shaking

  1. // 所有文件都有副作用,全都不可 tree-shaking
  2. {
  3. "sideEffects": true
  4. }
  5. // 没有文件有副作用,全都可以 tree-shaking
  6. {
  7. "sideEffects": false
  8. }
  9. // 只有这些文件有副作用,所有其他文件都可以 tree-shaking,但会保留这些文件
  10. {
  11. "sideEffects": [
  12. "./src/file1.js",
  13. "./src/file2.js"
  14. ]
  15. }
  16. // 全局 CSS 副作用规则相关的 Webpack 配置
  17. const config = {
  18. module: {
  19. rules: [
  20. {
  21. test: /regex/,
  22. use: [loaders],
  23. sideEffects: true
  24. }
  25. ]
  26. }
  27. };