当前位置: 首页>后端>正文

Webpack 5(七)Tree Shaking

参考文档

Tree Shaking 在打包的时候去除掉没有用到的代码。

想要实现 Tree Shaking 的功能,必须保证各个模块都采用 es6-module 语法来进行导入和导出。

有些第三方库不是采用 es6-module 语法来编写模块,则该库无法 Tree Shaking。

如果使用 Babel 的话,这里有一个小问题,因为 Babel 的预案(preset)默认会将任何模块类型都转译成 CommonJS 类型。修正这个问题也很简单,不是在 .babelrc 文件中就是在 webpack.config.js 文件中设置 modules: false 就好了。

对于 import() 动态引入的模块,无法进行 Tree Shaking。

配置

production 模式下,webpack 自动帮你配置好 optimization 选项,你不用做任何配置就能够 Tree Shaking。非 production 模式下,需要手动配置 optimization 选项,才能够 Tree Shaking。

相关配置选项:

  • optimization.minimize
  • optimization.minimizer
  • optimization.usedExports
  • optimization.sideEffects

optimization.usedExports: true optimization.sideEffects: true 标记未引用代码(dead code)
optimization.minimize: true 删除未引用代码,并压缩代码
optimization.minimizer: [] 指定代码压缩引擎

optimization 配置选项

optimization.minimize

是否使用压缩插件来压缩生成的 bundle 代码。

在 production 模式中 minimize 默认为 true。

module.exports = {
  optimization: {
    minimize: true
  }
}

optimization.minimizer

配置压缩插件,只有 minimize 为 true 的时候,配置 minimizer 才有用。

如果不配置该选项,则 webpack 4 默认采用 terser-webpack-plugin 插件,并且自动配置 terser-webpack-plugin 插件的 options 选项。安装 webpack 4 的时候会自动安装 terser-webpack-plugin,因此不需要 npm i -D terser-webpack-plugin

如果想要自己配置 terser-webpack-plugin 插件的 options 选项,需要手动配置 optimization.minimizer 选项。

module.exports = {
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin(options)
    ]
  }
}

还可以使用其他插件,例如使用 CssMinimizerPlugin 插件来压缩 css 代码

module.exports = {
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin(),
      new CssMinimizerPlugin()
    ]
  }
}

通过 '...' 表明使用系统默认的 TerserPlugin 插件以及默认配置

module.exports = {
  optimization: {
    minimize: true,
    minimizer: [
      '...',
      new CssMinimizerPlugin()
    ]
  }
}

optimization.usedExports

webpack 在打包文件的过程中,为未使用的 export 代码添加 /* unused harmony export */ 这样的注释。

在 production 模式中 usedExports 默认为 true。

module.exports = {
  optimization: {
    usedExports: true
  }
}

optimization.sideEffects

一个 es6 模块如果只是 export 一些变量以及函数,则该模块没有副作用。

如果一个 es6 模块除了 export 一些变量和函数,还做了其他的操作,比如定义了全局变量,或者写入日志等等,例如 import '@babel/polyfill' 这个模块,这个模块并没有 export 变量,而是直接定义了全局变量,因此该模块有副作用。

有副作用的模块不能够 tree shaking,因为虽然你的代码里面没有用到有副作用模块 export 的变量,但是也不能删除,因为那些代码可能会定义全局变量或者其他副作用。你删除了就不会定义全局变量或者其他副作用了。

如果一个包里面所有 es 模块都没有副作用,那么可以在 package.jsonsideEffects: false 指定,来告知 webpack 它可以安全地删除未用到的 export。

{
  "name": "your-project",
  "sideEffects": false
}

如果你的代码确实有一些副作用,可以改为提供一个数组:

{
  "name": "your-project",
  "sideEffects": ["./src/some-side-effectful-file.js"]
}

optimization.sideEffects 字段表明 webpack 是否会关注各个库中的 package.json 文件的 sideEffects 字段。

在 production 模式中 sideEffects 默认为 true。

module.exports = {
  optimization: {
    sideEffects: true
  }
}

实例

production 模式下

production 模式下,自动实现 Tree Shaking

module.exports = {
  mode: 'production'
}

非 production 模式下

none 和 development 模式下,需要配置 optimization.minimize optimization.usedExports optimization.sideEffects,才能实现 Tree Shaking

module.exports = {
  mode: 'none',
  optimization: {
    minimize: true,
    usedExports: true,
    sideEffects: true
  }
}

Tree Shaking 第三方库

如果你想要对库进行 Tree Shaking,首先要记住的注意点还是前面所说的:使用 ES6 模块。然而许多库并不一定使用 ES6 模块,比如 lodash 就是这样。因此我们需要安装 lodash-es 来代替 lodash。

npm i lodash-es
import { join } from lodash-es
join(['hello', 'webpack'], ' ')

https://www.xamrdz.com/backend/32v1941849.html

相关文章: