优化(Optimization)

从 webpack 4 开始,会根据你选择的 mode 来执行不同的优化, 不过所有的优化还是可以手动配置和重写。

optimization.minimize

boolean = true

告知 webpack 使用 TerserPlugin 或其它在 optimization.minimizer 定义的插件压缩 bundle。

webpack.config.js

module.exports = {
  //...
  optimization: {
    minimize: false,
  },
};

optimization.minimizer

[TerserPlugin][function (compiler)]

允许你通过提供一个或多个定制过的 TerserPlugin 实例, 覆盖默认压缩工具(minimizer)。

webpack.config.js

const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  optimization: {
    minimizer: [
      new TerserPlugin({
        parallel: true,
        sourceMap: true, // 如果在生产环境中使用 source-maps,必须设置为 true
        terserOptions: {
          // https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
        },
      }),
    ],
  },
};

或,使用函数的形式:

module.exports = {
  optimization: {
    minimizer: [
      (compiler) => {
        const TerserPlugin = require('terser-webpack-plugin');
        new TerserPlugin({
          /* 你的配置 */
        }).apply(compiler);
      },
    ],
  },
};

optimization.minimizer 中可以使用 '...' 来访问默认值。

module.exports = {
  optimization: {
    minimizer: [new CssMinimizer(), '...'],
  },
};

optimization.splitChunks

object

对于动态导入模块,默认使用 webpack v4+ 提供的全新的通用分块策略(common chunk strategy)。请在 SplitChunksPlugin 页面中查看配置其行为的可用选项。

optimization.runtimeChunk

object string boolean

optimization.runtimeChunk 设置为 true'multiple',会为每个入口添加一个只含有 runtime 的额外 chunk。此配置的别名如下:

webpack.config.js

module.exports = {
  //...
  optimization: {
    runtimeChunk: {
      name: (entrypoint) => `runtime~${entrypoint.name}`,
    },
  },
};

"single" 会创建一个在所有生成 chunk 之间共享的运行时文件。此设置是如下设置的别名:

webpack.config.js

module.exports = {
  //...
  optimization: {
    runtimeChunk: {
      name: 'runtime',
    },
  },
};

通过将 optimization.runtimeChunk 设置为 object,对象中可以设置只有 name 属性,其中属性值可以是名称或者返回名称的函数, 用于为 runtime chunks 命名。

默认值是 false:每个入口 chunk 中直接嵌入 runtime。

webpack.config.js

module.exports = {
  //...
  optimization: {
    runtimeChunk: {
      name: (entrypoint) => `runtimechunk~${entrypoint.name}`,
    },
  },
};

optimization.emitOnErrors

boolean = false

使用 optimization.emitOnErrors 在编译时每当有错误时,就会 emit asset。这样可以确保出错的 asset 被 emit 出来。关键错误会被 emit 到生成的代码中,并会在运行时报错。

webpack.config.js

module.exports = {
  //...
  optimization: {
    emitOnErrors: true,
  },
};

optimization.moduleIds

boolean: false string: 'natural' | 'named' | 'deterministic' | 'size'

告知 webpack 当选择模块 id 时需要使用哪种算法。将 optimization.moduleIds 设置为 false 会告知 webpack 没有任何内置的算法会被使用,但自定义的算法会由插件提供。

下面的字符串值均被支持:

选荐值描述
natural按使用顺序的数字 id。
named对调试更友好的可读的 id。
deterministic被哈希转化成的小位数值模块名。
size专注于让初始下载包大小更小的数字 id。

webpack.config.js

module.exports = {
  //...
  optimization: {
    moduleIds: 'deterministic',
  },
};

deterministic 选项有益于长期缓存,但对比于 hashed 来说,它会导致更小的文件 bundles。数字值的长度会被选作用于填满最多 80%的 id 空间。 当 optimization.moduleIds 被设置成 deterministic,默认最小 3 位数字会被使用。 要覆盖默认行为,要将 optimization.moduleIds 设置成 false, 并且要使用 webpack.ids.DeterministicModuleIdsPlugin

webpack.config.js

module.exports = {
  //...
  optimization: {
    moduleIds: false,
  },
  plugins: [
    new webpack.ids.DeterministicModuleIdsPlugin({
      maxLength: 5,
    }),
  ],
};

optimization.chunkIds

boolean = false string: 'natural' | 'named' | 'size' | 'total-size' | 'deterministic'

告知 webpack 当选择模块 id 时需要使用哪种算法。将 optimization.chunkIds 设置为 false 会告知 webpack 没有任何内置的算法会被使用,但自定义的算法会由插件提供。optimization.chunkIds 的默认值是 false

  • 如果环境是开发环境,那么 optimization.chunkIds 会被设置成 'named', 但当在生产环境中时,它会被设置成 'deterministic'
  • 如果上述的条件都不符合, optimization.chunkIds 会被默认设置为 'natural'

下述选项字符串值均为被支持:

选项值描述
'natural'按使用顺序的数字 id。
'named'对调试更友好的可读的 id。
'deterministic'在不同的编译中不变的短数字 id。有益于长期缓存。在生产模式中会默认开启。
'size'专注于让初始下载包大小更小的数字 id。
'total-size'专注于让总下载包大小更小的数字 id。

webpack.config.js

module.exports = {
  //...
  optimization: {
    chunkIds: 'named',
  },
};

默认地,当 optimization.chunkIds 被设置为 'deterministic' 时,最少 3 位数字会被使用。要覆盖默认的行为, 要将 optimization.chunkIds 设置为 false,同时要使用 webpack.ids.DeterministicChunkIdsPlugin

webpack.config.js

module.exports = {
  //...
  optimization: {
    chunkIds: false,
  },
  plugins: [
    new webpack.ids.DeterministicChunkIdsPlugin({
      maxLength: 5,
    }),
  ],
};

optimization.nodeEnv

boolean = false string

告知 webpack 将 process.env.NODE_ENV 设置为一个给定字符串。如果 optimization.nodeEnv 不是 false,则会使用 DefinePluginoptimization.nodeEnv 默认值取决于 mode,如果为 falsy 值,则会回退到 "production"

可能的值有:

  • 任何字符串:用于设置 process.env.NODE_ENV 的值。
  • false:不修改/设置 process.env.NODE_ENV的值。

webpack.config.js

module.exports = {
  //...
  optimization: {
    nodeEnv: 'production',
  },
};

optimization.mangleWasmImports

boolean = false

在设置为 true 时,告知 webpack 通过将导入修改为更短的字符串,来减少 WASM 大小。这会破坏模块和导出名称。

webpack.config.js

module.exports = {
  //...
  optimization: {
    mangleWasmImports: true,
  },
};

optimization.removeAvailableModules

boolean = false

如果模块已经包含在所有父级模块中,告知 webpack 从 chunk 中检测出这些模块,或移除这些模块。将 optimization.removeAvailableModules 设置为 true 以启用这项优化。在 生产 模式 中默认会被开启。

webpack.config.js

module.exports = {
  //...
  optimization: {
    removeAvailableModules: true,
  },
};

optimization.removeEmptyChunks

boolean = true

如果 chunk 为空,告知 webpack 检测或移除这些 chunk。将 optimization.removeEmptyChunks 设置为 false 以禁用这项优化。

webpack.config.js

module.exports = {
  //...
  optimization: {
    removeEmptyChunks: false,
  },
};

optimization.mergeDuplicateChunks

boolean = true

告知 webpack 合并含有相同模块的 chunk。将 optimization.mergeDuplicateChunks 设置为 false 以禁用这项优化。

webpack.config.js

module.exports = {
  //...
  optimization: {
    mergeDuplicateChunks: false,
  },
};

optimization.flagIncludedChunks

boolean

告知 webpack 确定和标记出作为其他 chunk 子集的那些 chunk,其方式是在已经加载过较大的 chunk 之后,就不再去加载这些 chunk 子集。optimization.flagIncludedChunks 默认会在 生产 模式 中启用,其他情况禁用。

webpack.config.js

module.exports = {
  //...
  optimization: {
    flagIncludedChunks: true,
  },
};

optimization.providedExports

boolean

告知 webpack 去确定那些由模块提供的导出内容,为 export * from ... 生成更多高效的代码。默认 optimization.providedExports 会被启用。

webpack.config.js

module.exports = {
  //...
  optimization: {
    providedExports: false,
  },
};

optimization.usedExports

boolean = true string: 'global'

告知 webpack 去决定每个模块使用的导出内容。这取决于 optimization.providedExports 选项。由 optimization.usedExports 收集的信息会被其它优化手段或者代码生成使用,比如未使用的导出内容不会被生成,当所有的使用都适配,导出名称会被处理做单个标记字符。 在压缩工具中的无用代码清除会受益于该选项,而且能够去除未使用的导出内容。

webpack.config.js

module.exports = {
  //...
  optimization: {
    usedExports: false,
  },
};

选择退出每次运行时使用 export 分享:

module.exports = {
  //...
  optimization: {
    usedExports: 'global',
  },
};

optimization.concatenateModules

boolean

告知 webpack 去寻找模块图形中的片段,哪些是可以安全地被合并到单一模块中。这取决于 optimization.providedExportsoptimization.usedExports。 默认 optimization.concatenateModules生产 模式 下被启用,而在其它情况下被禁用。

webpack.config.js

module.exports = {
  //...
  optimization: {
    concatenateModules: true,
  },
};

optimization.sideEffects

boolean = true string: 'flag'

告知 webpack 去辨识 package.json 中的 副作用 标记或规则,以跳过那些当导出不被使用且被标记不包含副作用的模块。

package.json

{
  "name": "awesome npm module",
  "version": "1.0.0",
  "sideEffects": false
}

optimization.sideEffects 取决于 optimization.providedExports 被设置成启用。这个依赖会有构建时间的损耗,但去掉模块会对性能有正面的影响,因为更少的代码被生成。该优化的效果取决于你的代码库, 可以尝试这个特性以获取一些可能的性能优化。

webpack.config.js

module.exports = {
  //...
  optimization: {
    sideEffects: true,
  },
};

只使用手动 flag,并且不对源码进行分析:

module.exports = {
  //...
  optimization: {
    sideEffects: 'flag',
  },
};

此处的 'flag' 值在非生产环境默认使用。

optimization.portableRecords

boolean

optimization.portableRecords 告知 webpack 生成带有相对路径的记录(records)使得可以移动上下文目录。

默认 optimization.portableRecords 被禁用。如果下列至少一个选项在 webpack 中被设置,该选项也会自动启用:recordsPath, recordsInputPath, recordsOutputPath

webpack.config.js

module.exports = {
  //...
  optimization: {
    portableRecords: true,
  },
};

optimization.mangleExports

boolean string: 'deterministic' | 'size'

optimization.mangleExports 允许控制导出处理(export mangling)。

默认 optimization.mangleExports: 'deterministic' 会在 production 模式下 启用而其它情况会被禁用。

此选项支持以下选项:

选项描述
'size'简写形式 — 通常只有一个字符 — 专注于最小的下载 size。
'deterministic'简写形式 - 通常两个字符 — 在添加或移除 export 时不会改变。适用于长效缓存。
true等价于 'deterministic'
false保留原名,有利于阅读和调试。

webpack.config.js

module.exports = {
  //...
  optimization: {
    mangleExports: true,
  },
};

optimization.innerGraph

boolean = true

optimization.innerGraph 告知 webpack 是否对未使用的导出内容,实施内部图形分析(graph analysis)。

webpack.config.js

module.exports = {
  //...
  optimization: {
    innerGraph: false,
  },
};

optimization.realContentHash

boolean = true

Adds an additional hash compilation pass after the assets have been processed to get the correct asset content hashes. If realContentHash is set to false, internal data is used to calculate the hash and it can change when assets are identical.

webpack.config.js

module.exports = {
  //...
  optimization: {
    realContentHash: false,
  },
};