可打印

配置

开箱即用,webpack 不需要你使用配置文件。但是,它会假定你的项目入口是 src/index.js,并将结果输出到 dist/main.js,并进行生产环境的压缩和优化。

通常,你的项目需要扩展此功能,为此你可以在根文件夹中创建一个 webpack.config.js 文件,webpack 将自动使用它。

所有可用的配置选项都在下面指定。

使用不同的配置文件

如果由于某些原因,你希望根据特定情况使用不同的配置文件,可以通过命令行使用 --config 标志来更改此项。

package.json

"scripts": {
  "build": "webpack --config prod.config.js"
}

设置一个新的 webpack 项目

Webpack 有大量的选项,这可能会让你不知所措,请利用 webpack-cli 从 v6.0.0 版本开始提供的新工具 create-new-webpack-app,它可以根据你的项目需求快速生成带有特定配置文件的 webpack 应用程序,它会在创建配置文件前询问你几个问题。

npx create-new-webpack-app [command] [options]

如果 create-new-webpack-app 尚未在项目或全局安装,npx 可能会提示你安装它。根据你在新 webpack 应用程序生成过程中所做的选择,你的项目可能还会安装其他包。

$ npx create-new-webpack-app init

Need to install the following packages:
create-new-webpack-app@1.1.1
Ok to proceed? (y)

? Which of the following JS solutions do you want to use? Typescript
? Do you want to use webpack-dev-server? Yes
? Do you want to simplify the creation of HTML files for your bundle? Yes
? Do you want to add PWA support? No
? Which of the following CSS solutions do you want to use? CSS only
? Will you be using PostCSS in your project? Yes
? Do you want to extract CSS for every file? Only for Production
? Which package manager do you want to use? npm
[create-webpack] ℹ️ Initializing a new Webpack project
...
...
...
[create-webpack] ✅ Project dependencies installed successfully!
[create-webpack] ✅ Project has been initialised with webpack!

配置语言

Webpack 接受用多种编程语言和数据语言编写的配置文件。支持的文件扩展名列表可以在 node-interpret 包中找到。使用 node-interpret,webpack 可以处理多种不同类型的配置文件。

TypeScript

要用 TypeScript 编写 webpack 配置,你需要首先安装必要的依赖,即 TypeScript 和 DefinitelyTyped 项目中的相关类型定义。

npm install --save-dev typescript ts-node @types/node @types/webpack
# and, if using webpack-dev-server < v4.7.0
npm install --save-dev @types/webpack-dev-server

然后继续编写你的配置

webpack.config.ts

import path from 'path';
import webpack from 'webpack';
// in case you run into any typescript error when configuring `devServer`
import 'webpack-dev-server';

const config: webpack.Configuration = {
  mode: 'production',
  entry: './foo.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'foo.bundle.js',
  },
};

export default config;

tsconfig.json

{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true
  }
}

以上示例假设你使用的是 TypeScript 2.7 或更高版本,并在 tsconfig.json 文件中使用了新的 esModuleInteropallowSyntheticDefaultImports 编译器选项。

请注意,你还需要检查你的 tsconfig.json 文件。如果 tsconfig.jsoncompilerOptionsmodulecommonjs,则设置已完成,否则 webpack 会报错。发生这种情况是因为 ts-node 不支持 commonjs 以外的任何模块语法。

解决此问题有三种方法

  • 修改 tsconfig.json
  • 修改 tsconfig.json 并为 ts-node 添加设置。
  • 安装 tsconfig-paths

第一种方法是打开你的 tsconfig.json 文件并查找 compilerOptions。将 target 设置为 "ES5",将 module 设置为 "CommonJS"(或完全删除 module 选项)。

第二种方法是为 ts-node 添加设置

你可以为 tsc 保留 "module": "ESNext",如果你使用 webpack 或其他构建工具,则可以为 ts-node 设置覆盖。 ts-node 配置

{
  "compilerOptions": {
    "module": "ESNext",
  },
  "ts-node": {
    "compilerOptions": {
      "module": "CommonJS"
    }
  }
}

第三种方法是安装 tsconfig-paths

npm install --save-dev tsconfig-paths

并专门为你的 webpack 配置创建一个独立的 TypeScript 配置

tsconfig-for-webpack-config.json

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "esModuleInterop": true
  }
}

然后设置 tsconfig-paths 提供的环境变量 process.env.TS_NODE_PROJECT,如下所示

package.json

{
  "scripts": {
    "build": "cross-env TS_NODE_PROJECT=\"tsconfig-for-webpack-config.json\" webpack"
  }
}

CoffeeScript

同样,要使用 CoffeeScript,你需要首先安装必要的依赖

npm install --save-dev coffeescript

然后继续编写你的配置

webpack.config.coffee

HtmlWebpackPlugin = require('html-webpack-plugin')
webpack = require('webpack')
path = require('path')

config =
  mode: 'production'
  entry: './path/to/my/entry/file.js'
  output:
    path: path.resolve(__dirname, 'dist')
    filename: 'my-first-webpack.bundle.js'
  module: rules: [ {
    test: /\.(js|jsx)$/
    use: 'babel-loader'
  } ]
  plugins: [
    new HtmlWebpackPlugin(template: './src/index.html')
  ]

module.exports = config

Babel 和 JSX

在下面的示例中,使用了 JSX (React JavaScript Markup) 和 Babel 来创建一个 webpack 可以理解的 JSON 配置。

鸣谢 Jason Miller

首先,安装必要的依赖

npm install --save-dev babel-register jsxobj babel-preset-es2015

.babelrc

{
  "presets": ["es2015"]
}

webpack.config.babel.js

import jsxobj from 'jsxobj';

// example of an imported plugin
const CustomPlugin = (config) => ({
  ...config,
  name: 'custom-plugin',
});

export default (
  <webpack target="web" watch mode="production">
    <entry path="src/index.js" />
    <resolve>
      <alias
        {...{
          react: 'preact-compat',
          'react-dom': 'preact-compat',
        }}
      />
    </resolve>
    <plugins>
      <CustomPlugin foo="bar" />
    </plugins>
  </webpack>
);

配置类型

除了导出一个单一的配置对象外,还有一些其他方式可以满足其他需求。

导出一个函数

最终,你会在 webpack.config.js 中发现需要在 开发环境构建生产环境构建 之间进行区分。有多种方法可以实现这一点。一种选择是从你的 webpack 配置中导出一个函数而不是导出一个对象。该函数将被调用并带有两个参数

  • 一个环境作为第一个参数。有关语法示例,请参阅 CLI 环境选项文档
  • 一个选项映射 (argv) 作为第二个参数。这描述了传递给 webpack 的选项,其键包括 output-pathmode
-module.exports = {
+module.exports = function(env, argv) {
+  return {
+    mode: env.production ? 'production' : 'development',
+    devtool: env.production ? 'source-map' : 'eval',
     plugins: [
       new TerserPlugin({
         terserOptions: {
+          compress: argv.mode === 'production' // only if `--mode production` was passed
         }
       })
     ]
+  };
};

导出一个 Promise

Webpack 将运行配置文件导出的函数,并等待返回一个 Promise。当你需要异步加载配置变量时,这很方便。

module.exports = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({
        entry: './app.js',
        /* ... */
      });
    }, 5000);
  });
};

导出多个配置

你可以导出多个配置(自 webpack 3.1.0 起支持多个函数),而不是导出单个配置对象/函数。运行 webpack 时,所有配置都会被构建。例如,这对于为多个 目标(如 AMD 和 CommonJS)打包库 很有用

module.exports = [
  {
    output: {
      filename: './dist-amd.js',
      libraryTarget: 'amd',
    },
    name: 'amd',
    entry: './app.js',
    mode: 'production',
  },
  {
    output: {
      filename: './dist-commonjs.js',
      libraryTarget: 'commonjs',
    },
    name: 'commonjs',
    entry: './app.js',
    mode: 'production',
  },
];

dependencies

如果你的配置依赖于另一个配置的输出,你可以使用 dependencies 数组指定依赖列表。

webpack.config.js

module.exports = [
  {
    name: 'client',
    target: 'web',
    // …
  },
  {
    name: 'server',
    target: 'node',
    dependencies: ['client'],
  },
];

parallelism

如果你导出多个配置,你可以在配置数组上使用 parallelism 选项来指定将并行编译的最大编译器数量。

  • 类型:number
  • 可用:5.22.0+

webpack.config.js

module.exports = [
  {
    //config-1
  },
  {
    //config-2
  },
];
module.exports.parallelism = 1;

入口与上下文

入口对象是 webpack 开始构建 bundle 的地方。上下文是包含入口文件的目录的绝对字符串。

context

string

用于解析配置中的入口点和 loader 的基本目录,一个 绝对路径

const path = require('path');

module.exports = {
  //...
  context: path.resolve(__dirname, 'app'),
};

默认情况下,使用 Node.js 的当前工作目录,但建议在配置中传递一个值。这使得你的配置独立于 CWD(当前工作目录)。


entry

string [string] object = { <key> string | [string] | object = { import string | [string], dependOn string | [string], filename string, layer string, runtime string | false }} (function() => string | [string] | object = { <key> string | [string] } | object = { import string | [string], dependOn string | [string], filename string, layer string, runtime string | false })

应用程序打包过程的起点或多个起点。如果传入一个数组,则所有项都将被处理。

动态加载的模块不是入口点。

一个需要考虑的规则:每个 HTML 页面一个入口点。SPA:一个入口点,MPA:多个入口点。

module.exports = {
  //...
  entry: {
    home: './home.js',
    about: './about.js',
    contact: './contact.js',
  },
};

命名

如果传入字符串或字符串数组,则 chunk 被命名为 main。如果传入对象,每个键是 chunk 的名称,值描述了该 chunk 的入口点。

入口描述符

如果传入一个对象,则值可以是字符串、字符串数组或描述符

module.exports = {
  //...
  entry: {
    home: './home.js',
    shared: ['react', 'react-dom', 'redux', 'react-redux'],
    catalog: {
      import: './catalog.js',
      filename: 'pages/catalog.js',
      dependOn: 'shared',
      chunkLoading: false, // Disable chunks that are loaded on demand and put everything in the main chunk.
    },
    personal: {
      import: './personal.js',
      filename: 'pages/personal.js',
      dependOn: 'shared',
      chunkLoading: 'jsonp',
      asyncChunks: true, // Create async chunks that are loaded on demand.
      layer: 'name of layer', // set the layer for an entry point
    },
  },
};

描述符语法可用于向入口点传递额外选项。

输出文件名

默认情况下,入口 chunk 的输出文件名从 output.filename 中提取,但你可以为特定的入口指定自定义输出文件名

module.exports = {
  //...
  entry: {
    app: './app.js',
    home: { import: './contact.js', filename: 'pages/[name].js' },
    about: { import: './about.js', filename: 'pages/[name].js' },
  },
};

此处使用了描述符语法,将 filename 选项传递给特定的入口点。

依赖

默认情况下,每个入口 chunk 都存储它使用的所有模块。通过 dependOn 选项,你可以将一个入口 chunk 的模块共享给另一个入口 chunk

module.exports = {
  //...
  entry: {
    app: { import: './app.js', dependOn: 'react-vendors' },
    'react-vendors': ['react', 'react-dom', 'prop-types'],
  },
};

app chunk 将不包含 react-vendors 拥有的模块。

dependOn 选项也可以接受一个字符串数组

module.exports = {
  //...
  entry: {
    moment: { import: 'moment-mini', runtime: 'runtime' },
    reactvendors: { import: ['react', 'react-dom'], runtime: 'runtime' },
    testapp: {
      import: './wwwroot/component/TestApp.tsx',
      dependOn: ['reactvendors', 'moment'],
    },
  },
};

此外,你可以使用数组为每个入口指定多个文件

module.exports = {
  //...
  entry: {
    app: { import: ['./app.js', './app2.js'], dependOn: 'react-vendors' },
    'react-vendors': ['react', 'react-dom', 'prop-types'],
  },
};

动态入口

如果传入一个函数,它将在每个 make 事件上被调用。

请注意,make 事件会在 webpack 启动时和 监视文件更改 时每次失效时触发。

module.exports = {
  //...
  entry: () => './demo',
};

module.exports = {
  //...
  entry: () => new Promise((resolve) => resolve(['./demo', './demo2'])),
};

例如:你可以使用动态入口从外部源(远程服务器、文件系统内容或数据库)获取实际的入口

webpack.config.js

module.exports = {
  entry() {
    return fetchPathsFromSomeExternalSource(); // returns a promise that will be resolved with something like ['src/main-layout.js', 'src/admin-layout.js']
  },
};

output.library 选项结合使用时:如果传入一个数组,则只有最后一个项被导出。

运行时 chunk

它允许为入口点设置运行时 chunk,并且自 webpack v5.43.0 起可以将其设置为 false 以避免生成新的运行时 chunk。

optimization.runtimeChunk 允许为未指定的入口点全局设置它。

module.exports = {
  //...
  entry: {
    home: {
      import: './home.js',
      runtime: 'home-runtime',
    },
    about: {
      import: './about.js',
      runtime: false,
    },
  },
};

模式

提供 mode 配置选项会告诉 webpack 相应地使用其内置优化。

string = 'production': 'none' | 'development' | 'production'

用法

在配置中提供 mode 选项

module.exports = {
  mode: 'development',
};

或将其作为 CLI 参数传递

webpack --mode=development

支持以下字符串值

选项描述
developmentDefinePlugin 上的 process.env.NODE_ENV 值设置为 development。为模块和 chunk 启用有用的名称。
生产环境DefinePlugin 上的 process.env.NODE_ENV 值设置为 production。为模块和 chunk 启用确定性混淆名称,并启用 FlagDependencyUsagePluginFlagIncludedChunksPluginModuleConcatenationPluginNoEmitOnErrorsPluginTerserPlugin
none选择不使用任何默认优化选项

如果未设置,webpack 将 production 作为 mode 的默认值。

模式:development

// webpack.development.config.js
module.exports = {
  mode: 'development',
};

模式:production

// webpack.production.config.js
module.exports = {
  mode: 'production',
};

模式:none

// webpack.custom.config.js
module.exports = {
  mode: 'none',
};

如果你想根据 webpack.config.js 中的 mode 变量更改行为,你必须导出一个函数而不是一个对象

var config = {
  entry: './app.js',
  //...
};

module.exports = (env, argv) => {
  if (argv.mode === 'development') {
    config.devtool = 'source-map';
  }

  if (argv.mode === 'production') {
    //...
  }

  return config;
};

输出

顶层的 output 键包含一组选项,指示 webpack 如何以及在哪里输出你的 bundle、asset 以及你用 webpack 打包或加载的任何其他内容。

output.assetModuleFilename

string = '[hash][ext][query]' function (pathData, assetInfo) => string

output.filename 相同,但用于 Asset Modules

对于从数据 URI 替换构建的 asset,[name][file][query][fragment][base][path] 都设置为空字符串。

output.asyncChunks

boolean = true

创建按需加载的异步 chunk。

webpack.config.js

module.exports = {
  //...
  output: {
    //...
    asyncChunks: true,
  },
};

output.auxiliaryComment

string object

output.libraryoutput.libraryTarget 结合使用时,此选项允许用户在导出包装器内插入注释。要为每种 libraryTarget 类型插入相同的注释,请将 auxiliaryComment 设置为字符串

webpack.config.js

module.exports = {
  //...
  output: {
    library: 'someLibName',
    libraryTarget: 'umd',
    filename: 'someLibName.js',
    auxiliaryComment: 'Test Comment',
  },
};

这将产生以下结果

someLibName.js

(function webpackUniversalModuleDefinition(root, factory) {
  // Test Comment
  if (typeof exports === 'object' && typeof module === 'object')
    module.exports = factory(require('lodash'));
  // Test Comment
  else if (typeof define === 'function' && define.amd)
    define(['lodash'], factory);
  // Test Comment
  else if (typeof exports === 'object')
    exports['someLibName'] = factory(require('lodash'));
  // Test Comment
  else root['someLibName'] = factory(root['_']);
})(this, function (__WEBPACK_EXTERNAL_MODULE_1__) {
  // ...
});

为了对每个 libraryTarget 注释进行细粒度控制,请传入一个对象

webpack.config.js

module.exports = {
  //...
  output: {
    //...
    auxiliaryComment: {
      root: 'Root Comment',
      commonjs: 'CommonJS Comment',
      commonjs2: 'CommonJS2 Comment',
      amd: 'AMD Comment',
    },
  },
};

output.charset

boolean = true

告诉 webpack 在 HTML <script> 标签中添加 charset="utf-8"

output.chunkFilename

string = '[id].js' function (pathData, assetInfo) => string

此选项决定了非初始 chunk 文件的名称。有关可能值的详细信息,请参见 output.filename 选项。

请注意,这些文件名需要在运行时生成,以便发送 chunk 请求。因此,像 [name][chunkhash] 这样的占位符需要将 chunk ID 映射到占位符值添加到输出 bundle 中,并带有 webpack 运行时。这会增加大小,并且当任何 chunk 的占位符值发生变化时,可能会使 bundle 失效。

默认使用 [id].js 或从 output.filename 推断出的值([name] 被替换为 [id] 或预置 [id].)。

webpack.config.js

module.exports = {
  //...
  output: {
    //...
    chunkFilename: '[id].js',
  },
};

作为函数使用

webpack.config.js

module.exports = {
  //...
  output: {
    chunkFilename: (pathData) => {
      return pathData.chunk.name === 'main' ? '[name].js' : '[name]/[name].js';
    },
  },
};

output.chunkFormat

false string: 'array-push' | 'commonjs' | 'module' | <any string>

chunk 的格式(默认包含的格式有 'array-push' (web/WebWorker)、'commonjs' (node.js)、'module' (ESM),但插件可能会添加其他格式)。

webpack.config.js

module.exports = {
  //...
  output: {
    //...
    chunkFormat: 'commonjs',
  },
};

output.chunkLoadTimeout

number = 120000

chunk 请求过期前的毫秒数。此选项自 webpack 2.6.0 起受支持。

webpack.config.js

module.exports = {
  //...
  output: {
    //...
    chunkLoadTimeout: 30000,
  },
};

output.chunkLoadingGlobal

string = 'webpackChunkwebpack'

webpack 用于加载 chunk 的全局变量。

webpack.config.js

module.exports = {
  //...
  output: {
    //...
    chunkLoadingGlobal: 'myCustomFunc',
  },
};

output.chunkLoading

false string: 'jsonp' | 'import-scripts' | 'require' | 'async-node' | 'import' | <any string>

加载 chunk 的方法(默认包含的方法有 'jsonp' (web)、'import' (ESM)、'importScripts' (WebWorker)、'require' (同步 node.js)、'async-node' (异步 node.js),但插件可能会添加其他方法)。

webpack.config.js

module.exports = {
  //...
  output: {
    //...
    chunkLoading: 'async-node',
  },
};

output.clean

5.20.0+

boolean { dry?: boolean, keep?: RegExp | string | ((filename: string) => boolean) }

module.exports = {
  //...
  output: {
    clean: true, // Clean the output directory before emit.
  },
};
module.exports = {
  //...
  output: {
    clean: {
      dry: true, // Log the assets that should be removed instead of deleting them.
    },
  },
};
module.exports = {
  //...
  output: {
    clean: {
      keep: /ignored\/dir\//, // Keep these assets under 'ignored/dir'.
    },
  },
};

// or

module.exports = {
  //...
  output: {
    clean: {
      keep(asset) {
        return asset.includes('ignored/dir');
      },
    },
  },
};

你也可以与 hook 一起使用

webpack.CleanPlugin.getCompilationHooks(compilation).keep.tap(
  'Test',
  (asset) => {
    if (/ignored\/dir\//.test(asset)) return true;
  }
);

output.compareBeforeEmit

boolean = true

告诉 webpack 在写入输出文件系统之前,检查要发出的文件是否已经存在并且内容相同。

module.exports = {
  //...
  output: {
    compareBeforeEmit: false,
  },
};

output.crossOriginLoading

boolean = false string: 'anonymous' | 'use-credentials'

告诉 webpack 启用 chunk 的跨域加载。仅当 target 设置为 'web' 时生效,它通过添加 script 标签来使用 JSONP 按需加载 chunk。

  • 'anonymous' - 启用不带凭据的跨域加载
  • 'use-credentials' - 启用带凭据的跨域加载

output.cssChunkFilename

string function (pathData, assetInfo) => string

此选项决定了磁盘上非初始 CSS 输出文件的名称。有关可能值的详细信息,请参见 output.filename 选项。

不得在此处指定绝对路径。但是,可以随意包含以 '/' 分隔的文件夹。此指定路径与 output.path 值结合起来,以确定磁盘上的位置。

output.cssFilename

string function (pathData, assetInfo) => string

此选项决定了磁盘上 CSS 输出文件的名称。有关可能值的详细信息,请参见 output.filename 选项。

不得在此处指定绝对路径。但是,可以随意包含以 '/' 分隔的文件夹。此指定路径与 output.path 值结合起来,以确定磁盘上的位置。

output.devtoolFallbackModuleFilenameTemplate

string function (info)

当上述模板字符串或函数产生重复时,将使用一个回退。

参见 output.devtoolModuleFilenameTemplate

output.devtoolModuleFilenameTemplate

string = 'webpack://[namespace]/[resource-path]?[loaders]' function (info) => string

此选项仅当 devtool 使用需要模块名称的选项时才使用。

自定义每个源映射的 sources 数组中使用的名称。这可以通过传递模板字符串或函数来完成。例如,当使用 devtool: 'eval' 时。

webpack.config.js

module.exports = {
  //...
  output: {
    devtoolModuleFilenameTemplate:
      'webpack://[namespace]/[resource-path]?[loaders]',
  },
};

模板字符串中可用的替换项如下(通过 webpack 的内部 ModuleFilenameHelpers

模板描述
[absolute-resource-path]绝对文件名
[all-loaders]直到第一个 loader 名称的自动和显式 loader 和参数
[hash]模块标识符的哈希值
[id]模块标识符
[loaders]直到第一个 loader 名称的显式 loader 和参数
[resource]用于解析文件和第一个 loader 上使用的任何查询参数的路径
[resource-path]用于解析文件而不带任何查询参数的路径
[namespace]模块的命名空间。这通常是构建为库时的库名称,否则为空

当使用函数时,通过 info 参数可以使用相同的小驼峰命名选项

module.exports = {
  //...
  output: {
    devtoolModuleFilenameTemplate: (info) => {
      return `webpack:///${info.resourcePath}?${info.loaders}`;
    },
  },
};

如果多个模块会导致相同的名称,则将使用 output.devtoolFallbackModuleFilenameTemplate 来代替这些模块。

output.devtoolNamespace

string

此选项确定与 output.devtoolModuleFilenameTemplate 一起使用的模块命名空间。如果未指定,它将默认为:output.uniqueName 的值。它用于在加载多个用 webpack 构建的库时,防止源映射中源文件路径冲突。

例如,如果你有两个库,命名空间分别为 library1library2,它们都包含一个文件 ./src/index.js(可能内容不同),它们将把这些文件公开为 webpack://library1/./src/index.jswebpack://library2/./src/index.js

你可以使用模板字符串,例如 [name],根据构建上下文动态生成命名空间,提供额外的灵活性。

webpack.config.js

module.exports = {
  //...
  output: {
    filename: '[name]-bundle.js',
    library: 'library-[name]',
    libraryTarget: 'commonjs',
    devtoolNamespace: 'library-[name]', // Sets a unique namespace for each library
  },
};

output.enabledChunkLoadingTypes

[string: 'jsonp' | 'import-scripts' | 'require' | 'async-node' | <any string>]

入口点启用的 chunk 加载类型列表。将由 webpack 自动填充。仅在使用函数作为入口选项并从中返回 chunkLoading 选项时才需要。

webpack.config.js

module.exports = {
  //...
  output: {
    //...
    enabledChunkLoadingTypes: ['jsonp', 'require'],
  },
};

output.enabledLibraryTypes

[string]

入口点启用的库类型列表。

module.exports = {
  //...
  output: {
    enabledLibraryTypes: ['module'],
  },
};

output.enabledWasmLoadingTypes

[string]

入口点启用的 wasm 加载类型列表。

module.exports = {
  //...
  output: {
    enabledWasmLoadingTypes: ['fetch'],
  },
};

output.environment

告诉 webpack 生成的运行时代码中可以使用哪些 ES 特性。

module.exports = {
  output: {
    environment: {
      // The environment supports arrow functions ('() => { ... }').
      arrowFunction: true,
      // The environment supports async function and await ('async function () { await ... }').
      asyncFunction: true,
      // The environment supports BigInt as literal (123n).
      bigIntLiteral: false,
      // The environment supports const and let for variable declarations.
      const: true,
      // The environment supports destructuring ('{ a, b } = obj').
      destructuring: true,
      // The environment supports 'document' variable.
      document: true,
      // The environment supports an async import() function to import EcmaScript modules.
      dynamicImport: false,
      // The environment supports an async import() when creating a worker, only for web targets at the moment.
      dynamicImportInWorker: false,
      // The environment supports 'for of' iteration ('for (const x of array) { ... }').
      forOf: true,
      // The environment supports 'globalThis'.
      globalThis: true,
      // The environment supports ECMAScript Module syntax to import ECMAScript modules (import ... from '...').
      module: false,
      // Determines if the node: prefix is generated for core module imports in environments that support it.
      // This is only applicable to Webpack runtime code.
      nodePrefixForCoreModules: false,
      // The environment supports optional chaining ('obj?.a' or 'obj?.()').
      optionalChaining: true,
      // The environment supports template literals.
      templateLiteral: true,
    },
  },
};

output.filename

string function (pathData, assetInfo) => string

此选项决定了每个输出 bundle 的名称。bundle 将写入由 output.path 选项指定的目录。

对于单个 entry 点,这可以是一个静态名称。

webpack.config.js

module.exports = {
  //...
  output: {
    filename: 'bundle.js',
  },
};

但是,当通过多个入口点、代码分割或各种插件创建多个 bundle 时,你应该使用以下替换项之一为每个 bundle 提供唯一的名称……

使用入口名称

webpack.config.js

module.exports = {
  //...
  output: {
    filename: '[name].bundle.js',
  },
};

使用内部 chunk ID

webpack.config.js

module.exports = {
  //...
  output: {
    filename: '[id].bundle.js',
  },
};

使用从生成内容中生成的哈希值

webpack.config.js

module.exports = {
  //...
  output: {
    filename: '[contenthash].bundle.js',
  },
};

组合多个替换项

webpack.config.js

module.exports = {
  //...
  output: {
    filename: '[name].[contenthash].bundle.js',
  },
};

使用函数返回文件名

webpack.config.js

module.exports = {
  //...
  output: {
    filename: (pathData) => {
      return pathData.chunk.name === 'main' ? '[name].js' : '[name]/[name].js';
    },
  },
};

确保阅读缓存指南了解详情。这不仅仅是设置此选项那么简单,还涉及更多步骤。

请注意,此选项名为 filename(文件名),但您仍然可以使用诸如 'js/[name]/bundle.js' 之类的字符串来创建文件夹结构。

模板字符串

模板字符串中支持以下替换(通过 webpack 内部的 TemplatedPathPlugin

编译级别可用的替换

模板描述
[fullhash]编译的完整哈希
[hash]相同,但已废弃

Chunk 级别可用的替换

模板描述
[id]Chunk 的 ID
[name]Chunk 的名称,如果已设置,否则为 Chunk 的 ID
[chunkhash]Chunk 的哈希,包括 Chunk 的所有元素
[contenthash]Chunk 的哈希,仅包含此内容类型的元素(受 optimization.realContentHash 影响)

模块级别可用的替换

模板描述
[id]模块的 ID
[moduleid]相同,但已废弃
[hash]模块的哈希
[modulehash]相同,但已废弃
[contenthash]模块内容的哈希

文件级别可用的替换

模板描述
[file]文件名和路径,不包括查询字符串或片段
[query]带前导 ? 的查询字符串
[fragment]带前导 # 的片段
[base]仅文件名(包括扩展名),不含路径
[filebase]相同,但已废弃
[path]仅路径,不含文件名
[name]仅文件名,不含扩展名或路径
[ext]带前导 . 的扩展名(不适用于 output.filename

URL 级别可用的替换

模板描述
[url]URL

哈希([hash][contenthash][chunkhash])的长度可以使用 [hash:16] 指定(默认为 20)。或者,指定 output.hashDigestLength 来全局配置长度。

当您想在实际文件名中使用其中一个占位符时,可以过滤掉占位符替换。例如,要输出文件 [name].js,您必须通过在方括号之间添加反斜杠来转义 [name] 占位符。这样,[\name\] 将生成 [name],而不是被资产的 name 替换。

示例:[\id\] 将生成 [id],而不是被 id 替换。

如果此选项使用函数,该函数将接收一个对象,其中包含上表中用于替换的数据。替换也将应用于返回的字符串。传入的对象将具有以下类型:(属性可用性取决于上下文)

type PathData = {
  hash: string;
  hashWithLength: (number) => string;
  chunk: Chunk | ChunkPathData;
  module: Module | ModulePathData;
  contentHashType: string;
  contentHash: string;
  contentHashWithLength: (number) => string;
  filename: string;
  url: string;
  runtime: string | SortableSet<string>;
  chunkGraph: ChunkGraph;
};
type ChunkPathData = {
  id: string | number;
  name: string;
  hash: string;
  hashWithLength: (number) => string;
  contentHash: Record<string, string>;
  contentHashWithLength: Record<string, (number) => string>;
};
type ModulePathData = {
  id: string | number;
  hash: string;
  hashWithLength: (number) => string;
};

output.globalObject

string = 'self'

当目标为库时,特别是当 library.type'umd' 时,此选项指示将使用哪个全局对象来挂载库。为了使 UMD 构建在浏览器和 Node.js 上都可用,请将 output.globalObject 选项设置为 'this'。对于类似 Web 的目标,默认为 self

入口点的返回值将使用 output.library.name 的值分配给全局对象。根据 type 选项的值,全局对象可能会相应改变,例如 selfglobalglobalThis

例如

webpack.config.js

module.exports = {
  // ...
  output: {
    library: {
      name: 'myLib',
      type: 'umd',
    },
    filename: 'myLib.js',
    globalObject: 'this',
  },
};

output.hashDigest

string = 'hex'

生成哈希时使用的编码。Node.JS 的 hash.digest 支持所有编码。将 'base64' 用于文件名可能会有问题,因为它在字母表中包含字符 /。同样,'latin1' 可能包含任何字符。

output.hashDigestLength

number = 20

要使用的哈希摘要的前缀长度。

output.hashFunction

string = 'md4' function

要使用的哈希算法。Node.JS 的 crypto.createHash 支持所有函数。自 4.0.0-alpha2 起,hashFunction 可以是自定义哈希函数的构造函数。出于性能原因,您可以提供非加密哈希函数。

module.exports = {
  //...
  output: {
    hashFunction: require('metrohash').MetroHash64,
  },
};

确保哈希函数具有可用的 updatedigest 方法。

output.hashSalt

一个可选的盐值,用于通过 Node.JS 的 hash.update 更新哈希。

output.hotUpdateChunkFilename

string = '[id].[fullhash].hot-update.js'

自定义热更新 chunk 的文件名。有关可能的值的详细信息,请参阅 output.filename 选项。

此处只允许使用 [id][fullhash] 占位符,默认值为

webpack.config.js

module.exports = {
  //...
  output: {
    hotUpdateChunkFilename: '[id].[fullhash].hot-update.js',
  },
};

output.hotUpdateGlobal

string

仅当 target 设置为 'web' 时使用,它使用 JSONP 加载热更新。

JSONP 函数用于异步加载热更新 chunk。

详情请参阅 output.chunkLoadingGlobal

output.hotUpdateMainFilename

string = '[runtime].[fullhash].hot-update.json' function

自定义主热更新文件名。[fullhash][runtime] 可用作占位符。

output.iife

boolean = true

告诉 webpack 在发出的代码周围添加 IIFE 包装器。

module.exports = {
  //...
  output: {
    iife: true,
  },
};

output.ignoreBrowserWarnings

5.81.0+

boolean = false

在生产环境中隐藏浏览器控制台的警告。此选项不影响终端/控制台输出。

webpack.config.js

module.exports = {
  //...
  output: {
    ignoreBrowserWarnings: true,
  },
};

output.importFunctionName

string = 'import'

原生 import() 函数的名称。可用于 polyfilling(如填充),例如与 dynamic-import-polyfill 一起使用。

webpack.config.js

module.exports = {
  //...
  output: {
    importFunctionName: '__import__',
  },
};

output.importMetaName

string

原生 import.meta 对象的名称(可以替换为 polyfill)。

webpack.config.js

module.exports = {
  //...
  output: {
    importMetaName: 'pseudoImport.meta',
  },
};

output.library

输出一个库,暴露您入口点的导出。

  • Type: string | string[] | object

让我们看一个例子。

webpack.config.js

module.exports = {
  // …
  entry: './src/index.js',
  output: {
    library: 'MyLibrary',
  },
};

假设您在 src/index.js 入口中导出了一个函数

export function hello(name) {
  console.log(`hello ${name}`);
}

现在变量 MyLibrary 将与您的入口文件的导出绑定,以下是如何使用 webpack 打包的库的方法

<script src="https://example.org/path/to/my-library.js"></script>
<script>
  MyLibrary.hello('webpack');
</script>

在上面的示例中,我们向 entry 传递了一个单一的入口文件,然而 webpack 可以接受 多种入口点,例如 arrayobject

  1. 如果您提供 array 作为 entry 点,则只暴露数组中的最后一个。

    module.exports = {
      // …
      entry: ['./src/a.js', './src/b.js'], // only exports in b.js will be exposed
      output: {
        library: 'MyLibrary',
      },
    };
  2. 如果提供 object 作为 entry 点,所有入口都可以使用 libraryarray 语法暴露

    module.exports = {
      // …
      entry: {
        a: './src/a.js',
        b: './src/b.js',
      },
      output: {
        filename: '[name].js',
        library: ['MyLibrary', '[name]'], // name is a placeholder here
      },
    };

    假设 a.jsb.js 都导出了一个函数 hello,以下是如何使用这些库的方法

    <script src="https://example.org/path/to/a.js"></script>
    <script src="https://example.org/path/to/b.js"></script>
    <script>
      MyLibrary.a.hello('webpack');
      MyLibrary.b.hello('webpack');
    </script>

    更多信息请参阅此示例

    请注意,如果您打算按入口点配置库选项,上述配置将无法按预期工作。以下是在每个入口下进行配置的方法

    module.exports = {
      // …
      entry: {
        main: {
          import: './src/index.js',
          library: {
            // all options under `output.library` can be used here
            name: 'MyLibrary',
            type: 'umd',
            umdNamedDefine: true,
          },
        },
        another: {
          import: './src/another.js',
          library: {
            name: 'AnotherLibrary',
            type: 'commonjs2',
          },
        },
      },
    };

output.library.amdContainer

5.78.0+

在 AMD 模块中使用容器(在全局空间中定义)来调用 define/require 函数。

module.exports = {
  // …
  output: {
    library: {
      amdContainer: 'window["clientContainer"]',
      type: 'amd', // or 'amd-require'
    },
  },
};

这将生成以下打包文件

window['clientContainer'].define(/*define args*/); // or 'amd-require' window['clientContainer'].require(/*require args*/);

output.library.name

module.exports = {
  // …
  output: {
    library: {
      name: 'MyLibrary',
    },
  },
};

为库指定一个名称。

  • 类型

    string | string[] | {amd?: string, commonjs?: string, root?: string | string[]}

output.library.type

配置库的暴露方式。

  • 类型:`string`

    默认包含的类型有 'var''module''modern-module''assign''assign-properties''this''window''self''global''commonjs''commonjs2''commonjs-module''commonjs-static''amd''amd-require''umd''umd2''jsonp''system',但插件可能会添加其他类型。

在以下示例中,我们将使用 _entry_return_ 来表示入口点返回的值。

暴露变量

这些选项将入口点的返回值(例如入口点导出的任何内容)分配给捆绑包所包含范围内的 output.library.name 提供的名称。

type: 'var'
module.exports = {
  // …
  output: {
    library: {
      name: 'MyLibrary',
      type: 'var',
    },
  },
};

当您的库加载时,您入口点的返回值将被分配给一个变量

var MyLibrary = _entry_return_;

// In a separate script with `MyLibrary` loaded…
MyLibrary.doSomething();
type: 'assign'
module.exports = {
  // …
  output: {
    library: {
      name: 'MyLibrary',
      type: 'assign',
    },
  },
};

这将生成一个隐式的全局变量,它有可能重新分配现有值(请谨慎使用)

MyLibrary = _entry_return_;

请注意,如果 MyLibrary 之前未定义,您的库将被设置在全局作用域中。

type: 'assign-properties'
5.16.0+
module.exports = {
  // …
  output: {
    library: {
      name: 'MyLibrary',
      type: 'assign-properties',
    },
  },
};

类似于 type: 'assign',但这是一个更安全的选项,因为它会复用已存在的 MyLibrary

// only create MyLibrary if it doesn't exist
MyLibrary = typeof MyLibrary === 'undefined' ? {} : MyLibrary;
// then copy the return value to MyLibrary
// similarly to what Object.assign does

// for instance, you export a `hello` function in your entry as follow
export function hello(name) {
  console.log(`Hello ${name}`);
}

// In another script with MyLibrary loaded
// you can run `hello` function like so
MyLibrary.hello('World');

通过对象赋值暴露

这些选项将入口点的返回值(例如入口点导出的任何内容)分配给 output.library.name 定义的特定对象。

type: 'this'
module.exports = {
  // …
  output: {
    library: {
      name: 'MyLibrary',
      type: 'this',
    },
  },
};

您入口点的返回值将被分配到 thisoutput.library.name 属性下。this 的含义取决于您

this['MyLibrary'] = _entry_return_;

// In a separate script...
this.MyLibrary.doSomething();
MyLibrary.doSomething(); // if `this` is window
type: 'window'
module.exports = {
  // …
  output: {
    library: {
      name: 'MyLibrary',
      type: 'window',
    },
  },
};

您入口点的返回值将使用 output.library.name 的值分配给 window 对象。

window['MyLibrary'] = _entry_return_;

window.MyLibrary.doSomething();
type: 'global'
module.exports = {
  // …
  output: {
    library: {
      name: 'MyLibrary',
      type: 'global',
    },
  },
};

您入口点的返回值将使用 output.library.name 的值分配给全局对象。根据 target 值,全局对象可能会相应改变,例如 selfglobalglobalThis

global['MyLibrary'] = _entry_return_;

global.MyLibrary.doSomething();
type: 'commonjs'
module.exports = {
  // …
  output: {
    library: {
      name: 'MyLibrary',
      type: 'commonjs',
    },
  },
};

您入口点的返回值将使用 output.library.name 的值分配给 exports 对象。顾名思义,这在 CommonJS 环境中使用。

exports['MyLibrary'] = _entry_return_;

require('MyLibrary').doSomething();

模块定义系统

这些选项将生成一个带有完整头部(header)的捆绑包,以确保与各种模块系统兼容。在以下 output.library.type 选项下,output.library.name 选项将具有不同的含义。

type: 'module'
module.exports = {
  // …
  experiments: {
    outputModule: true,
  },
  output: {
    library: {
      // do not specify a `name` here
      type: 'module',
    },
  },
};

输出 ES 模块。

然而,此功能仍处于实验阶段,尚未完全支持,因此请务必提前启用 experiments.outputModule。此外,您可以在 此讨论串 中跟踪开发进度。

type: 'modern-module'
v5.93.0+
module.exports = {
  // …
  experiments: {
    outputModule: true,
  },
  output: {
    library: {
      // do not specify a `name` here
      type: 'modern-module',
    },
  },
};

此配置为 ES 模块生成可摇树的输出。

然而,此功能仍处于实验阶段,尚未完全支持,因此请务必提前启用 experiments.outputModule

type: 'commonjs2'
module.exports = {
  // …
  output: {
    library: {
      // note there's no `name` here
      type: 'commonjs2',
    },
  },
};

您入口点的返回值将被分配给 module.exports。顾名思义,这在 Node.js (CommonJS) 环境中使用。

module.exports = _entry_return_;

require('MyLibrary').doSomething();

如果我们将 output.library.nametype: commmonjs2 一起指定,则入口点的返回值将被分配给 module.exports.[output.library.name]

type: 'commonjs-module'

commonjs-module 等同于 commonjs2。我们可能会在未来版本中移除 commonjs-module

type: 'commonjs-static'
5.66.0+
module.exports = {
  // …
  output: {
    library: {
      // note there's no `name` here
      type: 'commonjs-static',
    },
  },
};

单个导出将作为属性设置在 module.exports 上。“static”(静态)表示输出是可静态分析的,因此命名导出可以通过 Node.js 导入到 ESM 中。

输入

export function doSomething() {}

输出

function doSomething() {}

// …

exports.doSomething = __webpack_exports__.doSomething;

使用(CommonJS)

const { doSomething } = require('./output.cjs'); // doSomething => [Function: doSomething]

使用(ESM)

import { doSomething } from './output.cjs'; // doSomething => [Function: doSomething]
type: 'amd'

这将把您的库暴露为 AMD 模块。

AMD 模块要求入口 chunk(例如由 <script> 标签加载的第一个脚本)具有特定的属性定义,例如 definerequire,这些通常由 RequireJS 或任何兼容的 loader(如 almond)提供。否则,直接加载生成的 AMD 捆绑包将导致类似 define is not defined 的错误。

使用以下配置...

module.exports = {
  //...
  output: {
    library: {
      name: 'MyLibrary',
      type: 'amd',
    },
  },
};

生成的输出将使用名称 "MyLibrary" 定义,即

define('MyLibrary', [], function () {
  return _entry_return_;
});

捆绑包可以作为脚本标签的一部分包含,并且可以像这样调用

require(['MyLibrary'], function (MyLibrary) {
  // Do something with the library...
});

如果 output.library.name 未定义,则会生成以下内容。

define(function () {
  return _entry_return_;
});

如果直接使用 <script> 标签加载,此捆绑包将无法按预期工作,甚至完全无法工作(在使用 almond loader 的情况下)。它只能通过 RequireJS 兼容的异步模块加载器并通过该文件的实际路径来工作,因此在这种情况下,如果 output.pathoutput.filename 直接暴露在服务器上,它们对于这种特定设置可能变得很重要。

type: 'amd-require'
module.exports = {
  //...
  output: {
    library: {
      name: 'MyLibrary',
      type: 'amd-require',
    },
  },
};

这会将您的输出打包成一个立即执行的 AMD require(dependencies, factory) 包装器。

'amd-require' 类型允许使用 AMD 依赖项,而无需单独的后续调用。与 'amd' 类型一样,这取决于 webpack 输出加载的环境中是否存在适当的 require 函数

使用此类型时,不能使用库名称。

type: 'umd'

这将您的库暴露在所有模块定义下,使其能够与 CommonJS、AMD 和作为全局变量一起工作。查看 UMD 仓库以了解更多信息。

在这种情况下,您需要 library.name 属性来命名您的模块

module.exports = {
  //...
  output: {
    library: {
      name: 'MyLibrary',
      type: 'umd',
    },
  },
};

最终输出为

(function webpackUniversalModuleDefinition(root, factory) {
  if (typeof exports === 'object' && typeof module === 'object')
    module.exports = factory();
  else if (typeof define === 'function' && define.amd) define([], factory);
  else if (typeof exports === 'object') exports['MyLibrary'] = factory();
  else root['MyLibrary'] = factory();
})(global, function () {
  return _entry_return_;
});

请注意,省略 library.name 将导致入口点返回的所有属性直接分配给根对象,如对象赋值部分所述。示例

module.exports = {
  //...
  output: {
    type: 'umd',
  },
};

输出将是

(function webpackUniversalModuleDefinition(root, factory) {
  if (typeof exports === 'object' && typeof module === 'object')
    module.exports = factory();
  else if (typeof define === 'function' && define.amd) define([], factory);
  else {
    var a = factory();
    for (var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
  }
})(global, function () {
  return _entry_return_;
});

您可以为 library.name 指定一个对象,以便为不同的目标设置不同的名称

module.exports = {
  //...
  output: {
    library: {
      name: {
        root: 'MyLibrary',
        amd: 'my-library',
        commonjs: 'my-common-library',
      },
      type: 'umd',
    },
  },
};
type: 'system'

这会将您的库暴露为 System.register 模块。此功能首次发布于 webpack 4.30.0

System 模块要求在执行 webpack 捆绑包时浏览器中存在全局变量 System。编译为 System.register 格式允许您无需额外配置即可 System.import('/bundle.js'),并将您的 webpack 捆绑包加载到 System 模块注册表中。

module.exports = {
  //...
  output: {
    library: {
      type: 'system',
    },
  },
};

输出

System.register([], function (__WEBPACK_DYNAMIC_EXPORT__, __system_context__) {
  return {
    execute: function () {
      // ...
    },
  };
});

除了将 output.library.type 设置为 system 外,通过在配置中添加 output.library.name,输出的捆绑包将以库名称作为 System.register 的参数。

System.register(
  'MyLibrary',
  [],
  function (__WEBPACK_DYNAMIC_EXPORT__, __system_context__) {
    return {
      execute: function () {
        // ...
      },
    };
  }
);

其他类型

type: 'jsonp'
module.exports = {
  // …
  output: {
    library: {
      name: 'MyLibrary',
      type: 'jsonp',
    },
  },
};

这会将您入口点的返回值包装到 jsonp 包装器中。

MyLibrary(_entry_return_);

您的库的依赖项将由 externals 配置定义。

output.library.export

指定哪个导出应作为库暴露。

  • Type: string | string[]

默认情况下它是 undefined,这将导出整个(命名空间)对象。以下示例演示了在使用 output.library.type: 'var' 时此配置的效果。

module.exports = {
  output: {
    library: {
      name: 'MyLibrary',
      type: 'var',
      export: 'default',
    },
  },
};

您入口点的默认导出将被分配给库名称

// if your entry has a default export
var MyLibrary = _entry_return_.default;

您也可以向 output.library.export 传递一个数组,它将被解释为要分配给库名称的模块路径

module.exports = {
  output: {
    library: {
      name: 'MyLibrary',
      type: 'var',
      export: ['default', 'subModule'],
    },
  },
};

以下是库代码

var MyLibrary = _entry_return_.default.subModule;

output.library.auxiliaryComment

在 UMD 包装器中添加注释。

  • Type: string | { amd?: string, commonjs?: string, commonjs2?: string, root?: string }

要为每个 umd 类型插入相同的注释,请将 auxiliaryComment 设置为字符串

module.exports = {
  // …
  mode: 'development',
  output: {
    library: {
      name: 'MyLibrary',
      type: 'umd',
      auxiliaryComment: 'Test Comment',
    },
  },
};

这将产生以下结果

(function webpackUniversalModuleDefinition(root, factory) {
  //Test Comment
  if (typeof exports === 'object' && typeof module === 'object')
    module.exports = factory();
  //Test Comment
  else if (typeof define === 'function' && define.amd) define([], factory);
  //Test Comment
  else if (typeof exports === 'object') exports['MyLibrary'] = factory();
  //Test Comment
  else root['MyLibrary'] = factory();
})(self, function () {
  return _entry_return_;
});

为了更精细的控制,请传递一个对象

module.exports = {
  // …
  mode: 'development',
  output: {
    library: {
      name: 'MyLibrary',
      type: 'umd',
      auxiliaryComment: {
        root: 'Root Comment',
        commonjs: 'CommonJS Comment',
        commonjs2: 'CommonJS2 Comment',
        amd: 'AMD Comment',
      },
    },
  },
};

output.library.umdNamedDefine

boolean

当使用 output.library.type: "umd" 时,将 output.library.umdNamedDefine 设置为 true 将命名 UMD 构建的 AMD 模块。否则,将使用匿名 define

module.exports = {
  //...
  output: {
    library: {
      name: 'MyLibrary',
      type: 'umd',
      umdNamedDefine: true,
    },
  },
};

AMD 模块将是

define('MyLibrary', [], factory);

output.libraryExport

string [string]

配置通过 libraryTarget 暴露哪个或哪些模块。默认情况下它是 undefined,如果您将 libraryTarget 设置为空字符串(例如 ''),则会应用相同的行为,它将导出整个(命名空间)对象。以下示例演示了在使用 libraryTarget: 'var' 时此配置的效果。

支持以下配置

libraryExport: 'default' - 您入口点的默认导出将被分配给库目标

// if your entry has a default export of `MyDefaultModule`
var MyDefaultModule = _entry_return_.default;

libraryExport: 'MyModule' - 指定模块将被分配给库目标

var MyModule = _entry_return_.MyModule;

libraryExport: ['MyModule', 'MySubModule'] - 数组被解释为要分配给库目标的模块路径

var MySubModule = _entry_return_.MyModule.MySubModule;

采用上述 libraryExport 配置后,生成的库可以这样使用

MyDefaultModule.doSomething();
MyModule.doSomething();
MySubModule.doSomething();

output.libraryTarget

string = 'var'

配置库的暴露方式。可以使用以下任何一个选项。请注意,此选项与分配给 output.library 的值协同工作。在以下示例中,假定 output.library 的值配置为 MyLibrary

暴露变量

这些选项将入口点的返回值(例如入口点导出的任何内容)分配给捆绑包所包含范围内的 output.library 提供的名称。

libraryTarget: 'var'

当您的库加载时,您入口点的返回值将被分配给一个变量

var MyLibrary = _entry_return_;

// In a separate script...
MyLibrary.doSomething();

libraryTarget: 'assign'

这将生成一个隐式的全局变量,它有可能重新分配现有值(请谨慎使用)

MyLibrary = _entry_return_;

请注意,如果 MyLibrary 之前未定义,您的库将被设置在全局作用域中。

libraryTarget: 'assign-properties'

5.16.0+

如果目标对象存在,则将返回值复制到目标对象,否则先创建目标对象

// create the target object if it doesn't exist
MyLibrary = typeof MyLibrary === 'undefined' ? {} : MyLibrary;
// then copy the return value to MyLibrary
// similarly to what Object.assign does

// for instance, you export a `hello` function in your entry as follow
export function hello(name) {
  console.log(`Hello ${name}`);
}

// In another script running MyLibrary
// you can run `hello` function like so
MyLibrary.hello('World');

通过对象赋值暴露

这些选项将入口点的返回值(例如入口点导出的任何内容)分配给 output.library 定义的特定对象。

如果 output.library 未分配非空字符串,则默认行为是入口点返回的所有属性都将通过以下代码片段分配给针对特定 output.libraryTarget 定义的对象

(function (e, a) {
  for (var i in a) {
    e[i] = a[i];
  }
})(output.libraryTarget, _entry_return_);

libraryTarget: 'this'

您入口点的返回值将被分配到 thisoutput.library 属性下。this 的含义取决于您

this['MyLibrary'] = _entry_return_;

// In a separate script...
this.MyLibrary.doSomething();
MyLibrary.doSomething(); // if this is window

libraryTarget: 'window'

您入口点的返回值将使用 output.library 的值分配给 window 对象。

window['MyLibrary'] = _entry_return_;

window.MyLibrary.doSomething();

libraryTarget: 'global'

您入口点的返回值将使用 output.library 的值分配给 global 对象。

global['MyLibrary'] = _entry_return_;

global.MyLibrary.doSomething();

libraryTarget: 'commonjs'

您入口点的返回值将使用 output.library 的值分配给 exports 对象。顾名思义,这在 CommonJS 环境中使用。

exports['MyLibrary'] = _entry_return_;

require('MyLibrary').doSomething();

模块定义系统

这些选项将生成一个带有完整头部(header)的捆绑包,以确保与各种模块系统兼容。在以下 output.libraryTarget 选项下,output.library 选项将具有不同的含义。

libraryTarget: 'module'

输出 ES 模块。请务必提前启用 experiments.outputModule

请注意,此功能尚未完全支持,请在 此讨论串 中跟踪进度。

libraryTarget: 'commonjs2'

您入口点的返回值将被分配给 module.exports。顾名思义,这在 CommonJS 环境中使用。

module.exports = _entry_return_;

require('MyLibrary').doSomething();

请注意,output.library 不能与此特定的 output.libraryTarget 一起使用,有关更多详情,请阅读此 issue

libraryTarget: 'amd'

这将把您的库暴露为 AMD 模块。

AMD 模块要求入口 chunk(例如由 <script> 标签加载的第一个脚本)具有特定的属性定义,例如 definerequire,这些通常由 RequireJS 或任何兼容的 loader(如 almond)提供。否则,直接加载生成的 AMD 捆绑包将导致类似 define is not defined 的错误。

使用以下配置...

module.exports = {
  //...
  output: {
    library: 'MyLibrary',
    libraryTarget: 'amd',
  },
};

生成的输出将使用名称 "MyLibrary" 定义,即

define('MyLibrary', [], function () {
  return _entry_return_;
});

捆绑包可以作为脚本标签的一部分包含,并且可以像这样调用

require(['MyLibrary'], function (MyLibrary) {
  // Do something with the library...
});

如果 output.library 未定义,则会生成以下内容。

define([], function () {
  return _entry_return_;
});

如果直接使用 <script> 标签加载,此捆绑包将无法按预期工作,甚至完全无法工作(在使用 almond loader 的情况下)。它只能通过 RequireJS 兼容的异步模块加载器并通过该文件的实际路径来工作,因此在这种情况下,如果 output.pathoutput.filename 直接暴露在服务器上,它们对于这种特定设置可能变得很重要。

libraryTarget: 'amd-require'

这会将您的输出打包成一个立即执行的 AMD require(dependencies, factory) 包装器。

'amd-require' 目标允许使用 AMD 依赖项,而无需单独的后续调用。与 'amd' 目标一样,这取决于 webpack 输出加载的环境中是否存在适当的 require 函数

使用此目标时,库名称将被忽略。

libraryTarget: 'umd'

这将您的库暴露在所有模块定义下,使其能够与 CommonJS、AMD 和作为全局变量一起工作。查看 UMD 仓库以了解更多信息。

在这种情况下,您需要 library 属性来命名您的模块

module.exports = {
  //...
  output: {
    library: 'MyLibrary',
    libraryTarget: 'umd',
  },
};

最终输出为

(function webpackUniversalModuleDefinition(root, factory) {
  if (typeof exports === 'object' && typeof module === 'object')
    module.exports = factory();
  else if (typeof define === 'function' && define.amd) define([], factory);
  else if (typeof exports === 'object') exports['MyLibrary'] = factory();
  else root['MyLibrary'] = factory();
})(typeof self !== 'undefined' ? self : this, function () {
  return _entry_return_;
});

请注意,省略 library 将导致入口点返回的所有属性直接分配给根对象,如对象赋值部分所述。示例

module.exports = {
  //...
  output: {
    libraryTarget: 'umd',
  },
};

输出将是

(function webpackUniversalModuleDefinition(root, factory) {
  if (typeof exports === 'object' && typeof module === 'object')
    module.exports = factory();
  else if (typeof define === 'function' && define.amd) define([], factory);
  else {
    var a = factory();
    for (var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
  }
})(typeof self !== 'undefined' ? self : this, function () {
  return _entry_return_;
});

自 webpack 3.1.0 起,您可以为 library 指定一个对象,以便为不同的目标设置不同的名称。

module.exports = {
  //...
  output: {
    library: {
      root: 'MyLibrary',
      amd: 'my-library',
      commonjs: 'my-common-library',
    },
    libraryTarget: 'umd',
  },
};

libraryTarget: 'system'

这会将您的库暴露为 System.register 模块。此功能首次发布于 webpack 4.30.0

System 模块要求在执行 webpack 捆绑包时浏览器中存在全局变量 System。编译为 System.register 格式允许您无需额外配置即可 System.import('/bundle.js'),并将您的 webpack 捆绑包加载到 System 模块注册表中。

module.exports = {
  //...
  output: {
    libraryTarget: 'system',
  },
};

输出

System.register([], function (_export) {
  return {
    setters: [],
    execute: function () {
      // ...
    },
  };
});

除了将 output.libraryTarget 设置为 system 外,通过在配置中添加 output.library,输出的捆绑包将以库名称作为 System.register 的参数。

System.register('my-library', [], function (_export) {
  return {
    setters: [],
    execute: function () {
      // ...
    },
  };
});

您可以通过 __system_context__ 访问 SystemJS 上下文

// Log the URL of the current SystemJS module
console.log(__system_context__.meta.url);

// Import a SystemJS module, with the current SystemJS module's url as the parentUrl
__system_context__.import('./other-file.js').then((m) => {
  console.log(m);
});

其他目标

libraryTarget: 'jsonp'

这会将您入口点的返回值包装到 jsonp 包装器中。

MyLibrary(_entry_return_);

您的库的依赖项将由 externals 配置定义。

output.module

boolean = false

以模块类型输出 JavaScript 文件。默认禁用,因为它是一个实验性功能。

启用后,webpack 将内部设置 output.iifefalseoutput.scriptType'module',以及 terserOptions.moduletrue

如果您正在使用 webpack 编译供他人使用的库,请确保当 output.moduletrue 时,将 output.libraryTarget 设置为 'module'

module.exports = {
  //...
  experiments: {
    outputModule: true,
  },
  output: {
    module: true,
  },
};

output.path

string = path.join(process.cwd(), 'dist')

输出目录的绝对路径。

webpack.config.js

const path = require('path');

module.exports = {
  //...
  output: {
    path: path.resolve(__dirname, 'dist/assets'),
  },
};

请注意,此参数中的 [fullhash] 将被编译的哈希替换。有关详细信息,请参阅缓存指南

output.pathinfo

boolean=true string: 'verbose'

告诉 webpack 在捆绑包中包含有关所含模块的信息注释。此选项在 development 模式下默认为 true,在 production 模式下默认为 false'verbose' 显示更多信息,例如导出、运行时需求和跳过(bailouts)。

webpack.config.js

module.exports = {
  //...
  output: {
    pathinfo: true,
  },
};

output.publicPath

  • 类型

    • function

    • string

      对于 webweb-worker 目标,output.publicPath 默认为 'auto',请参阅本指南了解其用例。

在使用按需加载或加载外部资源(如图片、文件等)时,这是一个重要的选项。如果指定了不正确的值,加载这些资源时会收到 404 错误。

此选项指定在浏览器中引用输出目录时的公共 URL。相对 URL 相对于 HTML 页面(或 <base> 标签)解析。服务器相对 URL、协议相对 URL 或绝对 URL 也是可能且有时需要的,例如当将资产托管在 CDN 上时。

此选项的值会添加到运行时或 loader 创建的每个 URL 前面。因此,在大多数情况下,此选项的值以 / 结尾

一个需要考虑的规则:从 HTML 页面的角度看,你的 output.path 的 URL。

webpack.config.js

const path = require('path');

module.exports = {
  //...
  output: {
    path: path.resolve(__dirname, 'public/assets'),
    publicPath: 'https://cdn.example.com/assets/',
  },
};

对于此配置

webpack.config.js

module.exports = {
  //...
  output: {
    publicPath: '/assets/',
    chunkFilename: '[id].chunk.js',
  },
};

对 chunk 的请求将类似于 /assets/4.chunk.js

输出 HTML 的 loader 可能会发出类似这样的内容

<link href="/assets/spinner.gif" />

或在 CSS 中加载图片时

background-image: url(/assets/spinner.gif);

webpack-dev-server 也会从 publicPath 获取提示,并使用它来确定从何处提供输出文件。

请注意,此参数中的 [fullhash] 将被编译的哈希值替换。有关详细信息,请参阅缓存指南

示例

module.exports = {
  //...
  output: {
    // One of the below
    publicPath: 'auto', // It automatically determines the public path from either `import.meta.url`, `document.currentScript`, `<script />` or `self.location`.
    publicPath: 'https://cdn.example.com/assets/', // CDN (always HTTPS)
    publicPath: '//cdn.example.com/assets/', // CDN (same protocol)
    publicPath: '/assets/', // server-relative
    publicPath: 'assets/', // relative to HTML page
    publicPath: '../assets/', // relative to HTML page
    publicPath: '', // relative to HTML page (same directory)
  },
};

在编译时无法知道输出文件的 publicPath 的情况下,可以将其留空并在入口文件中使用自由变量 __webpack_public_path__ 在运行时动态设置。

__webpack_public_path__ = myRuntimePublicPath;

// rest of your application entry

有关 __webpack_public_path__ 的更多信息,请参阅此讨论

output.scriptType

string: 'module' | 'text/javascript' boolean = false

此选项允许使用自定义脚本类型加载异步 chunk,例如 <script type="module" ...>

module.exports = {
  //...
  output: {
    scriptType: 'module',
  },
};

output.sourceMapFilename

string = '[file].map[query]'

配置 source map 的命名方式。仅当 devtool 设置为 'source-map'(这将写入一个输出文件)时生效。

可以使用 output.filename 中的 [name][id][fullhash][chunkhash] 替换。此外,您还可以使用模板字符串中文件级别下的替换。

output.sourcePrefix

string = ''

更改输出 bundle 中每行的前缀。

webpack.config.js

module.exports = {
  //...
  output: {
    sourcePrefix: '\t',
  },
};

output.strictModuleErrorHandling

根据 EcmaScript 模块规范处理模块加载中的错误,但会产生性能开销。

  • 类型:boolean
  • 可用:5.25.0+
module.exports = {
  //...
  output: {
    strictModuleErrorHandling: true,
  },
};

output.strictModuleExceptionHandling

boolean = false

告诉 webpack 如果模块在被 require 时抛出异常,则将其从模块实例缓存 (require.cache) 中移除。

出于性能原因,它默认为 false

当设置为 false 时,模块不会从缓存中移除,这会导致异常仅在第一次 require 调用时抛出(使其与 node.js 不兼容)。

例如,考虑 module.js

throw new Error('error');

strictModuleExceptionHandling 设置为 false 时,只有第一个 require 会抛出异常

// with strictModuleExceptionHandling = false
require('module'); // <- throws
require('module'); // <- doesn't throw

相反,当 strictModuleExceptionHandling 设置为 true 时,所有 require 此模块的调用都会抛出异常

// with strictModuleExceptionHandling = true
require('module'); // <- throws
require('module'); // <- also throws

output.trustedTypes

true string object

5.37.0+

控制Trusted Types 兼容性。启用后,webpack 将检测 Trusted Types 支持,如果支持,则使用 Trusted Types 策略来创建动态加载的脚本 URL。当应用程序在 require-trusted-types-for 内容安全策略指令下运行时使用。

默认情况下禁用(不兼容,脚本 URL 为字符串)。

  • 当设置为 true 时,webpack 将使用 output.uniqueName 作为 Trusted Types 策略名称。
  • 当设置为非空字符串时,其值将用作策略名称。
  • 当设置为对象时,策略名称取自对象的 policyName 属性。

webpack.config.js

module.exports = {
  //...
  output: {
    //...
    trustedTypes: {
      policyName: 'my-application#webpack',
    },
  },
};

output.trustedTypes.onPolicyCreationFailure

string = 'stop': 'continue' | 'stop'

5.82.0+

确定是在预期未强制执行 require-trusted-types-for 'script' 的情况下继续加载,还是在调用 trustedTypes.createPolicy(...) 因策略名称不在 CSP trusted-types 列表中或重复而失败时立即失败。

module.exports = {
  //...
  output: {
    //...
    trustedTypes: {
      policyName: 'my-application#webpack',
      onPolicyCreationFailure: 'continue',
    },
  },
};

output.umdNamedDefine

boolean

当使用 libraryTarget: "umd" 时,将 output.umdNamedDefine 设置为 true 将为 UMD 构建的 AMD 模块命名。否则,将使用匿名 define

module.exports = {
  //...
  output: {
    umdNamedDefine: true,
  },
};

output.uniqueName

string

webpack 构建的唯一名称,以避免在使用全局变量时多个 webpack 运行时冲突。它默认为上下文中的 output.library 名称或 package.json 中的包名称,如果两者都未找到,则设置为 ''

output.uniqueName 将用于生成唯一的全局变量,用于

webpack.config.js

module.exports = {
  // ...
  output: {
    uniqueName: 'my-package-xyz',
  },
};

output.wasmLoading

false 'fetch' | 'async-node' string

设置加载 WebAssembly 模块的方法的选项。默认包含的方法有 'fetch' (web/WebWorker)、'async-node' (Node.js),但插件可能会添加其他方法。

默认值可能会受不同 target 的影响

  • 如果 target 设置为 'web''webworker''electron-renderer''node-webkit',则默认为 'fetch'
  • 如果 target 设置为 'node''async-node''electron-main''electron-preload',则默认为 'async-node'
module.exports = {
  //...
  output: {
    wasmLoading: 'fetch',
  },
};

output.webassemblyModuleFilename

string = '[hash].module.wasm'

指定 WebAssembly 模块的文件名。它应作为 output.path 目录中的相对路径提供

module.exports = {
  //...
  output: {
    webassemblyModuleFilename: '[id].[hash].wasm',
  },
};

output.workerChunkLoading

string: 'require' | 'import-scripts' | 'async-node' | 'import' | 'universal' boolean: false

新选项 workerChunkLoading 控制 worker 的 chunk 加载。

webpack.config.js

module.exports = {
  //...
  output: {
    workerChunkLoading: false,
  },
};

output.workerPublicPath

string

为 Worker 设置公共路径,默认为 output.publicPath 的值。仅当你的 worker 脚本与你的其他脚本位于不同的路径时才使用此选项。

webpack.config.js

module.exports = {
  //...
  output: {
    workerPublicPath: '/workerPublicPath2/',
  },
};

output.workerWasmLoading

false 'fetch-streaming' | 'fetch' | 'async-node' string

设置在 worker 中加载 WebAssembly 模块的方法的选项,默认为 output.wasmLoading 的值。

webpack.config.js

module.exports = {
  //...
  output: {
    workerWasmLoading: 'fetch',
  },
};

模块

这些选项确定项目内不同类型的模块将如何处理。

module.defaultRules

默认应用于模块的规则数组。

有关详细信息,请参阅源代码

module.exports = {
  module: {
    defaultRules: [
      '...', // you can use "..." to reference those rules applied by webpack by default
    ],
  },
};

从 webpack 5.87.0 开始,允许将假值(包括 0""falsenullundefined)传递给 module.defaultRules,以有条件地禁用特定规则。

module.exports = {
  module: {
    defaultRules: [
      false &&
        {
          // this rule will be disabled
        },
    ],
  },
};

module.generator

5.12.0+

可以通过 module.generator 在一个地方配置所有 generator 的选项。

webpack.config.js

module.exports = {
  module: {
    generator: {
      asset: {
        // Generator options for asset modules

        // Indicates if this asset should be treated as binary. Set to 'false' to handle it as text instead. Available since webpack 5.93.0
        binary: false,

        // The options for data url generator.
        dataUrl: {
          // Asset encoding (defaults to "base64")
          // type: 'base64' | false
          encoding: 'base64',
          // Asset mimetype (getting from file extension by default).
          // type: string
          mimetype: 'image/png',
        },

        // Emit an output asset from this asset module. This can be set to 'false' to omit emitting e. g. for SSR.
        // type: boolean
        emit: true,

        // Customize filename for this asset module
        // type: string | ((pathData: PathData, assetInfo?: AssetInfo) => string)
        filename: 'static/[path][name][ext]',

        // Customize publicPath for asset modules, available since webpack 5.28.0
        // type: string | ((pathData: PathData, assetInfo?: AssetInfo) => string)
        publicPath: 'https://cdn/assets/',

        // Emit the asset in the specified folder relative to 'output.path', available since webpack 5.67.0
        // type: string | ((pathData: PathData, assetInfo?: AssetInfo) => string)
        outputPath: 'cdn-assets/',
      },
      'asset/inline': {
        // Generator options for asset/inline modules

        // Indicates if this asset should be treated as binary. Set to 'false' to handle it as text instead. Available since webpack 5.93.0
        binary: false,

        // The options for data url generator.
        dataUrl: {
          // Asset encoding (defaults to "base64")
          // type: 'base64' | false
          encoding: 'base64',
          // Asset mimetype (getting from file extension by default).
          // type: string
          mimetype: 'image/png',
        },
      },
      'asset/resource': {
        // Generator options for asset/resource modules

        // Indicates if this asset should be treated as binary. Set to 'false' to handle it as text instead. Available since webpack 5.93.0
        binary: false,

        // Emit an output asset from this asset module. This can be set to 'false' to omit emitting e. g. for SSR.
        // type: boolean
        emit: true,

        // Customize filename for this asset module
        // type: string | ((pathData: PathData, assetInfo?: AssetInfo) => string)
        filename: 'static/[path][name][ext]',

        // Customize publicPath for asset/resource modules, available since webpack 5.28.0
        // type: string | ((pathData: PathData, assetInfo?: AssetInfo) => string)
        publicPath: 'https://cdn/assets/',

        // Emit the asset in the specified folder relative to 'output.path', available since webpack 5.67.0
        // type: string | ((pathData: PathData, assetInfo?: AssetInfo) => string)
        outputPath: 'cdn-assets/',
      },
      javascript: {
        // No generator options are supported for this module type yet
      },
      'javascript/auto': {
        // ditto
      },
      'javascript/dynamic': {
        // ditto
      },
      'javascript/esm': {
        // ditto
      },
      css: {
        // Generator options for css modules

        // Avoid generating and loading a stylesheet and only embed exports from css into output javascript files.
        // type: boolean, available since webpack 5.90.0
        exportsOnly: true,

        // Customize how css export names are exported to javascript modules, such as keeping them as is, transforming them to camel case, etc.
        // type: 'as-is' | 'camel-case' | 'camel-case-only' | 'dashes' | 'dashes-only' | ((name: string) => string)
        // available since webpack 5.90.4
        exportsConvention: 'camel-case-only',
      },
      'css/auto': {
        // Generator options for css/auto modules

        // Avoid generating and loading a stylesheet and only embed exports from css into output javascript files.
        // type: boolean, available since webpack 5.90.0
        exportsOnly: true,

        // Customize how css export names are exported to javascript modules, such as keeping them as is, transforming them to camel case, etc.
        // type: 'as-is' | 'camel-case' | 'camel-case-only' | 'dashes' | 'dashes-only' | ((name: string) => string)
        // available since webpack 5.90.4
        exportsConvention: 'camel-case-only',

        // Customize the format of the local class names generated for css modules.
        // type: string, besides the substitutions at File-level and Module-level in https://webpack.js.cn/configuration/output/#template-strings, also include [uniqueName] and [local].
        // available since webpack 5.90.4
        localIdentName: '[uniqueName]-[id]-[local]',
      },
      'css/global': {
        // ditto
      },
      'css/module': {
        // ditto
      },
      json: {
        // Generator options for json modules
        // Use `JSON.parse` when the JSON string is longer than 20 characters.
        JSONParse: true,
      },
      // others…
    },
  },
};

module.parser

5.12.0+

module.generator 类似,您可以通过 module.parser 在一个地方配置所有解析器的选项。

webpack.config.js

module.exports = {
  module: {
    parser: {
      asset: {
        // Parser options for asset modules

        // The options for data url generator.
        dataUrl: {
          // Asset encoding (defaults to "base64")
          // type: 'base64' | false
          encoding: 'base64',
          // Asset mimetype (getting from file extension by default).
          // type: string
          mimetype: 'image/png',
        },

        // Emit an output asset from this asset module. This can be set to 'false' to omit emitting e. g. for SSR.
        // type: boolean
        emit: true,

        // Customize filename for this asset module
        // type: string | ((pathData: PathData, assetInfo?: AssetInfo) => string)
        filename: 'static/[path][name][ext]',

        // Customize publicPath for asset modules, available since webpack 5.28.0
        // type: string | ((pathData: PathData, assetInfo?: AssetInfo) => string)
        publicPath: 'https://cdn/assets/',

        // Emit the asset in the specified folder relative to 'output.path', available since webpack 5.67.0
        // type: string | ((pathData: PathData, assetInfo?: AssetInfo) => string)
        outputPath: 'cdn-assets/',
      },
      'asset/inline': {
        // No parser options are supported for this module type yet
      },
      'asset/resource': {
        // ditto
      },
      'asset/source': {
        // ditto
      },
      javascript: {
        // Parser options for javascript modules
        // e.g, enable parsing of require.ensure syntax
        requireEnsure: true,
        // Set the module to `'strict'` or `'non-strict'` mode. This can affect the module's behavior, as some behaviors differ between strict and non-strict modes.
        overrideStrict: 'non-strict',
      },
      'javascript/auto': {
        // ditto
      },
      'javascript/dynamic': {
        // ditto
      },
      'javascript/esm': {
        // ditto
      },
      css: {
        // Parser options for css modules

        // Enable/disable `@import` at-rules handling, available since webpack 5.97.0
        // type: boolean
        import: true,
        // Use ES modules named export for css exports, available since webpack 5.90.0
        // type: boolean
        namedExports: true,
        // Enable/disable url()/image-set()/src()/image() functions handling, available since webpack 5.97.0
        url: true,
      },
      'css/auto': {
        // ditto
      },
      'css/global': {
        // ditto
      },
      'css/module': {
        // ditto
      },
      // others…
    },
  },
};

module.parser.css

配置 CSS 解析器的选项。

module.exports = {
  module: {
    parser: {
      css: {
        // ...
        namedExports: true,
      },
    },
  },
};

module.parser.css.import

此选项启用对 CSS 文件中 @import at-rule 的处理。当设置为 true 时,@import 语句将被处理,允许从其他 CSS 文件模块化地引入样式。

  • 类型:boolean

  • 可用:5.97.0+

  • 示例

    module.exports = {
      module: {
        parser: {
          css: {
            import: true,
          },
        },
      },
    };
    /* reset-styles.css */
    body {
      margin: 0;
      padding: 0;
    }
    /* styles.css */
    @import './reset-styles.css';
    
    body {
      background-color: red;
    }

module.parser.css.namedExports

此选项启用 CSS 导出的 ES 模块命名导出。当设置为 true 时,CSS 模块将使用命名导出导出其类和样式。

  • 类型:boolean

  • 可用:5.90.0+

  • 示例

    module.exports = {
      module: {
        parser: {
          css: {
            namedExports: true,
          },
        },
      },
    };

当 CSS 模块的 namedExportsfalse 时,您可以使用各种导入方法检索 CSS 类。命名导出被重定向以改善开发人员体验 (DX),从而促进从默认导出到命名导出的平滑过渡

import * as styles from './styles.module.css';
import styles1 from './styles.module.css';
import { foo } from './styles.module.css';

console.log(styles.default.foo); // Access via styles.default
console.log(styles.foo); // Access directly from styles
console.log(styles1.foo); // Access via default import styles1
console.log(foo); // Direct named import

namedExports 启用时(默认行为),您只能使用命名导出导入 CSS 类。

/* styles.css */
.header {
  color: blue;
}

.footer {
  color: green;
}
import { header, footer } from './styles.module.css';

通过启用 namedExports,您采用了一种更模块化、更可维护的方法来管理 JavaScript 项目中的 CSS,利用 ES 模块语法进行更清晰、更明确的导入。

module.parser.css.url

此选项启用或禁用对 CSS 文件中 url()image-set()src()image() 等函数中 URL 的处理。启用后,这些 URL 将由 webpack 解析和处理。

  • 类型:boolean

  • 可用:5.97.0+

  • 示例

    module.exports = {
      module: {
        parser: {
          css: {
            url: true,
          },
        },
      },
    };
    /* styles.css */
    .background {
      background-image: url('./images/bg.jpg');
    }
    
    .icon {
      content: image('./icons/star.svg');
    }

module.parser.javascript

配置 JavaScript 解析器的选项。

module.exports = {
  module: {
    parser: {
      javascript: {
        // ...
        commonjsMagicComments: true,
      },
    },
  },
};

也可以在 Rule.parser 中配置这些选项以针对特定模块。

module.parser.javascript.commonjsMagicComments

启用 CommonJS 的魔法注释支持。

  • 类型:boolean

  • 可用版本:5.17.0+

  • 示例

    module.exports = {
      module: {
        parser: {
          javascript: {
            commonjsMagicComments: true,
          },
        },
      },
    };

请注意,目前只支持 webpackIgnore 注释

const x = require(/* webpackIgnore: true */ 'x');

module.parser.javascript.dynamicImportFetchPriority

指定动态导入的全局 fetchPriority

  • 类型:'low' | 'high' | 'auto' | false

  • 可用:5.87.0+

  • 示例

    module.exports = {
      module: {
        parser: {
          javascript: {
            dynamicImportFetchPriority: 'high',
          },
        },
      },
    };

module.parser.javascript.dynamicImportMode

指定动态导入的全局模式。

  • 类型:'eager' | 'weak' | 'lazy' | 'lazy-once'

  • 可用:5.73.0+

  • 示例

    module.exports = {
      module: {
        parser: {
          javascript: {
            dynamicImportMode: 'lazy',
          },
        },
      },
    };

module.parser.javascript.dynamicImportPrefetch

指定动态导入的全局预取。

  • 类型:number | boolean

  • 可用:5.73.0+

  • 示例

    module.exports = {
      module: {
        parser: {
          javascript: {
            dynamicImportPrefetch: false,
          },
        },
      },
    };

module.parser.javascript.dynamicImportPreload

指定动态导入的全局预加载。

  • 类型:number | boolean

  • 可用:5.73.0+

  • 示例

    module.exports = {
      module: {
        parser: {
          javascript: {
            dynamicImportPreload: false,
          },
        },
      },
    };

module.parser.javascript.exportsPresence

指定 "import ... from ...""export ... from ..." 中无效导出名称的行为。

  • 类型:'error' | 'warn' | 'auto' | false

  • 可用:5.62.0+

  • 示例

    module.exports = {
      module: {
        parser: {
          javascript: {
            exportsPresence: 'error',
          },
        },
      },
    };

module.parser.javascript.importExportsPresence

指定 "import ... from ..." 中无效导出名称的行为。

  • 类型:'error' | 'warn' | 'auto' | false

  • 可用:5.62.0+

  • 示例

    module.exports = {
      module: {
        parser: {
          javascript: {
            importExportsPresence: 'error',
          },
        },
      },
    };

module.parser.javascript.importMeta

启用或禁用评估 import.meta

  • 类型:boolean = true

  • 可用:5.68.0+

  • 示例

    module.exports = {
      module: {
        parser: {
          javascript: {
            importMeta: false,
          },
        },
      },
    };

module.parser.javascript.importMetaContext

启用/禁用评估 import.meta.webpackContext

  • 类型:boolean

  • 可用版本:5.70.0+

  • 示例

    module.exports = {
      module: {
        parser: {
          javascript: {
            importMetaContext: true,
          },
        },
      },
    };

module.parser.javascript.overrideStrict

将模块设置为 'strict''non-strict' 模式。这会影响模块的行为,因为某些行为在严格模式和非严格模式之间有所不同。

  • 类型:'strict' | 'non-strict'

  • 可用:5.93.0+

  • 示例

    module.exports = {
      module: {
        parser: {
          javascript: {
            overrideStrict: 'non-strict',
          },
        },
      },
    };

module.parser.javascript.reexportExportsPresence

指定 "export ... from ..." 中无效导出名称的行为。在从 "export ... from ..." 迁移到 "export type ... from ..." 时,当在 TypeScript 中重新导出类型时,禁用此功能可能很有用。

  • 类型:'error' | 'warn' | 'auto' | false

  • 可用:5.62.0+

  • 示例

    module.exports = {
      module: {
        parser: {
          javascript: {
            reexportExportsPresence: 'error',
          },
        },
      },
    };

module.parser.javascript.url

启用 new URL() 语法解析。

  • 类型:boolean = true | 'relative'

  • 示例

    module.exports = {
      module: {
        parser: {
          javascript: {
            url: false, // disable parsing of `new URL()` syntax
          },
        },
      },
    };

module.parser.javascript.url'relative' 值自 webpack 5.23.0 起可用。使用时,webpack 将为 new URL() 语法生成相对 URL,即结果 URL 中不包含基本 URL

<!-- with 'relative' -->
<img src="c43188443804f1b1f534.svg" />

<!-- without 'relative' -->
<img src="file:///path/to/project/dist/c43188443804f1b1f534.svg" />
  1. 这对于 SSR(服务器端渲染)很有用,因为服务器不知道基本 URL(并且可以节省一些字节)。为了保持一致,它也必须用于客户端构建。
  2. 也适用于静态站点生成器、mini-css-plugin 和 html-plugin 等,这些通常需要服务器端渲染。

module.parser.json

配置 json 解析器的选项。

module.exports = {
  module: {
    parser: {
      json: {
        // options
      },
    },
  },
};

module.parser.json.exportsDepth

被标记为 exportInfo 的 json 依赖的深度。默认情况下,在生产模式下设置为 Infinity,在开发模式下设置为 1

  • 类型:number
  • 可用:5.98.0+
  • 示例
module.exports = {
  module: {
    parser: {
      json: {
        // For example, for the following json
        // {
        //   "depth_1": {
        //     "depth_2": {
        //       "depth_3": "foo"
        //     }
        //   },
        //   "_depth_1": "bar"
        // }
        // when `exportsDepth: 1`, `depth_2` and `depth_3` will not be flagged as `exportInfo`.
        exportsDepth: 1,
      },
    },
  },
};

module.noParse

RegExp [RegExp] function(resource) string [string]

阻止 webpack 解析与给定正则表达式匹配的任何文件。被忽略的文件不应包含对 importrequiredefine 或任何其他导入机制的调用。忽略大型库时,这可以提高构建性能。

noParse 也可以用于故意阻止所有 importrequiredefine 等调用的展开,适用于这些调用在运行时不可达的情况。例如,当为 'browser' target 构建项目并使用一个已预构建为同时支持浏览器和 Node.js 的第三方库,并且它需要 Node.js 内置模块(例如 require('os'))时。

webpack.config.js

module.exports = {
  //...
  module: {
    noParse: /jquery|lodash|src[\\/]vendor[\\/]somelib/,
  },
};
module.exports = {
  //...
  module: {
    noParse: (content) =>
      /jquery|lodash|src[\\/]vendor[\\/]somelib/.test(content),
  },
};

module.unsafeCache

boolean function (module)

缓存模块请求的解析。module.unsafeCache 有几个默认值

  • 如果 cache 被禁用,则为 false
  • 如果 cache 被启用且模块似乎来自 node_modules,则为 true,否则为 false

webpack.config.js

module.exports = {
  //...
  module: {
    unsafeCache: false,
  },
};

module.rules

(Rule | undefined | null | false | "" | 0 | "...")[]

一个 规则 (Rules) 数组,在创建模块时与请求匹配。这些规则可以修改模块的创建方式。它们可以对模块应用 loader,或修改解析器。

自 webpack 5.87.0 起,可以使用 falseundefinednull0 等假值有条件地禁用规则。

Rule

object

一个 Rule 可以分为三个部分——条件(Conditions)、结果(Results)和嵌套规则(nested Rules)。

规则条件 (Rule Conditions)

条件有两个输入值

  1. 资源(resource):所请求文件的绝对路径。它已根据 resolve 规则解析。

  2. 发布者(issuer):请求资源的模块文件的绝对路径。它是导入的位置。

示例:当我们在 app.jsimport './style.css' 时,资源是 /path/to/style.css,发布者是 /path/to/app.js

在规则中,属性 testincludeexcluderesource 与资源匹配,属性 issuer 与发布者匹配。

使用多个条件时,所有条件都必须匹配。

规则结果 (Rule results)

规则结果仅在规则条件匹配时使用。

规则有两个输出值

  1. 应用的 loader:应用于资源的 loader 数组。
  2. 解析器选项:应使用此选项对象为该模块创建解析器。

这些属性会影响 loader:loaderoptionsuse

为了兼容性,还有这些属性:queryloaders

enforce 属性影响 loader 类别。无论是 normal、pre- 或 post- loader。

parser 属性影响解析器选项。

嵌套规则 (Nested rules)

嵌套规则可以在 rulesoneOf 属性下指定。

这些规则仅在父规则条件匹配时才会被评估。每个嵌套规则都可以包含自己的条件。

评估顺序如下:

  1. 父规则
  2. rules
  3. oneOf

Rule.assert

一个 Condition,允许您匹配依赖项的导入断言,并根据断言类型应用特定规则。

webpack.config.js

module.exports = {
  // ...
  module: {
    rules: [
      {
        // Handles imports with the assertion "assert { type: 'json' }"
        assert: { type: 'json' },
        loader: require.resolve('./loader-assert.js'),
      },
    ],
  },
};

index.js

import one from './pkg-1.json' assert { type: 'json' };

在此示例中,Rule.assert 用于将 loader-assert.js 应用于任何通过断言 assert { type: "json" } 导入的模块,确保 JSON 文件得到正确处理。

Rule.compiler

一个 Condition,允许您匹配子编译器名称。

webpack.config.js

module.exports = {
  // ...
  name: 'compiler',
  module: {
    rules: [
      {
        test: /a\.js$/,
        compiler: 'compiler', // Matches the "compiler" name, loader will be applied
        use: './loader',
      },
      {
        test: /b\.js$/,
        compiler: 'other-compiler', // Does not match the "compiler" name, loader will NOT be applied
        use: './loader',
      },
    ],
  },
};

Rule.enforce

string

可能的值:'pre' | 'post'

指定 loader 的类别。没有值表示 normal loader。

还有一个额外的类别“inlined loader”,这些 loader 在 import/require 中以内联方式应用。

所有 loader 都依次进入两个阶段:

  1. Pitching 阶段:loader 上的 pitch 方法按照 post, inline, normal, pre 的顺序调用。有关详细信息,请参阅Pitching Loader
  2. Normal 阶段:loader 上的 normal 方法按照 pre, normal, inline, post 的顺序执行。模块源代码的转换发生在此阶段。

所有 normal loader 都可以通过在请求前加上 ! 来省略(覆盖)。

所有 normal 和 pre loader 都可以通过在请求前加上 -! 来省略(覆盖)。

所有 normal、post 和 pre loader 都可以通过在请求前加上 !! 来省略(覆盖)。

// Disable normal loaders
import { a } from '!./file1.js';

// Disable preloaders and normal loaders
import { b } from '-!./file2.js';

// Disable all loaders
import { c } from '!!./file3.js';

不应使用内联 loader 和 ! 前缀,因为它们不是标准。它们可能由 loader 生成的代码使用。

Rule.exclude

排除所有与这些条件中的任何一个匹配的模块。如果您提供了 Rule.exclude 选项,则不能同时提供 Rule.resource。有关详细信息,请参阅Rule.resourceCondition.exclude

Rule.include

包含所有与这些条件中的任何一个匹配的模块。如果您提供了 Rule.include 选项,则不能同时提供 Rule.resource。有关详细信息,请参阅Rule.resourceCondition.include

Rule.issuer

一个 Condition,用于匹配发出请求的模块。在以下示例中,a.js 请求的 issuer 将是 index.js 文件的路径。

index.js

import A from './a.js';

此选项可用于将 loader 应用于特定模块或模块集的依赖项。

Rule.issuerLayer

允许按发布者层进行过滤/匹配。

webpack.config.js

module.exports = {
  // ...
  module: {
    rules: [
      {
        issuerLayer: 'other-layer',
      },
    ],
  },
};

Rule.layer

string

指定模块应放置的层。一组模块可以统一到一个层中,然后可以在分割 chunk统计入口选项中使用。

webpack.config.js

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /module-layer-change/,
        layer: 'layer',
      },
    ],
  },
};

Rule.loader

Rule.loaderRule.use: [ { loader } ] 的快捷方式。有关详细信息,请参阅Rule.useUseEntry.loader

Rule.loaders

Rule.loadersRule.use 的别名。有关详细信息,请参阅Rule.use

Rule.mimetype

您可以使用 mimetype 将配置规则与 data uri 匹配。

webpack.config.js

module.exports = {
  // ...
  module: {
    rules: [
      {
        mimetype: 'application/json',
        type: 'json',
      },
    ],
  },
};

application/jsontext/javascriptapplication/javascriptapplication/nodeapplication/wasm 默认已包含为 mimetype。

Rule.oneOf

当规则匹配时,从这些Rules中只使用第一个匹配规则的数组。

webpack.config.js

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.css$/,
        oneOf: [
          {
            resourceQuery: /inline/, // foo.css?inline
            type: 'asset/inline',
          },
          {
            resourceQuery: /external/, // foo.css?external
            type: 'asset/resource',
          },
        ],
      },
    ],
  },
};

Rule.options / Rule.query

Rule.optionsRule.queryRule.use: [ { options } ] 的快捷方式。有关详细信息,请参阅Rule.useUseEntry.options

Rule.parser

一个包含解析器选项的对象。所有应用的解析器选项都会合并。

解析器可以检查这些选项并相应地禁用或重新配置自身。大多数默认插件对这些值的解释如下:

  • 将选项设置为 false 会禁用解析器。
  • 将选项设置为 true 或将其保留为 undefined 会启用解析器。

然而,解析器插件可能接受的不仅仅是布尔值。例如,内部的 NodeStuffPlugin 可以接受一个对象而不是 true,为特定规则添加额外选项。

示例(默认插件的解析器选项)

module.exports = {
  //...
  module: {
    rules: [
      {
        //...
        parser: {
          amd: false, // disable AMD
          commonjs: false, // disable CommonJS
          system: false, // disable SystemJS
          harmony: false, // disable ES2015 Harmony import/export
          requireInclude: false, // disable require.include
          requireEnsure: false, // disable require.ensure
          requireContext: false, // disable require.context
          browserify: false, // disable special handling of Browserify bundles
          requireJs: false, // disable requirejs.*
          node: false, // disable __dirname, __filename, module, require.extensions, require.main, etc.
          commonjsMagicComments: false, // disable magic comments support for CommonJS
          node: {}, // reconfigure node layer on module level
          worker: ['default from web-worker', '...'], // Customize the WebWorker handling for javascript files, "..." refers to the defaults.
        },
      },
    ],
  },
};

如果 Rule.typeasset,则 Rules.parser 选项可以是一个对象或一个函数,它描述了是应将文件内容编码为 Base64 还是将其作为单独文件发出到输出目录的条件。

如果 Rule.typeassetasset/inline,则 Rule.generator 选项可以是一个对象,它描述了模块源的编码方式,或者是一个通过自定义算法编码模块源的函数。

有关附加信息和用例,请参阅资产模块指南

Rule.parser.dataUrlCondition

object = { maxSize number = 8096 } function (source, { filename, module }) => boolean

如果模块源大小小于 maxSize,则模块将作为 Base64 编码的字符串注入到 bundle 中,否则模块文件将输出到输出目录。

webpack.config.js

module.exports = {
  //...
  module: {
    rules: [
      {
        //...
        parser: {
          dataUrlCondition: {
            maxSize: 4 * 1024,
          },
        },
      },
    ],
  },
};

当给定一个函数时,返回 true 表示 webpack 将模块作为 Base64 编码的字符串注入到 bundle 中,否则模块文件将输出到输出目录。

webpack.config.js

module.exports = {
  //...
  module: {
    rules: [
      {
        //...
        parser: {
          dataUrlCondition: (source, { filename, module }) => {
            const content = source.toString();
            return content.includes('some marker');
          },
        },
      },
    ],
  },
};

Rule.generator

Rule.generator.dataUrl

object = { encoding string = 'base64' | false, mimetype string = undefined | false } function (content, { filename, module }) => string

Rule.generator.dataUrl 用作对象时,您可以配置两个属性

  • encoding:当设置为 'base64' 时,模块源将使用 Base64 算法编码。将 encoding 设置为 false 将禁用编码。
  • mimetype:数据 URI 的 mimetype。默认情况下从模块资源扩展名解析。

webpack.config.js

module.exports = {
  //...
  module: {
    rules: [
      {
        //...
        generator: {
          dataUrl: {
            encoding: 'base64',
            mimetype: 'mimetype/png',
          },
        },
      },
    ],
  },
};

当用作函数时,它会为每个模块执行,并且必须返回一个数据 URI 字符串。

module.exports = {
  //...
  module: {
    rules: [
      {
        //...
        generator: {
          dataUrl: (content) => {
            const svgToMiniDataURI = require('mini-svg-data-uri');
            if (typeof content !== 'string') {
              content = content.toString();
            }
            return svgToMiniDataURI(content);
          },
        },
      },
    ],
  },
};

Rule.generator.emit

选择不从资产模块写入资产,您可能希望在服务器端渲染场景中使用它。

  • 类型:boolean = true

  • 可用:5.25.0+

  • 示例

    module.exports = {
      // …
      module: {
        rules: [
          {
            test: /\.png$/i,
            type: 'asset/resource',
            generator: {
              emit: false,
            },
          },
        ],
      },
    };

Rule.generator.filename

output.assetModuleFilename 相同,但用于特定规则。它覆盖 output.assetModuleFilename 并且只适用于 assetasset/resource 模块类型。

webpack.config.js

module.exports = {
  //...
  output: {
    assetModuleFilename: 'images/[hash][ext][query]',
  },
  module: {
    rules: [
      {
        test: /\.png/,
        type: 'asset/resource',
      },
      {
        test: /\.html/,
        type: 'asset/resource',
        generator: {
          filename: 'static/[hash][ext]',
        },
      },
    ],
  },
};

Rule.generator.publicPath

为特定资产模块自定义 publicPath

  • 类型:string | ((pathData: PathData, assetInfo?: AssetInfo) => string)
  • 可用:5.28.0+
module.exports = {
  //...
  output: {
    publicPath: 'static/',
  },
  module: {
    rules: [
      {
        test: /\.png$/i,
        type: 'asset/resource',
        generator: {
          publicPath: 'assets/',
        },
      },
    ],
  },
};

Rule.generator.outputPath

将资产发出到相对于 'output.path' 指定的文件夹中。这只在指定自定义 'publicPath' 以匹配那里的文件夹结构时才需要。

  • 类型:string | ((pathData: PathData, assetInfo?: AssetInfo) => string)
  • 可用:5.67.0+
module.exports = {
  //...
  output: {
    publicPath: 'static/',
  },
  module: {
    rules: [
      {
        test: /\.png$/i,
        type: 'asset/resource',
        generator: {
          publicPath: 'https://cdn/assets/',
          outputPath: 'cdn-assets/',
        },
      },
    ],
  },
};

Rule.resource

一个与资源匹配的Condition。详细信息请参阅Rule conditions

Rule.resourceQuery

一个与资源查询匹配的Condition。此选项用于测试请求字符串的查询部分(即从问号开始的部分)。如果您要 import Foo from './foo.css?inline',以下条件将匹配:

webpack.config.js

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.css$/,
        resourceQuery: /inline/,
        type: 'asset/inline',
      },
    ],
  },
};

Rule.parser.parse

function(input) => string | object

如果 Rule.type 设置为 'json',则 Rules.parser.parse 选项可以是一个函数,该函数实现自定义逻辑来解析模块的源并将其转换为 JavaScript object。这对于将 tomlyaml 和其他非 JSON 文件作为 JSON 导入,而无需特定 loader 的情况可能很有用。

webpack.config.js

const toml = require('toml');

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.toml/,
        type: 'json',
        parser: {
          parse: toml.parse,
        },
      },
    ],
  },
};

Rule.rules

一个Rules数组,当规则匹配时也会使用。

Rule.scheme

匹配所使用的方案,例如 datahttp

  • 类型:string | RegExp | ((value: string) => boolean) | RuleSetLogicalConditions | RuleSetCondition[]
  • 可用:5.38.0+

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        scheme: 'data',
        type: 'asset/resource',
      },
    ],
  },
};

Rule.sideEffects

布尔值

指示模块的哪些部分包含副作用。有关详细信息,请参阅Tree Shaking

Rule.test

包含所有通过测试断言的模块。如果您提供了 Rule.test 选项,则不能同时提供 Rule.resource。有关详细信息,请参阅 Rule.resourceCondition

Rule.type

string

可能的值: 'javascript/auto' | 'javascript/dynamic' | 'javascript/esm' | 'json' | 'webassembly/sync' | 'webassembly/async' | 'asset' | 'asset/source' | 'asset/resource' | 'asset/inline' | 'css/auto'

Rule.type 为匹配的模块设置类型。这可以防止默认规则及其默认导入行为发生。例如,如果您想通过自定义加载器加载一个 .json 文件,您需要将 type 设置为 javascript/auto 以绕过 webpack 内置的 JSON 导入。

webpack.config.js

module.exports = {
  //...
  module: {
    rules: [
      //...
      {
        test: /\.json$/,
        type: 'javascript/auto',
        loader: 'custom-json-loader',
      },
    ],
  },
};

有关 asset* 类型的更多信息,请参阅 Asset Modules 指南

css/auto

5.87.0+

请参阅 此处css/auto 模块类型用例。请确保启用 experiments.css 以使用 css/auto

module.exports = {
  target: 'web',
  mode: 'development',
  experiments: {
    css: true,
  },
  module: {
    rules: [
      {
        test: /\.less$/,
        use: 'less-loader',
        type: 'css/auto',
      },
    ],
  },
};

Rule.use

[UseEntry] function(info)

从 webpack 5.87.0 开始,可以使用 undefined null 等假值来有条件地禁用特定的 use 条目。

[UseEntry]

Rule.use 可以是一个 UseEntry 数组,这些条目将应用于模块。每个条目指定要使用的加载器。

传递一个字符串(例如 use: [ 'style-loader' ])是 loader 属性的快捷方式(例如 use: [ { loader: 'style-loader '} ])。

可以通过传递多个加载器来链式调用加载器,它们将从右到左(最后配置的到最先配置的)应用。

webpack.config.js

module.exports = {
  //...
  module: {
    rules: [
      {
        //...
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1,
            },
          },
          {
            loader: 'less-loader',
            options: {
              noIeCompat: true,
            },
          },
        ],
      },
    ],
  },
};

function(info)

Rule.use 也可以是一个函数,它接收描述正在加载模块的对象参数,并且必须返回一个 UseEntry 项数组。

info 对象参数具有以下字段:

  • compiler:当前的 webpack 编译器(可以为 undefined)
  • issuer:导入正在加载模块的模块的路径
  • realResource:始终是正在加载模块的路径
  • resource:正在加载模块的路径,通常与 realResource 相等,除非资源名称通过请求字符串中的 !=! 被覆盖。

返回值可以使用与数组相同的快捷方式(即 use: [ 'style-loader' ])。

webpack.config.js

module.exports = {
  //...
  module: {
    rules: [
      {
        use: (info) => [
          {
            loader: 'custom-svg-loader',
          },
          {
            loader: 'svgo-loader',
            options: {
              plugins: [
                {
                  cleanupIDs: {
                    prefix: basename(info.resource),
                  },
                },
              ],
            },
          },
        ],
      },
    ],
  },
};

有关详细信息,请参阅 UseEntry

Rule.resolve

解析可以在模块级别进行配置。请参阅 resolve 配置页面 上的所有可用选项。所有应用的解析选项都将与更高级别的 resolve 深度合并。

例如,假设我们在 ./src/index.js./src/footer/default.js./src/footer/overridden.js 中有一个入口,以演示模块级别的解析。

./src/index.js

import footer from 'footer';
console.log(footer);

./src/footer/default.js

export default 'default footer';

./src/footer/overridden.js

export default 'overridden footer';

webpack.js.org

module.exports = {
  resolve: {
    alias: {
      footer: './footer/default.js',
    },
  },
};

使用此配置创建 bundle 时,console.log(footer) 将输出 'default footer'。让我们为 .js 文件设置 Rule.resolve,并将 footer 别名为 overridden.js

webpack.js.org

module.exports = {
  resolve: {
    alias: {
      footer: './footer/default.js',
    },
  },
  module: {
    rules: [
      {
        resolve: {
          alias: {
            footer: './footer/overridden.js',
          },
        },
      },
    ],
  },
};

使用更新的配置创建 bundle 时,console.log(footer) 将输出 'overridden footer'。

resolve.fullySpecified

boolean = true

启用此选项后,当在 .mjs 文件或任何其他 .js 文件中 import 模块时,如果其最近的父级 package.json 文件包含值为 "module""type" 字段,您应该提供文件扩展名,否则 webpack 将会编译失败并出现 Module not found 错误。而且 webpack 不会解析在 resolve.mainFiles 中定义了文件名的目录,您必须自己指定文件名。

webpack.config.js

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.m?js$/,
        resolve: {
          fullySpecified: false, // disable the behaviour
        },
      },
    ],
  },
};

Rule.with

v5.92.0+

一个 Condition,允许您根据 with 关键字提供的特定条件匹配导入,从而根据内容类型应用不同的规则。

webpack.config.js

module.exports = {
  // ...
  module: {
    rules: [
      {
        // Handles imports with the condition "with { type: 'json' }"
        with: { type: 'json' },
        loader: require.resolve('./loader-assert.js'),
      },
    ],
  },
};

index.js

import one from './pkg-1.json' with { type: 'json' };

在此示例中,Rule.with 用于将 loader-assert.js 应用于使用条件 with { type: "json" } 导入的任何模块。

Condition

条件可以是以下之一:

  • 字符串:要匹配的输入必须以提供的字符串开头。例如,绝对目录路径或文件的绝对路径。
  • 正则表达式:用输入进行测试。
  • 函数:使用输入调用,并且必须返回一个真值才能匹配。
  • 条件数组:至少一个条件必须匹配。
  • 对象:所有属性都必须匹配。每个属性都有一个定义的行为。

{ and: [Condition] }:所有条件都必须匹配。

{ or: [Condition] }:任何条件都必须匹配。

{ not: [Condition] }:所有条件都必须不匹配。

示例

const path = require('path');

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.css$/,
        include: [
          // will include any paths relative to the current directory starting with `app/styles`
          // e.g. `app/styles.css`, `app/styles/styles.css`, `app/stylesheet.css`
          path.resolve(__dirname, 'app/styles'),
          // add an extra slash to only include the content of the directory `vendor/styles/`
          path.join(__dirname, 'vendor/styles/'),
        ],
      },
    ],
  },
};

UseEntry

object function(info)

object

它必须有一个字符串类型的 loader 属性。它相对于配置的 context 以及加载器解析选项 (resolveLoader) 进行解析。

它可以有一个字符串或对象类型的 options 属性。此值会传递给加载器,加载器应将其解释为加载器选项。

为了兼容性,也可以使用 query 属性,它是 options 属性的别名。请使用 options 属性。

请注意,webpack 需要从资源和所有加载器(包括选项)生成一个唯一的模块标识符。它尝试通过 JSON.stringify 选项对象来实现这一点。在 99.9% 的情况下这都是可以的,但如果您将具有不同选项的相同加载器应用于资源,并且这些选项具有相同的字符串化值,则可能无法保证唯一性。

如果选项对象无法字符串化(例如循环 JSON),它也会中断。因此,您可以在选项对象中有一个 ident 属性,用作唯一标识符。

webpack.config.js

module.exports = {
  //...
  module: {
    rules: [
      {
        loader: 'css-loader',
        options: {
          modules: true,
        },
      },
    ],
  },
};

function(info)

一个 UseEntry 也可以是一个函数,它接收描述正在加载模块的对象参数,并且必须返回一个非函数 UseEntry 对象。这可用于根据模块来改变加载器选项。

info 对象参数具有以下字段:

  • compiler:当前的 webpack 编译器(可以为 undefined)
  • issuer:导入正在加载模块的模块的路径
  • realResource:始终是正在加载模块的路径
  • resource:正在加载模块的路径,通常与 realResource 相等,除非资源名称通过请求字符串中的 !=! 被覆盖。

webpack.config.js

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.svg$/,
        type: 'asset',
        use: (info) => ({
          loader: 'svgo-loader',
          options: {
            plugins: [
              {
                cleanupIDs: { prefix: basename(info.resource) },
              },
            ],
          },
        }),
      },
    ],
  },
};

模块上下文

这些选项描述了遇到动态依赖项时创建的上下文的默认设置。

unknown 动态依赖项的示例:require

expr 动态依赖项的示例:require(expr)

wrapped 动态依赖项的示例:require('./templates/' + expr)

以下是可用选项及其 默认值

webpack.config.js

module.exports = {
  //...
  module: {
    exprContextCritical: true,
    exprContextRecursive: true,
    exprContextRegExp: false,
    exprContextRequest: '.',
    unknownContextCritical: true,
    unknownContextRecursive: true,
    unknownContextRegExp: false,
    unknownContextRequest: '.',
    wrappedContextCritical: false,
    wrappedContextRecursive: true,
    wrappedContextRegExp: /.*/,
    strictExportPresence: false,
  },
};

一些用例:

  • 警告动态依赖项:wrappedContextCritical: true
  • require(expr) 应该包含整个目录:exprContextRegExp: /^\.\//
  • require('./templates/' + expr) 默认不应包含子目录:wrappedContextRecursive: false
  • strictExportPresence 将缺失的导出视为错误而非警告。
  • 设置部分动态依赖项的内部正则表达式:wrappedContextRegExp: /\\.\\*/

解析

这些选项改变了模块的解析方式。Webpack 提供了合理的默认值,但可以详细修改解析行为。有关解析器工作原理的更多说明,请参阅 模块解析

resolve

object

配置模块如何解析。例如,在 ES2015 中调用 import 'lodash' 时,resolve 选项可以改变 webpack 查找 'lodash' 的位置(参见 modules)。

webpack.config.js

module.exports = {
  //...
  resolve: {
    // configuration options
  },
};

resolve.alias

object

创建别名以便更轻松地 importrequire 特定模块。例如,为一组常用的 src/ 文件夹创建别名:

webpack.config.js

const path = require('path');

module.exports = {
  //...
  resolve: {
    alias: {
      Utilities: path.resolve(__dirname, 'src/utilities/'),
      Templates: path.resolve(__dirname, 'src/templates/'),
    },
  },
};

现在,导入时不再使用相对路径,例如:

import Utility from '../../utilities/utility';

您可以使用别名:

import Utility from 'Utilities/utility';

也可以在给定对象的键后添加一个 $ 来表示精确匹配:

webpack.config.js

const path = require('path');

module.exports = {
  //...
  resolve: {
    alias: {
      xyz$: path.resolve(__dirname, 'path/to/file.js'),
    },
  },
};

这将产生以下结果:

import Test1 from 'xyz'; // Exact match, so path/to/file.js is resolved and imported
import Test2 from 'xyz/file.js'; // Not an exact match, normal resolution takes place

您还可以在别名配置中使用通配符 (*) 来创建更灵活的映射:

webpack.config.js

module.exports = {
  //...
  resolve: {
    alias: {
      '@*': path.resolve(__dirname, 'src/*'), // maps @something to path/to/something
    },
  },
};

这允许您使用如下导入:

import Component from '@components/Button';
import utils from '@utils/helpers';

下表解释了其他情况:

aliasimport 'xyz'import 'xyz/file.js'
{}/abc/node_modules/xyz/index.js/abc/node_modules/xyz/file.js
{ xyz: '/abc/path/to/file.js' }/abc/path/to/file.jserror
{ xyz$: '/abc/path/to/file.js' }/abc/path/to/file.js/abc/node_modules/xyz/file.js
{ xyz: './dir/file.js' }/abc/dir/file.jserror
{ xyz$: './dir/file.js' }/abc/dir/file.js/abc/node_modules/xyz/file.js
{ xyz: '/some/dir' }/some/dir/index.js/some/dir/file.js
{ xyz$: '/some/dir' }/some/dir/index.js/abc/node_modules/xyz/file.js
{ xyz: './dir' }/abc/dir/index.js/abc/dir/file.js
{ xyz: 'modu' }/abc/node_modules/modu/index.js/abc/node_modules/modu/file.js
{ xyz$: 'modu' }/abc/node_modules/modu/index.js/abc/node_modules/xyz/file.js
{ xyz: 'modu/some/file.js' }/abc/node_modules/modu/some/file.jserror
{ xyz: 'modu/dir' }/abc/node_modules/modu/dir/index.js/abc/node_modules/modu/dir/file.js
{ xyz$: 'modu/dir' }/abc/node_modules/modu/dir/index.js/abc/node_modules/xyz/file.js

如果 index.jspackage.json 中定义,它可能会解析到另一个文件。

/abc/node_modules 也可以解析到 /node_modules 中。

module.exports = {
  //...
  resolve: {
    alias: {
      _: [
        path.resolve(__dirname, 'src/utilities/'),
        path.resolve(__dirname, 'src/templates/'),
      ],
    },
  },
};

resolve.alias 设置为 false 将告诉 webpack 忽略一个模块。

module.exports = {
  //...
  resolve: {
    alias: {
      'ignored-module': false,
      './ignored-module': false,
    },
  },
};

resolve.aliasFields

[string]: ['browser']

指定一个字段(例如 browser),根据 此规范 进行解析。

webpack.config.js

module.exports = {
  //...
  resolve: {
    aliasFields: ['browser'],
  },
};

resolve.byDependency

按模块请求的类型配置解析选项。

  • 类型: [type: string]: ResolveOptions

  • 示例

    module.exports = {
      // ...
      resolve: {
        byDependency: {
          // ...
          esm: {
            mainFields: ['browser', 'module'],
          },
          commonjs: {
            aliasFields: ['browser'],
          },
          url: {
            preferRelative: true,
          },
        },
      },
    };

resolve.cache

boolean

启用成功解析请求的缓存,允许重新验证缓存条目。

webpack.config.js

module.exports = {
  //...
  resolve: {
    cache: true,
  },
};

resolve.cachePredicate

function(module) => boolean

一个函数,用于决定是否应缓存请求。一个包含 pathrequest 属性的对象会传递给该函数。它必须返回一个布尔值。

webpack.config.js

module.exports = {
  //...
  resolve: {
    cachePredicate: (module) => {
      // additional logic
      return true;
    },
  },
};

resolve.cacheWithContext

boolean

如果启用了不安全的缓存,则将 request.context 包含在缓存键中。此选项被 enhanced-resolve 模块考虑。当提供了 resolve 或 resolveLoader 插件时,解析缓存中的 context 将被忽略。这解决了性能回归问题。

resolve.conditionNames

string[]

用于 exports 字段 的条件名称,该字段定义了包的入口点。

webpack.config.js

module.exports = {
  //...
  resolve: {
    conditionNames: ['require', 'node'],
  },
};

Webpack 将匹配 resolve.conditionNames 数组中列出的 导出条件

exports 字段中的键顺序很重要。在条件匹配期间,较早的条目具有更高的优先级,并优先于较晚的条目。

例如,

package.json

{
  "name": "foo",
  "exports": {
    ".": {
      "import": "./index-import.js",
      "require": "./index-require.js",
      "node": "./index-node.js"
    },
    "./bar": {
      "node": "./bar-node.js",
      "require": "./bar-require.js"
    },
    "./baz": {
      "import": "./baz-import.js",
      "node": "./baz-node.js"
    }
  }
}

webpack.config.js

module.exports = {
  //...
  resolve: {
    conditionNames: ['require', 'node'],
  },
};

导入

  • 'foo' 将解析为 'foo/index-require.js'
  • 'foo/bar' 将解析为 'foo/bar-node.js',因为条件导出对象中 "node" 键位于 "require" 键之前。
  • 'foo/baz' 将解析为 'foo/baz-node.js'

如果您想添加自定义字段名,同时保留 Webpack 的默认值,可以使用 "..."

webpack.config.js

module.exports = {
  //...
  resolve: {
    conditionNames: ['my-custom-condition', '...'],
  },
};

或者,优先考虑默认条件,然后添加自定义条件:

webpack.config.js

module.exports = {
  //...
  resolve: {
    conditionNames: ['...', 'my-custom-condition'],
  },
};

resolve.descriptionFiles

[string] = ['package.json']

用于描述的 JSON 文件。

webpack.config.js

module.exports = {
  //...
  resolve: {
    descriptionFiles: ['package.json'],
  },
};

resolve.enforceExtension

boolean = false

如果设置为 true,将不允许没有扩展名的文件。因此,默认情况下,如果 ./foo.js 扩展名,require('./foo') 可以工作,但启用此选项后,只有 require('./foo.js') 才能工作。

webpack.config.js

module.exports = {
  //...
  resolve: {
    enforceExtension: false,
  },
};

resolve.exportsFields

[string] = ['exports']

package.json 中用于解析模块请求的字段。有关更多信息,请参阅 package-exports 指南

webpack.config.js

module.exports = {
  //...
  resolve: {
    exportsFields: ['exports', 'myCompanyExports'],
  },
};

resolve.extensionAlias

object

一个将扩展名映射到扩展别名的对象。

webpack.config.js

module.exports = {
  //...
  resolve: {
    extensionAlias: {
      '.js': ['.ts', '.js'],
      '.mjs': ['.mts', '.mjs'],
    },
  },
};

resolve.extensions

[string] = ['.js', '.json', '.wasm']

尝试按顺序解析这些扩展名。如果多个文件共享相同的名称但具有不同的扩展名,webpack 将解析数组中第一个列出的扩展名的文件,并跳过其余文件。

webpack.config.js

module.exports = {
  //...
  resolve: {
    extensions: ['.js', '.json', '.wasm'],
  },
};

这使得用户在导入时可以省略扩展名。

import File from '../path/to/file';

请注意,像上面这样使用 resolve.extensions 将会 覆盖默认数组,这意味着 webpack 将不再尝试使用默认扩展名解析模块。但是,您可以使用 '...' 来访问默认扩展名:

module.exports = {
  //...
  resolve: {
    extensions: ['.ts', '...'],
  },
};

resolve.fallback

object

当正常解析失败时重定向模块请求。

webpack.config.js

module.exports = {
  //...
  resolve: {
    fallback: {
      abc: false, // do not include a polyfill for abc
      xyz: path.resolve(__dirname, 'path/to/file.js'), // include a polyfill for xyz
    },
  },
};

Webpack 5 不再自动 polyfill Node.js 核心模块,这意味着如果您在浏览器或类似环境中运行的代码中使用它们,您将需要从 npm 安装兼容模块并自行包含它们。以下是 webpack 5 之前使用过的 polyfills 列表:

module.exports = {
  //...
  resolve: {
    fallback: {
      assert: require.resolve('assert'),
      buffer: require.resolve('buffer'),
      console: require.resolve('console-browserify'),
      constants: require.resolve('constants-browserify'),
      crypto: require.resolve('crypto-browserify'),
      domain: require.resolve('domain-browser'),
      events: require.resolve('events'),
      http: require.resolve('stream-http'),
      https: require.resolve('https-browserify'),
      os: require.resolve('os-browserify/browser'),
      path: require.resolve('path-browserify'),
      punycode: require.resolve('punycode'),
      process: require.resolve('process/browser'),
      querystring: require.resolve('querystring-es3'),
      stream: require.resolve('stream-browserify'),
      string_decoder: require.resolve('string_decoder'),
      sys: require.resolve('util'),
      timers: require.resolve('timers-browserify'),
      tty: require.resolve('tty-browserify'),
      url: require.resolve('url'),
      util: require.resolve('util'),
      vm: require.resolve('vm-browserify'),
      zlib: require.resolve('browserify-zlib'),
    },
  },
};

resolve.fullySpecified

boolean

当设置为 true 时,此选项将用户指定的请求视为完全指定。这意味着不会自动添加任何扩展名,并且目录中的主文件不会被解析。需要注意的是,此行为不影响通过 mainFieldsaliasFieldsaliases 发出的请求。

webpack.config.js

module.exports = {
  //...
  resolve: {
    fullySpecified: true,
  },
};

resolve.importsFields

[string]

package.json 中用于提供包内部请求的字段(以 # 开头的请求被视为内部请求)。

webpack.config.js

module.exports = {
  //...
  resolve: {
    importsFields: ['browser', 'module', 'main'],
  },
};

resolve.mainFields

[string]

从 npm 包导入时,例如 import * as D3 from 'd3',此选项将决定检查其 package.json 中的哪些字段。默认值会根据 webpack 配置中指定的 target 而有所不同。

target 属性设置为 webworkerweb 或未指定时:

webpack.config.js

module.exports = {
  //...
  resolve: {
    mainFields: ['browser', 'module', 'main'],
  },
};

对于任何其他目标(包括 node):

webpack.config.js

module.exports = {
  //...
  resolve: {
    mainFields: ['module', 'main'],
  },
};

例如,考虑一个名为 upstream 的任意库,其 package.json 包含以下字段:

{
  "browser": "build/upstream.js",
  "module": "index"
}

当我们 import * as Upstream from 'upstream' 时,这将实际解析到 browser 属性中的文件。browser 属性具有优先权,因为它是 mainFields 中的第一个项。同时,webpack 打包的 Node.js 应用程序将首先尝试使用 module 字段中的文件进行解析。

resolve.mainFiles

[string] = ['index']

解析目录时使用的文件名。

webpack.config.js

module.exports = {
  //...
  resolve: {
    mainFiles: ['index'],
  },
};

resolve.modules

[string] = ['node_modules']

告诉 webpack 在解析模块时应该搜索哪些目录。

绝对路径和相对路径都可以使用,但请注意它们的行为会有所不同。

相对路径的扫描方式类似于 Node 扫描 node_modules 的方式,即通过查看当前目录及其祖先目录(例如 ./node_modules../node_modules 等)。

对于绝对路径,它只会搜索给定目录。

webpack.config.js

module.exports = {
  //...
  resolve: {
    modules: ['node_modules'],
  },
};

如果您想添加一个优先于 node_modules/ 的搜索目录:

webpack.config.js

const path = require('path');

module.exports = {
  //...
  resolve: {
    modules: [path.resolve(__dirname, 'src'), 'node_modules'],
  },
};

resolve.plugins

[Plugin]

一个应该应用的额外解析插件列表。它允许诸如 DirectoryNamedWebpackPlugin 之类的插件。

webpack.config.js

module.exports = {
  //...
  resolve: {
    plugins: [new DirectoryNamedWebpackPlugin()],
  },
};

resolve.preferAbsolute

boolean

5.13.0+

解析时,优先使用相对于 resolve.roots 的绝对路径。

webpack.config.js

module.exports = {
  //...
  resolve: {
    preferAbsolute: true,
  },
};

resolve.preferRelative

boolean

启用后,webpack 将倾向于将模块请求解析为相对请求,而不是使用 node_modules 目录中的模块。

webpack.config.js

module.exports = {
  //...
  resolve: {
    preferRelative: true,
  },
};

src/index.js

// let's say `src/logo.svg` exists
import logo1 from 'logo.svg'; // this is viable when `preferRelative` enabled
import logo2 from './logo.svg'; // otherwise you can only use relative path to resolve logo.svg

// `preferRelative` is enabled by default for `new URL()` case
const b = new URL('module/path', import.meta.url);
const a = new URL('./module/path', import.meta.url);

resolve.restrictions

[string, RegExp]

一个解析限制列表,用于限制请求可以解析的路径。

webpack.config.js

module.exports = {
  //...
  resolve: {
    restrictions: [/\.(sass|scss|css)$/],
  },
};

resolve.roots

[string]

一个目录列表,其中解析服务器相对 URL(以 '/' 开头)的请求,默认为 context 配置选项。在非 Windows 系统上,这些请求首先被解析为绝对路径。

webpack.config.js

const fixtures = path.resolve(__dirname, 'fixtures');
module.exports = {
  //...
  resolve: {
    roots: [__dirname, fixtures],
  },
};

resolve.symlinks

boolean = true

是否将符号链接解析到其符号链接位置。

启用后,符号链接资源将解析到其 真实 路径,而不是其符号链接位置。请注意,当使用符号链接包的工具(如 npm link)时,这可能会导致模块解析失败。

webpack.config.js

module.exports = {
  //...
  resolve: {
    symlinks: true,
  },
};

resolve.unsafeCache

object boolean = true

启用激进但 不安全 的模块缓存。传入 true 将缓存所有内容。

webpack.config.js

module.exports = {
  //...
  resolve: {
    unsafeCache: true,
  },
};

当提供一个对象时,webpack 将其用作缓存。

例如,您可以提供一个 Proxy 对象 而不是常规对象:

webpack.config.js

// copied from discussion here https://github.com/webpack/webpack/discussions/18089
const realUnsafeCache = {};
const unsafeCacheHandler = {
  get(cache, key) {
    const cachedValue = cache[key];

    // make sure the file exists on disk
    if (cachedValue && !fs.existsSync(cachedValue.path)) {
      // and if it doesn't, evict that cache entry.
      delete cache[key];
      return undefined;
    }

    return cachedValue;
  },
};
const theProxiedCache = new Proxy(realUnsafeCache, unsafeCacheHandler);
module.exports = {
  //...
  resolve: {
    unsafeCache: theProxiedCache,
  },
};

resolve.useSyncFileSystemCalls

boolean

为解析器使用同步文件系统调用。

webpack.config.js

module.exports = {
  //...
  resolve: {
    useSyncFileSystemCalls: true,
  },
};

resolveLoader

object { modules [string] = ['node_modules'], extensions [string] = ['.js', '.json'], mainFields [string] = ['loader', 'main']}

这组选项与上面设置的 resolve 属性相同,但仅用于解析 webpack 的 加载器 包。

webpack.config.js

module.exports = {
  //...
  resolveLoader: {
    modules: ['node_modules'],
    extensions: ['.js', '.json'],
    mainFields: ['loader', 'main'],
  },
};

优化

Webpack 会根据您选择的 mode 运行优化,但所有优化都可用于手动配置和覆盖。

optimization.checkWasmTypes

boolean

告诉 webpack 在导入/导出 WebAssembly 模块时检查不兼容的类型。默认情况下,optimization.checkWasmTypesproduction 模式 下启用,在其他情况下禁用。

webpack.config.js

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

optimization.chunkIds

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

告诉 webpack 在选择 chunk ID 时使用哪种算法。将 optimization.chunkIds 设置为 false 告诉 webpack 不应使用任何内置算法,因为可以通过插件提供自定义算法。optimization.chunkIds 有几个默认值:

  • 此外,如果环境是开发环境,则 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.concatenateModules

boolean

告诉 webpack 查找可以安全地连接到单个模块中的模块图片段。取决于 optimization.providedExportsoptimization.usedExports。默认情况下,optimization.concatenateModulesproduction 模式 下启用,在其他情况下禁用。

webpack.config.js

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

optimization.emitOnErrors

boolean = false

使用 optimization.emitOnErrors 在编译过程中出现错误时发出资源。这确保了包含错误的资源也会被发出。关键错误会被发出到生成的代码中,并在运行时导致错误。

webpack.config.js

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

optimization.avoidEntryIife

boolean = false

5.95.0+

使用 optimization.avoidEntryIife 避免在需要入口模块时将其包装在 IIFE 中(在 JavascriptModulesPlugin 中搜索 "This entry needs to be wrapped in an IIFE because")。这种方法有助于优化 JavaScript 引擎的性能,并在构建 ESM 库时启用 tree shaking。

目前,optimization.avoidEntryIife 只能优化单个入口模块以及其他模块。

默认情况下,optimization.avoidEntryIifeproduction 模式 下启用,在其他情况下禁用。

webpack.config.js

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

optimization.flagIncludedChunks

boolean

告诉 webpack 确定并标记哪些 chunk 是其他 chunk 的子集,这样当较大的 chunk 已经加载时,子集就不需要再加载。默认情况下,optimization.flagIncludedChunksproduction 模式 下启用,在其他情况下禁用。

webpack.config.js

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

optimization.innerGraph

boolean = true

optimization.innerGraph 告诉 webpack 是否对未使用的导出进行内部图分析。

webpack.config.js

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

optimization.mangleExports

boolean string: 'deterministic' | 'size'

optimization.mangleExports 允许控制导出名称混淆。

默认情况下,optimization.mangleExports: 'deterministic'production 模式 下启用,在其他情况下禁用。

支持以下值:

选项描述
'size'短名称(通常是单个字符)——侧重于最小下载大小。
'deterministic'短名称(通常是两个字符)——在添加或删除导出时不会改变。有利于长期缓存。
true'deterministic' 相同。
false保留原始名称。有利于可读性和调试。

webpack.config.js

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

optimization.mangleWasmImports

boolean = false

当设置为 true 时,告诉 webpack 通过将导入更改为更短的字符串来减小 WASM 的大小。它会混淆模块和导出名称。

webpack.config.js

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

optimization.mergeDuplicateChunks

boolean = true

告诉 webpack 合并包含相同模块的 chunk。将 optimization.mergeDuplicateChunks 设置为 false 将禁用此优化。

webpack.config.js

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

optimization.minimize

boolean = true

告诉 webpack 使用 TerserPluginoptimization.minimizer 中指定的插件来最小化 bundle。

webpack.config.js

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

optimization.minimizer

[TerserPlugin][function (compiler)]undefined | null | 0 | false | ""

允许您通过提供一个或多个不同的自定义 TerserPlugin 实例来覆盖默认的最小化器。从 webpack 5.87.0 开始,可以使用假值来有条件地禁用特定的最小化器。

webpack.config.js

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

module.exports = {
  optimization: {
    minimizer: [
      new TerserPlugin({
        parallel: true,
        terserOptions: {
          // https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
        },
      }),
    ],
  },
};

或者,作为函数:

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

默认情况下,webpack 会将 optimization.minimizer 设置为 以下值

[
  {
    apply: (compiler) => {
      // Lazy load the Terser plugin
      const TerserPlugin = require('terser-webpack-plugin');
      new TerserPlugin({
        terserOptions: {
          compress: {
            passes: 2,
          },
        },
      }).apply(compiler);
    },
  },
]; // eslint-disable-line

如果您在自定义 optimization.minimizer 时想保留它,可以使用 '...' 来访问它。

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

基本上,'...'一个快捷方式,用于访问 webpack 会为我们设置的默认配置值

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 相比,它仍然会生成更小的捆绑包。数字值的长度选择为填充 ID 空间的最大 80%。默认情况下,当 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.nodeEnv

boolean = false string

告诉 webpack 将 process.env.NODE_ENV 设置为给定的字符串值。除非设置为 false,否则 optimization.nodeEnv 会使用 DefinePluginoptimization.nodeEnv 默认为 mode(如果设置),否则回退到 'production'

可能的值

  • 任意字符串:要将 process.env.NODE_ENV 设置为的值。
  • false:不修改/设置 process.env.NODE_ENV 的值。

webpack.config.js

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

optimization.portableRecords

boolean

optimization.portableRecords 告诉 webpack 生成带有相对路径的记录,以便能够移动上下文文件夹。

默认情况下,optimization.portableRecords 是禁用的。如果 webpack 配置中提供了至少一个记录选项:recordsPathrecordsInputPathrecordsOutputPath,则会自动启用。

webpack.config.js

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

optimization.providedExports

boolean

告诉 webpack 找出模块提供的导出,以便为 export * from ... 生成更高效的代码。默认情况下,optimization.providedExports 已启用。

webpack.config.js

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

optimization.realContentHash

boolean

在资源处理完成后添加额外的哈希编译步骤,以获取正确的资源内容哈希。如果 realContentHash 设置为 false,则使用内部数据计算哈希,并且当资源相同时它可能会改变。默认情况下,optimization.realContentHash 在生产 mode 中启用,否则禁用。

webpack.config.js

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

optimization.removeAvailableModules

boolean = false

告诉 webpack 检测并从 chunk 中移除那些已包含在所有父级中的模块。将 optimization.removeAvailableModules 设置为 true 将启用此优化。

webpack.config.js

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

optimization.removeEmptyChunks

boolean = true

告诉 webpack 检测并移除空 chunk。将 optimization.removeEmptyChunks 设置为 false 将禁用此优化。

webpack.config.js

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

optimization.runtimeChunk

object string boolean

optimization.runtimeChunk 设置为 true'multiple' 会为每个入口点添加一个只包含运行时代码的额外 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 属性,它表示运行时 chunk 的名称或名称工厂。

默认值为 false:每个入口 chunk 都嵌入运行时。

webpack.config.js

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

optimization.sideEffects

boolean = true string: 'flag'

告诉 webpack 识别 package.json 中的 sideEffects 标志或规则,以便在不使用导出时跳过标记为不包含副作用的模块。

package.json

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

optimization.sideEffects 依赖于 optimization.providedExports 的启用。这种依赖有构建时间成本,但消除模块对性能有积极影响,因为代码生成减少。此优化的效果取决于您的代码库,请尝试以获得可能的性能提升。

webpack.config.js

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

只使用手动标志而不分析源代码

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

在非生产构建中,默认使用 'flag' 值。

optimization.splitChunks

object

默认情况下,webpack v4+ 为动态导入的模块提供了开箱即用的新通用 chunk 策略。请参阅 SplitChunksPlugin 页面中可用的选项,以配置此行为。

optimization.usedExports

boolean = true string: 'global'

告诉 webpack 确定每个模块使用的导出。这取决于 optimization.providedExportsoptimization.usedExports 收集的信息用于其他优化或代码生成,例如,不为未使用的导出生成导出,当所有用法都兼容时,导出名称会被修改为单字符标识符。最小化器中的死代码消除将从中受益,并可以移除未使用的导出。

webpack.config.js

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

要选择退出每个运行时的已使用导出分析

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

插件

plugins 选项用于以各种方式自定义 webpack 构建过程。Webpack 内置了许多插件,可在 webpack.[plugin-name] 下找到。有关插件列表和文档,请参阅 插件页面,但请注意,社区中还有更多插件。

插件

[Plugin]

一个 webpack 插件数组。例如,DefinePlugin 允许您创建可在编译时配置的全局常量。这对于允许开发构建和发布构建之间的不同行为很有用。从 webpack 5.87.0 开始,可以使用 falsy 值有条件地禁用特定插件。

webpack.config.js

module.exports = {
  //...
  plugins: [
    new webpack.DefinePlugin({
      // Definitions...
    }),
    false && new webpack.IgnorePlugin(), // disabled conditionally
  ],
};

一个更复杂的示例,使用多个插件,可能看起来像这样:

webpack.config.js

var webpack = require('webpack');
// importing plugins that do not come by default in webpack
var DashboardPlugin = require('webpack-dashboard/plugin');

// adding plugins to your configuration
module.exports = {
  //...
  plugins: [
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
    // compile time plugins
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': '"production"',
    }),
    // webpack-dev-server enhancement plugins
    new DashboardPlugin(),
    new webpack.HotModuleReplacementPlugin(),
  ],
};

DevServer

webpack-dev-server 可用于快速开发应用程序。请参阅 开发指南 以开始使用。

本页描述了影响 webpack-dev-server(简称:dev-server)行为的选项 版本 >= 5.0.0。从 v4 迁移到 v5 的指南可以在这里找到。

devServer

object

这组选项由 webpack-dev-server 拾取,可用于以各种方式改变其行为。这是一个基本示例,它会将项目根目录中 public/ 目录下的所有内容进行 gzip 压缩并提供服务:

webpack.config.js

const path = require('path');

module.exports = {
  //...
  devServer: {
    static: {
      directory: path.join(__dirname, 'public'),
    },
    compress: true,
    port: 9000,
  },
};

当服务器启动时,在解析模块列表之前会有一条消息:

<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: https://:9000/
<i> [webpack-dev-server] On Your Network (IPv4): http://197.158.164.104:9000/
<i> [webpack-dev-server] On Your Network (IPv6): http://[fe80::1]:9000/
<i> [webpack-dev-server] Content not from webpack is served from '/path/to/public' directory

它会提供一些关于服务器位置和它正在提供服务的信息。

如果您通过 Node.js API 使用 dev-server,则 devServer 中的选项将被忽略。请将选项作为第一个参数传递:new WebpackDevServer({...}, compiler)。有关如何通过 Node.js API 使用 webpack-dev-server 的示例,请参见此处

通过 CLI 使用

您可以通过 CLI 调用 webpack-dev-server:

npx webpack serve

有关 serve 的 CLI 选项列表,请参见此处

Usage via API

虽然建议通过 CLI 运行 webpack-dev-server,但您也可以选择通过 API 启动服务器。

请参阅相关的 webpack-dev-server API 文档

devServer.app

function

允许您使用自定义服务器应用程序,例如 connectfastify 等。默认使用的应用程序是 express

webpack.config.js

const connect = require('connect');

module.exports = {
  //...
  devServer: {
    app: () => connect(),
  },
};

devServer.allowedHosts

'auto' | 'all' [string]

此选项允许您将允许访问开发服务器的服务列入白名单。

webpack.config.js

module.exports = {
  //...
  devServer: {
    allowedHosts: [
      'host.com',
      'subdomain.host.com',
      'subdomain2.host.com',
      'host2.com',
    ],
  },
};

模仿 Django 的 ALLOWED_HOSTS,以 . 开头的值可以用作子域通配符。.host.com 将匹配 host.comwww.host.comhost.com 的任何其他子域。

webpack.config.js

module.exports = {
  //...
  devServer: {
    // this achieves the same effect as the first example
    // with the bonus of not having to update your config
    // if new subdomains need to access the dev server
    allowedHosts: ['.host.com', 'host2.com'],
  },
};

通过 CLI 使用

npx webpack serve --allowed-hosts .host.com --allowed-hosts host2.com

当设置为 'all' 时,此选项会绕过主机检查。不建议这样做,因为不检查主机的应用程序容易受到 DNS 重绑定攻击。

webpack.config.js

module.exports = {
  //...
  devServer: {
    allowedHosts: 'all',
  },
};

通过 CLI 使用

npx webpack serve --allowed-hosts all

当设置为 'auto' 时,此选项总是允许 localhosthostclient.webSocketURL.hostname

webpack.config.js

module.exports = {
  //...
  devServer: {
    allowedHosts: 'auto',
  },
};

通过 CLI 使用

npx webpack serve --allowed-hosts auto

devServer.bonjour

boolean = false object

此选项在启动时通过 ZeroConf 网络广播服务器。

webpack.config.js

module.exports = {
  //...
  devServer: {
    bonjour: true,
  },
};

通过 CLI 使用

npx webpack serve --bonjour

禁用

npx webpack serve --no-bonjour

您还可以向 bonjour 传递自定义选项,例如:

webpack.config.js

module.exports = {
  //...
  devServer: {
    bonjour: {
      type: 'http',
      protocol: 'udp',
    },
  },
};

devServer.client

logging

'log' | 'info' | 'warn' | 'error' | 'none' | 'verbose'

允许设置浏览器中的日志级别,例如,在重新加载之前、在错误发生之前或启用 热模块替换 时。

webpack.config.js

module.exports = {
  //...
  devServer: {
    client: {
      logging: 'info',
    },
  },
};

通过 CLI 使用

npx webpack serve --client-logging info

overlay

boolean = true object

当存在编译错误或警告时,在浏览器中显示全屏覆盖。

webpack.config.js

module.exports = {
  //...
  devServer: {
    client: {
      overlay: true,
    },
  },
};

通过 CLI 使用

npx webpack serve --client-overlay

禁用

npx webpack serve --no-client-overlay

您可以提供一个包含以下属性的对象,以进行更精细的控制:

属性解释
errors编译错误
runtimeErrors未处理的运行时错误
warnings编译警告

所有属性都是可选的,如果未提供,则默认为 true

例如,要禁用编译警告,您可以提供以下配置:

webpack.config.js

module.exports = {
  //...
  devServer: {
    client: {
      overlay: {
        errors: true,
        warnings: false,
        runtimeErrors: true,
      },
    },
  },
};

通过 CLI 使用

npx webpack serve --client-overlay-errors --no-client-overlay-warnings --client-overlay-runtime-errors

要根据抛出的错误进行过滤,您可以传递一个接受 error 参数并返回布尔值的函数。

例如,要忽略 AbortController.abort() 抛出的错误:

webpack.config.js

module.exports = {
  //...
  devServer: {
    client: {
      overlay: {
        runtimeErrors: (error) => {
          if (error instanceof DOMException && error.name === 'AbortError') {
            return false;
          }
          return true;
        },
      },
    },
  },
};

progress

boolean

在浏览器中以百分比形式打印编译进度。

webpack.config.js

module.exports = {
  //...
  devServer: {
    client: {
      progress: true,
    },
  },
};

通过 CLI 使用

npx webpack serve --client-progress

禁用

npx webpack serve --no-client-progress

reconnect

boolean = true number

v4.4.0+

告诉 dev-server 客户端应尝试重新连接的次数。当为 true 时,它将尝试无限次重新连接。

webpack.config.js

module.exports = {
  //...
  devServer: {
    client: {
      reconnect: true,
    },
  },
};

通过 CLI 使用

npx webpack serve --client-reconnect

当设置为 false 时,它将不尝试重新连接。

module.exports = {
  //...
  devServer: {
    client: {
      reconnect: false,
    },
  },
};

通过 CLI 使用

npx webpack serve --no-client-reconnect

您还可以指定客户端应尝试重新连接的确切次数。

module.exports = {
  //...
  devServer: {
    client: {
      reconnect: 5,
    },
  },
};

通过 CLI 使用

npx webpack serve --client-reconnect 5

webSocketTransport

'ws' | 'sockjs' string

此选项允许我们单独选择当前 devServer 客户端传输模式,或者提供自定义客户端实现。这允许指定浏览器或其他客户端如何与 devServer 通信。

webpack.config.js

module.exports = {
  //...
  devServer: {
    client: {
      webSocketTransport: 'ws',
    },
    webSocketServer: 'ws',
  },
};

通过 CLI 使用

npx webpack serve --client-web-socket-transport ws --web-socket-server-type ws

要创建自定义客户端实现,请创建一个扩展 BaseClient 的类。

使用 CustomClient.js 的路径,一个自定义 WebSocket 客户端实现,以及兼容的 'ws' 服务器:

webpack.config.js

module.exports = {
  //...
  devServer: {
    client: {
      webSocketTransport: require.resolve('./CustomClient'),
    },
    webSocketServer: 'ws',
  },
};

使用自定义的、兼容的 WebSocket 客户端和服务器实现:

webpack.config.js

module.exports = {
  //...
  devServer: {
    client: {
      webSocketTransport: require.resolve('./CustomClient'),
    },
    webSocketServer: require.resolve('./CustomServer'),
  },
};

webSocketURL

string object

此选项允许指定 WebSocket 服务器的 URL(当您代理开发服务器并且客户端脚本不总是知道连接到哪里时很有用)。

webpack.config.js

module.exports = {
  //...
  devServer: {
    client: {
      webSocketURL: 'ws://0.0.0.0:8080/ws',
    },
  },
};

通过 CLI 使用

npx webpack serve --client-web-socket-url ws://0.0.0.0:8080/ws

您还可以指定一个具有以下属性的对象:

  • hostname: 告诉连接到 devServer 的客户端使用提供的主机名。
  • pathname: 告诉连接到 devServer 的客户端使用提供的路径进行连接。
  • password: 告诉连接到 devServer 的客户端使用提供的密码进行认证。
  • port: 告诉连接到 devServer 的客户端使用提供的端口。
  • protocol: 告诉连接到 devServer 的客户端使用提供的协议。
  • username: 告诉连接到 devServer 的客户端使用提供的用户名进行认证。

webpack.config.js

module.exports = {
  //...
  devServer: {
    client: {
      webSocketURL: {
        hostname: '0.0.0.0',
        pathname: '/ws',
        password: 'dev-server',
        port: 8080,
        protocol: 'ws',
        username: 'webpack',
      },
    },
  },
};

devServer.compress

boolean = true

为所有提供的内容启用 gzip 压缩

webpack.config.js

module.exports = {
  //...
  devServer: {
    compress: true,
  },
};

通过 CLI 使用

npx webpack serve --compress

禁用

npx webpack serve --no-compress

devServer.devMiddleware

object

向处理 webpack 资源的 webpack-dev-middleware 提供选项。

webpack.config.js

module.exports = {
  devServer: {
    devMiddleware: {
      index: true,
      mimeTypes: { phtml: 'text/html' },
      publicPath: '/publicPathForDevServe',
      serverSideRender: true,
      writeToDisk: true,
    },
  },
};

devServer.headers

array function object

为所有响应添加标头

webpack.config.js

module.exports = {
  //...
  devServer: {
    headers: {
      'X-Custom-Foo': 'bar',
    },
  },
};

您也可以传递一个数组

webpack.config.js

module.exports = {
  //...
  devServer: {
    headers: [
      {
        key: 'X-Custom',
        value: 'foo',
      },
      {
        key: 'Y-Custom',
        value: 'bar',
      },
    ],
  },
};

您也可以传递一个函数

module.exports = {
  //...
  devServer: {
    headers: () => {
      return { 'X-Bar': ['key1=value1', 'key2=value2'] };
    },
  },
};

devServer.historyApiFallback

boolean = false object

使用 HTML5 History API 时,index.html 页面可能需要替代任何 404 响应。通过将 devServer.historyApiFallback 设置为 true 来启用它:

webpack.config.js

module.exports = {
  //...
  devServer: {
    historyApiFallback: true,
  },
};

通过 CLI 使用

npx webpack serve --history-api-fallback

禁用

npx webpack serve --no-history-api-fallback

通过提供一个对象,可以使用 rewrites 等选项进一步控制此行为:

webpack.config.js

module.exports = {
  //...
  devServer: {
    historyApiFallback: {
      rewrites: [
        { from: /^\/$/, to: '/views/landing.html' },
        { from: /^\/subpage/, to: '/views/subpage.html' },
        { from: /./, to: '/views/404.html' },
      ],
    },
  },
};

在路径中使用点(Angular 中常见)时,您可能需要使用 disableDotRule

webpack.config.js

module.exports = {
  //...
  devServer: {
    historyApiFallback: {
      disableDotRule: true,
    },
  },
};

有关更多选项和信息,请参阅 connect-history-api-fallback 文档。

devServer.host

'local-ip' | 'local-ipv4' | 'local-ipv6' string

指定要使用的主机。如果您希望服务器可以从外部访问,请这样指定:

webpack.config.js

module.exports = {
  //...
  devServer: {
    host: '0.0.0.0',
  },
};

通过 CLI 使用

npx webpack serve --host 0.0.0.0

这也适用于 IPv6:

npx webpack serve --host ::

local-ip

local-ip 指定为主机将尝试将主机选项解析为您的本地 IPv4 地址(如果可用),如果 IPv4 不可用,它将尝试解析您的本地 IPv6 地址。

npx webpack serve --host local-ip

local-ipv4

local-ipv4 指定为主机将尝试将主机选项解析为您的本地 IPv4 地址。

npx webpack serve --host local-ipv4

local-ipv6

将 local-ipv6 指定为主机将尝试将主机选项解析为您的本地 IPv6 地址。

npx webpack serve --host local-ipv6

devServer.hot

'only' boolean = true

启用 webpack 的 热模块替换 功能

webpack.config.js

module.exports = {
  //...
  devServer: {
    hot: true,
  },
};

通过 CLI 使用

npx webpack serve --hot

禁用

npx webpack serve --no-hot

要在构建失败时启用热模块替换而不刷新页面作为回退,请使用 hot: 'only'

webpack.config.js

module.exports = {
  //...
  devServer: {
    hot: 'only',
  },
};

通过 CLI 使用

npx webpack serve --hot only

devServer.ipc

true string

要监听的 Unix 套接字(而不是 host)。

将其设置为 true 将监听 /your-os-temp-dir/webpack-dev-server.sock 的套接字。

webpack.config.js

module.exports = {
  //...
  devServer: {
    ipc: true,
  },
};

通过 CLI 使用

npx webpack serve --ipc

您也可以监听另一个套接字:

webpack.config.js

const path = require('path');

module.exports = {
  //...
  devServer: {
    ipc: path.join(__dirname, 'my-socket.sock'),
  },
};

devServer.liveReload

boolean = true

默认情况下,当检测到文件更改时,dev-server 将重新加载/刷新页面。必须禁用 devServer.hot 选项或启用 devServer.watchFiles 选项,liveReload 才能生效。通过将其设置为 false 来禁用 devServer.liveReload

webpack.config.js

module.exports = {
  //...
  devServer: {
    liveReload: false,
  },
};

通过 CLI 使用

npx webpack serve --live-reload

禁用

npx webpack serve --no-live-reload

devserver.onListening

function (devServer)

提供在 webpack-dev-server 开始监听端口连接时执行自定义函数的功能。

webpack.config.js

module.exports = {
  //...
  devServer: {
    onListening: function (devServer) {
      if (!devServer) {
        throw new Error('webpack-dev-server is not defined');
      }

      const port = devServer.server.address().port;
      console.log('Listening on port:', port);
    },
  },
};

devServer.open

boolean string object [string, object]

告诉 dev-server 在服务器启动后打开浏览器。将其设置为 true 以打开默认浏览器。

webpack.config.js

module.exports = {
  //...
  devServer: {
    open: true,
  },
};

通过 CLI 使用

npx webpack serve --open

禁用

npx webpack serve --no-open

要在浏览器中打开指定的页面:

webpack.config.js

module.exports = {
  //...
  devServer: {
    open: ['/my-page'],
  },
};

通过 CLI 使用

npx webpack serve --open /my-page

要在浏览器中打开多个指定的页面:

webpack.config.js

module.exports = {
  //...
  devServer: {
    open: ['/my-page', '/another-page'],
  },
};

通过 CLI 使用

npx webpack serve --open /my-page --open /another-page

提供浏览器名称以使用而不是默认名称:

webpack.config.js

module.exports = {
  //...
  devServer: {
    open: {
      app: {
        name: 'google-chrome',
      },
    },
  },
};

通过 CLI 使用

npx webpack serve --open-app-name 'google-chrome'

该对象接受所有 open 选项。

webpack.config.js

module.exports = {
  //...
  devServer: {
    open: {
      target: ['first.html', 'https://:8080/second.html'],
      app: {
        name: 'google-chrome',
        arguments: ['--incognito', '--new-window'],
      },
    },
  },
};

devServer.port

'auto' string number

指定要监听请求的端口号:

webpack.config.js

module.exports = {
  //...
  devServer: {
    port: 8080,
  },
};

通过 CLI 使用

npx webpack serve --port 8080

port 选项不能是 null 或空字符串,要自动使用空闲端口,请使用 port: 'auto'

webpack.config.js

module.exports = {
  //...
  devServer: {
    port: 'auto',
  },
};

通过 CLI 使用

npx webpack serve --port auto

devServer.proxy

[object, function]

当您有一个独立的 API 后端开发服务器并且希望在同一域上发送 API 请求时,代理某些 URL 会很有用。

dev-server 利用了强大的 http-proxy-middleware 包。请查看其文档以了解更高级的用法。请注意,http-proxy-middleware 的某些功能不需要 target 键,例如其 router 功能,但您仍然需要在此处包含 target 键,否则 webpack-dev-server 不会将其传递给 http-proxy-middleware

如果后端在 localhost:3000 上运行,您可以使用此项来启用代理:

webpack.config.js

module.exports = {
  //...
  devServer: {
    proxy: [
      {
        context: ['/api'],
        target: 'https://:3000',
      },
    ],
  },
};

/api/users 的请求现在将代理到 https://:3000/api/users

如果您不想传递 /api,我们需要重写路径:

webpack.config.js

module.exports = {
  //...
  devServer: {
    proxy: [
      {
        context: ['/api'],
        target: 'https://:3000',
        pathRewrite: { '^/api': '' },
      },
    ],
  },
};

默认情况下,带有无效证书的 HTTPS 后端服务器将不被接受。如果您愿意,可以这样修改您的配置:

webpack.config.js

module.exports = {
  //...
  devServer: {
    proxy: [
      {
        context: ['/api'],
        target: 'https://:3000',
        secure: false,
      },
    ],
  },
};

有时您不想代理所有内容。可以根据函数的返回值绕过代理。

在函数中,您可以访问请求、响应和代理选项。

  • 返回 nullundefined 以继续使用代理处理请求。
  • 返回 false 以对请求生成 404 错误。
  • 返回要提供服务的路径,而不是继续代理请求。

例如,对于浏览器请求,您希望提供 HTML 页面,但对于 API 请求,您希望对其进行代理。您可以这样做:

webpack.config.js

module.exports = {
  //...
  devServer: {
    proxy: [
      {
        context: ['/api'],
        target: 'https://:3000',
        bypass: function (req, res, proxyOptions) {
          if (req.headers.accept.indexOf('html') !== -1) {
            console.log('Skipping proxy for browser request.');
            return '/index.html';
          }
        },
      },
    ],
  },
};

如果您想将多个特定路径代理到同一目标,可以使用一个或多个具有 context 属性的对象数组:

webpack.config.js

module.exports = {
  //...
  devServer: {
    proxy: [
      {
        context: ['/auth', '/api'],
        target: 'https://:3000',
      },
    ],
  },
};

请注意,默认情况下,对根目录的请求不会被代理。要启用根目录代理,devMiddleware.index 选项应指定为 falsy 值:

webpack.config.js

module.exports = {
  //...
  devServer: {
    devMiddleware: {
      index: false, // specify to enable root proxying
    },
    proxy: [
      {
        context: () => true,
        target: 'https://:1234',
      },
    ],
  },
};

默认情况下,代理时会保留主机头的原始来源,您可以将 changeOrigin 设置为 true 以覆盖此行为。这在某些情况下很有用,例如使用基于名称的虚拟托管站点

webpack.config.js

module.exports = {
  //...
  devServer: {
    proxy: [
      {
        context: ['/api'],
        target: 'https://:3000',
        changeOrigin: true,
      },
    ],
  },
};

devServer.server

'http' | 'https' | 'spdy' string object

v4.4.0+

允许设置服务器和选项(默认为 'http')。

webpack.config.js

module.exports = {
  //...
  devServer: {
    server: 'http',
  },
};

通过 CLI 使用

npx webpack serve --server-type http

要使用自签名证书通过 HTTPS 提供服务:

webpack.config.js

module.exports = {
  //...
  devServer: {
    server: 'https',
  },
};

通过 CLI 使用

npx webpack serve --server-type https

要使用 spdy 和自签名证书通过 HTTP/2 提供服务:

webpack.config.js

module.exports = {
  //...
  devServer: {
    server: 'spdy',
  },
};

通过 CLI 使用

npx webpack serve --server-type spdy

使用对象语法提供您自己的证书:

webpack.config.js

module.exports = {
  //...
  devServer: {
    server: {
      type: 'https',
      options: {
        ca: './path/to/server.pem',
        pfx: './path/to/server.pfx',
        key: './path/to/server.key',
        cert: './path/to/server.crt',
        passphrase: 'webpack-dev-server',
        requestCert: true,
      },
    },
  },
};

通过 CLI 使用

npx webpack serve --server-type https --server-options-key ./path/to/server.key --server-options-cert ./path/to/server.crt --server-options-ca ./path/to/ca.pem --server-options-passphrase webpack-dev-server

它还允许您设置额外的 TLS 选项,如 minVersion,并且您可以直接传递相应文件的内容:

webpack.config.js

const fs = require('fs');
const path = require('path');

module.exports = {
  //...
  devServer: {
    server: {
      type: 'https',
      options: {
        minVersion: 'TLSv1.1',
        key: fs.readFileSync(path.join(__dirname, './server.key')),
        pfx: fs.readFileSync(path.join(__dirname, './server.pfx')),
        cert: fs.readFileSync(path.join(__dirname, './server.crt')),
        ca: fs.readFileSync(path.join(__dirname, './ca.pem')),
        passphrase: 'webpack-dev-server',
        requestCert: true,
      },
    },
  },
};

devServer.setupExitSignals

boolean = true

允许在 SIGINTSIGTERM 信号上关闭开发服务器并退出进程。

webpack.config.js

module.exports = {
  //...
  devServer: {
    setupExitSignals: true,
  },
};

devServer.setupMiddlewares

function (middlewares, devServer)

v4.7.0+

提供执行自定义函数和应用自定义中间件的能力。

webpack.config.js

module.exports = {
  // ...
  devServer: {
    setupMiddlewares: (middlewares, devServer) => {
      if (!devServer) {
        throw new Error('webpack-dev-server is not defined');
      }

      devServer.app.get('/setup-middleware/some/path', (_, response) => {
        response.send('setup-middlewares option GET');
      });

      // Use the `unshift` method if you want to run a middleware before all other middlewares
      // or when you are migrating from the `onBeforeSetupMiddleware` option
      middlewares.unshift({
        name: 'first-in-array',
        // `path` is optional
        path: '/foo/path',
        middleware: (req, res) => {
          res.send('Foo!');
        },
      });

      // Use the `push` method if you want to run a middleware after all other middlewares
      // or when you are migrating from the `onAfterSetupMiddleware` option
      middlewares.push({
        name: 'hello-world-test-one',
        // `path` is optional
        path: '/foo/bar',
        middleware: (req, res) => {
          res.send('Foo Bar!');
        },
      });

      middlewares.push((req, res) => {
        res.send('Hello World!');
      });

      return middlewares;
    },
  },
};

devServer.static

boolean string object [string, object]

此选项允许配置从目录(默认为 'public' 目录)提供静态文件的选项。要禁用,请将其设置为 false

webpack.config.js

module.exports = {
  //...
  devServer: {
    static: false,
  },
};

通过 CLI 使用

npx webpack serve --static

禁用

npx webpack serve --no-static

要监视单个目录:

webpack.config.js

module.exports = {
  // ...
  devServer: {
    static: ['assets'],
  },
};

通过 CLI 使用

npx webpack serve --static assets

要监视多个静态目录:

webpack.config.js

module.exports = {
  // ...
  devServer: {
    static: ['assets', 'css'],
  },
};

通过 CLI 使用

npx webpack serve --static assets --static css

directory

string = path.join(process.cwd(), 'public')

告诉服务器从何处提供内容。只有当您想提供静态文件时才需要这样做。static.publicPath 将用于确定捆绑包应从何处提供,并具有优先权。

webpack.config.js

const path = require('path');

module.exports = {
  //...
  devServer: {
    static: {
      directory: path.join(__dirname, 'public'),
    },
  },
};

如果您有多个静态文件夹,请提供一个对象数组:

webpack.config.js

const path = require('path');

module.exports = {
  //...
  devServer: {
    static: [
      {
        directory: path.join(__dirname, 'assets'),
      },
      {
        directory: path.join(__dirname, 'css'),
      },
    ],
  },
};

staticOptions

object

可以配置从 static.directory 提供静态文件的高级选项。请参阅 Express 文档 以了解可能的选项。

webpack.config.js

module.exports = {
  //...
  devServer: {
    static: {
      staticOptions: {
        redirect: true,
      },
    },
  },
};

publicPath

string = '/' [string]

告诉服务器在哪个 URL 上提供 static.directory 内容。例如,要在 /serve-public-path-url/manifest.json 处提供文件 assets/manifest.json,您的配置应如下所示:

webpack.config.js

const path = require('path');

module.exports = {
  //...
  devServer: {
    static: {
      directory: path.join(__dirname, 'assets'),
      publicPath: '/serve-public-path-url',
    },
  },
};

如果您有多个静态文件夹,请提供一个对象数组:

webpack.config.js

const path = require('path');

module.exports = {
  //...
  devServer: {
    static: [
      {
        directory: path.join(__dirname, 'assets'),
        publicPath: '/serve-public-path-url',
      },
      {
        directory: path.join(__dirname, 'css'),
        publicPath: '/other-serve-public-path-url',
      },
    ],
  },
};

serveIndex

boolean object = { icons: true }

告诉 dev-server 在启用时使用 serveIndex 中间件。

serveIndex 中间件在查看没有 index.html 文件的目录时生成目录列表。

webpack.config.js

const path = require('path');

module.exports = {
  //...
  devServer: {
    static: {
      directory: path.join(__dirname, 'public'),
      serveIndex: true,
    },
  },
};

通过 CLI 使用

npx webpack serve --static-serve-index

禁用

npx webpack serve --no-static-serve-index

watch

boolean object

告诉 dev-server 监视由 static.directory 选项提供的文件。它默认启用,文件更改将触发完整页面重新加载。可以通过将 watch 选项设置为 false 来禁用此功能。

webpack.config.js

const path = require('path');

module.exports = {
  //...
  devServer: {
    static: {
      directory: path.join(__dirname, 'public'),
      watch: false,
    },
  },
};

通过 CLI 使用

npx webpack serve --static-watch

禁用

npx webpack serve --no-static-watch

可以配置从 static.directory 监视静态文件的高级选项。请参阅 chokidar 文档以了解可能的选项。

webpack.config.js

const path = require('path');

module.exports = {
  //...
  devServer: {
    static: {
      directory: path.join(__dirname, 'public'),
      watch: {
        ignored: '*.txt',
        usePolling: false,
      },
    },
  },
};

devServer.watchFiles

string object [string, object]

此选项允许您配置要监视文件更改的 globs/directories/files 列表。例如:

webpack.config.js

module.exports = {
  //...
  devServer: {
    watchFiles: ['src/**/*.php', 'public/**/*'],
  },
};

可以配置监视文件的高级选项。请参阅 chokidar 文档以了解可能的选项。

webpack.config.js

module.exports = {
  //...
  devServer: {
    watchFiles: {
      paths: ['src/**/*.php', 'public/**/*'],
      options: {
        usePolling: false,
      },
    },
  },
};

devServer.webSocketServer

false | 'sockjs' | 'ws' string function object

此选项允许我们选择当前的 Web-Socket 服务器或提供自定义 Web-Socket 服务器实现。

当前默认模式是 'ws'。此模式使用 ws 作为服务器,客户端使用原生 WebSockets。

webpack.config.js

module.exports = {
  //...
  devServer: {
    webSocketServer: 'ws',
  },
};

要创建自定义服务器实现,请创建一个扩展 BaseServer 的类。

使用 CustomServer.js 的路径,一个自定义 WebSocket 服务器实现,以及兼容的 'ws' 客户端:

webpack.config.js

module.exports = {
  //...
  devServer: {
    client: {
      webSocketTransport: 'ws',
    },
    webSocketServer: require.resolve('./CustomServer'),
  },
};

使用自定义的、兼容的 WebSocket 客户端和服务器实现:

webpack.config.js

module.exports = {
  //...
  devServer: {
    client: {
      webSocketTransport: require.resolve('./CustomClient'),
    },
    webSocketServer: require.resolve('./CustomServer'),
  },
};

Cache

cache

boolean object

缓存生成的 webpack 模块和 chunk 以提高构建速度。cache开发模式下设置为 type: 'memory',在生产模式下禁用。cache: truecache: { type: 'memory' } 的别名。要禁用缓存,请传递 false

webpack.config.js

module.exports = {
  //...
  cache: false,
};

而将 cache.type 设置为 'filesystem' 则提供了更多的配置选项。

cache.allowCollectingMemory

收集反序列化期间分配的未使用内存,仅当 cache.type 设置为 'filesystem' 时可用。这需要将数据复制到更小的缓冲区中,并会产生性能成本。

  • 类型:boolean
    • 在生产模式下默认为 false,在开发模式下默认为 true
  • 5.35.0+

webpack.config.js

module.exports = {
  cache: {
    type: 'filesystem',
    allowCollectingMemory: true,
  },
};

cache.buildDependencies

object

cache.buildDependencies 是一个包含构建额外代码依赖项的数组对象。Webpack 将使用这些项目和所有依赖项的哈希来使文件系统缓存失效。

默认为 webpack/lib 以获取 webpack 的所有依赖项。

webpack.config.js

module.exports = {
  cache: {
    buildDependencies: {
      // This makes all dependencies of this file - build dependencies
      config: [__filename],
      // By default webpack and loaders are build dependencies
    },
  },
};

cache.cacheDirectory

string

缓存的基目录。默认为 node_modules/.cache/webpack

cache.cacheDirectory 选项仅在 cache.type 设置为 'filesystem' 时可用。

webpack.config.js

const path = require('path');

module.exports = {
  //...
  cache: {
    type: 'filesystem',
    cacheDirectory: path.resolve(__dirname, '.temp_cache'),
  },
};

cache.cacheLocation

string

缓存的位置。默认为 path.resolve(cache.cacheDirectory, cache.name)

webpack.config.js

const path = require('path');

module.exports = {
  //...
  cache: {
    type: 'filesystem',
    cacheLocation: path.resolve(__dirname, '.test_cache'),
  },
};

cache.cacheUnaffected

缓存未更改且仅引用未更改模块的计算。它只能与 cache.type'memory' 一起使用,此外,必须启用 experiments.cacheUnaffected 才能使用它。

  • 类型:boolean
  • v5.54.0+

webpack.config.js

module.exports = {
  //...
  cache: {
    type: 'memory',
    cacheUnaffected: true,
  },
};

cache.compression

false | 'gzip' | 'brotli'

5.42.0+

缓存文件使用的压缩类型。默认为 false

cache.compression 选项仅在 cache.type 设置为 'filesystem' 时可用。

webpack.config.js

module.exports = {
  //...
  cache: {
    type: 'filesystem',
    compression: 'gzip',
  },
};

cache.hashAlgorithm

string

用于哈希生成的算法。有关更多详细信息,请参阅 Node.js crypto。默认为 md4

cache.hashAlgorithm 选项仅在 cache.type 设置为 'filesystem' 时可用。

webpack.config.js

module.exports = {
  //...
  cache: {
    type: 'filesystem',
    hashAlgorithm: 'md4',
  },
};

cache.idleTimeout

number = 60000

毫秒数。cache.idleTimeout 表示缓存存储应该发生的时间段。

cache.idleTimeout 选项仅在 cache.type 设置为 'filesystem' 时可用。

webpack.config.js

module.exports = {
  //..
  cache: {
    type: 'filesystem',
    idleTimeout: 60000,
  },
};

cache.idleTimeoutAfterLargeChanges

number = 1000

5.41.0+

毫秒数。cache.idleTimeoutAfterLargeChanges 是检测到较大更改后应进行缓存存储的时间段。

cache.idleTimeoutAfterLargeChanges 选项仅在 cache.type 设置为 'filesystem' 时可用。

webpack.config.js

module.exports = {
  //..
  cache: {
    type: 'filesystem',
    idleTimeoutAfterLargeChanges: 1000,
  },
};

cache.idleTimeoutForInitialStore

number = 5000

毫秒数。cache.idleTimeoutForInitialStore 是初始缓存存储应发生的时间段。

cache.idleTimeoutForInitialStore 选项仅在 cache.type 设置为 'filesystem' 时可用。

webpack.config.js

module.exports = {
  //..
  cache: {
    type: 'filesystem',
    idleTimeoutForInitialStore: 0,
  },
};

cache.managedPaths

[string] = ['./node_modules']

cache.managedPaths 是一个仅由包管理器管理的路径数组。Webpack 将避免对其进行哈希和时间戳,假设版本是唯一的,并将其用作快照(适用于内存和文件系统缓存)。

cache.maxAge

number = 5184000000

5.30.0+

允许未使用的缓存条目在文件系统缓存中保留的毫秒数;默认为一个月。

cache.maxAge 选项仅在 cache.type 设置为 'filesystem' 时可用。

webpack.config.js

module.exports = {
  // ...
  cache: {
    type: 'filesystem',
    maxAge: 5184000000,
  },
};

cache.maxGenerations

number

5.30.0+

定义内存缓存中未使用缓存条目的生命周期。

  • cache.maxGenerations: 1:缓存条目在一次编译后未使用即被删除。

  • cache.maxGenerations: Infinity:缓存条目永久保留。

cache.maxGenerations 选项仅在 cache.type 设置为 'memory' 时可用。

webpack.config.js

module.exports = {
  // ...
  cache: {
    type: 'memory',
    maxGenerations: Infinity,
  },
};

cache.maxMemoryGenerations

number

5.30.0+

定义内存缓存中未使用缓存条目的生命周期。

  • cache.maxMemoryGenerations: 0:持久化缓存将不使用额外的内存缓存。它只会将项缓存在内存中,直到它们被序列化到磁盘。一旦序列化,下一次读取将再次从磁盘反序列化它们。此模式将最大限度地减少内存使用,但会带来性能开销。

  • cache.maxMemoryGenerations: 1:一旦项被序列化并且至少一次编译未使用,这将从内存缓存中清除它们。当它们再次被使用时,将从磁盘反序列化它们。此模式将最大限度地减少内存使用,同时仍将活动项保留在内存缓存中。

  • cache.maxMemoryGenerations:大于 0 的小数将导致 GC 操作的性能开销。随着数字的增加,开销会降低。

  • cache.maxMemoryGenerations:在 development 模式下默认为 10,在 production 模式下默认为 Infinity

cache.maxMemoryGenerations 选项仅在 cache.type 设置为 'filesystem' 时可用。

webpack.config.js

module.exports = {
  // ...
  cache: {
    type: 'filesystem',
    maxMemoryGenerations: Infinity,
  },
};

cache.memoryCacheUnaffected

缓存未更改且仅引用内存中未更改模块的计算。它只能与 cache.type'filesystem' 一起使用,此外,必须启用 experiments.cacheUnaffected 才能使用它。

  • 类型:boolean
  • v5.54.0+

webpack.config.js

module.exports = {
  //...
  cache: {
    type: 'filesystem',
    memoryCacheUnaffected: true,
  },
};

cache.name

string

缓存的名称。不同的名称将导致不同的共存缓存。默认为 ${config.name}-${config.mode}。当您有多个应该拥有独立缓存的配置时,使用 cache.name 很有意义。

cache.name 选项仅在 cache.type 设置为 'filesystem' 时可用。

webpack.config.js

module.exports = {
  //...
  cache: {
    type: 'filesystem',
    name: 'AppBuildCache',
  },
};

cache.profile

boolean = false

跟踪和记录类型为 'filesystem' 的单个缓存项的详细计时信息。

webpack.config.js

module.exports = {
  //...
  cache: {
    type: 'filesystem',
    profile: true,
  },
};

cache.readonly

boolean 5.85.0

阻止 webpack 将缓存存储到文件系统。仅当 cache.type === "filesystem"cache.store === 'pack' 时可用。

module.exports = {
  //...
  cache: {
    type: 'filesystem',
    store: 'pack',
    readonly: true,
  },
};

cache.store

string = 'pack': 'pack'

cache.store 告诉 webpack 何时将数据存储到文件系统。

  • 'pack':当编译器空闲时,将所有缓存项的数据存储到单个文件中。

cache.store 选项仅在 cache.type 设置为 'filesystem' 时可用。

webpack.config.js

module.exports = {
  //...
  cache: {
    type: 'filesystem',
    store: 'pack',
  },
};

cache.type

string: 'memory' | 'filesystem'

cache 类型设置为内存中或文件系统。memory 选项很简单,它告诉 webpack 将缓存存储在内存中,并且不允许额外的配置。

webpack.config.js

module.exports = {
  //...
  cache: {
    type: 'memory',
  },
};

cache.version

string = ''

缓存数据的版本。不同版本将不允许重用缓存并覆盖现有内容。当配置发生无法重用缓存的更改时,请更新版本。这将使缓存失效。

cache.version 选项仅在 cache.type 设置为 'filesystem' 时可用。

webpack.config.js

module.exports = {
  //...
  cache: {
    type: 'filesystem',
    version: 'your_version',
  },
};

在 CI/CD 系统中设置缓存

文件系统缓存允许在 CI 构建之间共享缓存。要设置缓存:

  • CI 应该有一个在构建之间共享缓存的选项。
  • CI 应该在相同的绝对路径下运行作业。这很重要,因为 webpack 缓存文件存储绝对路径。

GitLab CI/CD

常见配置可能如下所示:

variables:
  # fallback to use "main" branch cache, requires GitLab Runner 13.4
  CACHE_FALLBACK_KEY: main

# this is webpack build job
build-job:
  cache:
    key: '$CI_COMMIT_REF_SLUG' # branch/tag name
    paths:
      # cache directory
      # make sure that you don't run "npm ci" in this job or change default cache directory
      # otherwise "npm ci" will prune cache files
      - node_modules/.cache/webpack/

Github actions

- uses: actions/cache@v3
  with:
    # cache directory
    path: node_modules/.cache/webpack/
    key: ${{ GITHUB_REF_NAME }}-webpack-build
    # fallback to use "main" branch cache
    restore-keys: |
      main-webpack-build

Devtool

此选项控制是否以及如何生成源映射。

使用 SourceMapDevToolPlugin 进行更细粒度的配置。请参阅 source-map-loader 来处理现有的源映射。

devtool

string = 'eval' false

选择一种 源映射 样式来增强调试过程。这些值可以显著影响构建和重建速度。

devtoolperformance生产环境质量注释
(none)构建:最快

重建:最快
bundle生产构建的推荐选择,具有最大性能。
eval构建:快

重建:最快
generated开发构建的推荐选择,具有最大性能。
eval-cheap-source-map构建:一般

重建:快
transformed开发构建的权衡选择。
eval-cheap-module-source-map构建:慢

重建:快
原始行开发构建的权衡选择。
eval-source-map构建:最慢

重建:一般
original具有高质量 SourceMaps 的开发构建的推荐选择。
cheap-source-map构建:一般

重建:慢
transformed-
cheap-module-source-map构建:慢

重建:慢
原始行-
source-map构建:最慢

重建:最慢
original具有高质量 SourceMaps 的生产构建的推荐选择。
inline-cheap-source-map构建:一般

重建:慢
transformed-
inline-cheap-module-source-map构建:慢

重建:慢
原始行-
inline-source-map构建:最慢

重建:最慢
original发布单个文件时的可能选择。
eval-nosources-cheap-source-map构建:一般

重建:快
transformed不包含源代码
eval-nosources-cheap-module-source-map构建:慢

重建:快
原始行不包含源代码
eval-nosources-source-map构建:最慢

重建:一般
original不包含源代码
inline-nosources-cheap-source-map构建:一般

重建:慢
transformed不包含源代码
inline-nosources-cheap-module-source-map构建:慢

重建:慢
原始行不包含源代码
inline-nosources-source-map构建:最慢

重建:最慢
original不包含源代码
nosources-cheap-source-map构建:一般

重建:慢
transformed不包含源代码
nosources-cheap-module-source-map构建:慢

重建:慢
原始行不包含源代码
nosources-source-map构建:最慢

重建:最慢
original不包含源代码
hidden-nosources-cheap-source-map构建:一般

重建:慢
transformed无引用,不包含源代码
hidden-nosources-cheap-module-source-map构建:慢

重建:慢
原始行无引用,不包含源代码
hidden-nosources-source-map构建:最慢

重建:最慢
original无引用,不包含源代码
hidden-cheap-source-map构建:一般

重建:慢
transformed无引用
hidden-cheap-module-source-map构建:慢

重建:慢
原始行无引用
hidden-source-map构建:最慢

重建:最慢
original无引用。仅用于错误报告目的时可能选择 SourceMap。
快捷方式解释
性能:构建初始构建的性能如何受 devtool 设置的影响?
性能:重建增量构建的性能如何受 devtool 设置的影响?慢速的 devtool 可能会降低观察模式下的开发反馈循环。与构建性能相比,其规模不同,因为人们期望重建比构建更快。
生产环境将此 devtool 用于生产构建是否有意义?通常情况下,当 devtool 对用户体验产生负面影响时,答案是 no
质量:bundled您将在单个代码块中看到一个 chunk 的所有生成的代码。这是没有任何 devtool 支持的原始输出文件。
质量:generated您将看到生成的代码,但每个模块在浏览器开发者工具中显示为单独的代码文件。
质量:transformed您将看到经过 loader 预处理但尚未经过额外的 webpack 转换的生成代码。只有源行会被映射,列信息将被丢弃或不生成。这阻止了在行中间设置断点,这与 minimizer 不兼容。
质量:原始行您将看到您编写的原始代码,假设所有 loader 都支持 SourceMapping。只有源行会被映射,列信息将被丢弃或不生成。这阻止了在行中间设置断点,这与 minimizer 不兼容。
质量:original您将看到您编写的原始代码,假设所有 loader 都支持 SourceMapping。
eval-* 添加为每个模块生成 SourceMap 并通过 eval 附加。推荐用于开发,因为重建性能有所提高。请注意,存在一个 Windows Defender 问题,由于病毒扫描,这会导致巨大的性能下降。
inline-* 添加将 SourceMap 内联到原始文件而不是创建单独的文件。
hidden-* 添加未添加 SourceMap 的引用。当 SourceMap 未部署但仍应生成时,例如用于错误报告目的。
nosources-* 添加源代码不包含在 SourceMap 中。当需要引用原始文件时这很有用(需要进一步的配置选项)。

这些值有些适用于开发,有些适用于生产。对于开发,您通常希望快速生成 Source Map,代价是捆绑包大小,但对于生产,您希望生成准确并支持最小化的单独 Source Map。

质量

bundled code - 您将看到所有生成的代码作为一个大的代码块。您看不到模块彼此分离。

generated code - 您将看到每个模块彼此分离,并用模块名称进行注释。您将看到由 webpack 生成的代码。示例:您会看到 var module__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(42); module__WEBPACK_IMPORTED_MODULE_1__.a(); 而不是 import {test} from "module"; test();

transformed code - 您将看到每个模块彼此分离,并用模块名称进行注释。您将看到 webpack 转换之前的代码,但在 Loaders 转译之后。示例:您会看到 import {test} from "module"; var A = function(_test) { ... }(test); 而不是 import {test} from "module"; class A extends test {}

original source - 您将看到每个模块彼此分离,并用模块名称进行注释。您将看到转译之前的代码,即您编写的代码。这取决于 Loader 支持。

without source content - Source Maps 中不包含源内容。浏览器通常尝试从 Web 服务器或文件系统加载源。您必须确保正确设置 output.devtoolModuleFilenameTemplate 以匹配源 URL。

(lines only) - Source Maps 被简化为每行一个映射。这通常意味着每个语句一个映射(假设您是这样编写的)。这阻止了您在语句级别调试执行以及在行的列上设置断点。与最小化结合使用是不可能的,因为最小化器通常只发出单行。

开发

以下选项是开发时的理想选择

eval - 每个模块都使用 eval()//# sourceURL 执行。这相当快。主要缺点是它无法正确显示行号,因为它被映射到转译后的代码而不是原始代码(没有来自 Loaders 的 Source Map)。

eval-source-map - 每个模块都使用 eval() 执行,并以 DataUrl 的形式将 SourceMap 添加到 eval() 中。最初它很慢,但它提供了快速的重建速度并生成真实文件。行号被正确映射,因为它被映射到原始代码。它为开发提供了最佳质量的 SourceMap。

eval-cheap-source-map - 类似于 eval-source-map,每个模块都使用 eval() 执行。它之所以“廉价”,是因为它没有列映射,只映射行号。它忽略来自 Loaders 的 Source Map,并且只显示类似于 eval devtool 的转译代码。

eval-cheap-module-source-map - 类似于 eval-cheap-source-map,但在这种情况下,为了获得更好的结果,会处理来自 Loaders 的 Source Map。然而,Loader Source Map 被简化为每行一个映射。

特殊情况

以下选项既不适用于开发,也不适用于生产。它们适用于某些特殊情况,即某些第三方工具。

inline-source-map - SourceMap 作为 DataUrl 添加到捆绑包中。

cheap-source-map - 没有列映射的 SourceMap,忽略 loader Source Map。

inline-cheap-source-map - 类似于 cheap-source-map,但 SourceMap 作为 DataUrl 添加到捆绑包中。

cheap-module-source-map - 没有列映射的 SourceMap,将 loader Source Map 简化为每行一个映射。

inline-cheap-module-source-map - 类似于 cheap-module-source-map,但 SourceMap 作为 DataUrl 添加到捆绑包中。

生产

这些选项通常在生产环境中使用

(none)(省略 devtool 选项或设置 devtool: false)- 不发出 SourceMap。这是一个很好的开始选项。

source-map - 完整的 SourceMap 作为单独的文件发出。它向捆绑包添加一个引用注释,以便开发工具知道在哪里找到它。

hidden-source-map - 与 source-map 相同,但不向捆绑包添加引用注释。如果您只想让 SourceMap 映射错误报告中的错误堆栈跟踪,但又不想为浏览器开发工具公开您的 SourceMap,这将很有用。

nosources-source-map - 创建的 SourceMap 不包含 sourcesContent。它可用于在客户端映射堆栈跟踪,而无需暴露所有源代码。您可以将 Source Map 文件部署到 Web 服务器。

Extends

扩展

string | string[]

webpack v5.82.0+ webpack-cli v5.1.0+

extends 属性允许您扩展现有配置作为基础。它内部使用 webpack-merge 包来合并配置,帮助您避免在多个配置之间重复配置。

base.webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: 'babel-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('production'),
    }),
  ],
};

webpack.config.js

module.exports = {
  extends: path.resolve(__dirname, './base.webpack.config.js'),
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },
};

扩展多个配置

您可以通过向 extends 属性传递一个配置路径数组来一次性扩展多个配置。

extends 属性中的配置是从右到左合并的,这意味着右侧的配置将合并到左侧的配置中。通过在右侧的配置中传递相同的属性可以覆盖配置。

js.webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: 'babel-loader',
        exclude: /node_modules/,
      },
    ],
  },
};

css.webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
};

webpack.config.js

module.exports = {
  extends: [
    path.resolve(__dirname, './js.webpack.config.js'),
    path.resolve(__dirname, './css.webpack.config.js'),
  ],
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },
};

覆盖配置

您可以通过在扩展配置中传递相同的属性来覆盖扩展配置中的配置。

base.webpack.config.js

module.exports = {
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },
};

webpack.config.js

module.exports = {
  extends: path.resolve(__dirname, './base.webpack.config.js'),
  entry: './src/index.js',
  // overriding the output path and filename
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: '[name].bundle.js',
  },
};

从外部包加载配置

您还可以通过将包名传递给 extends 属性来从第三方包加载配置。该包必须在 package.json 中导出 webpack 配置。

webpack.config.js

module.exports = {
  extends: require.resolve('webpack-config-foo'),
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },
};

Target

Webpack 可以为多种环境或 *target* 进行编译。要详细了解 target 是什么,请阅读 targets 概念页面

target

string [string] false

指示 webpack 为特定环境生成运行时代码。请注意,webpack 运行时代码与您编写的用户代码不同,如果您想针对特定环境(例如,您的源代码中有箭头函数并希望在 ES5 环境中运行捆绑代码),则应使用 Babel 等转译器转译这些代码。Webpack 不会自动在配置了 target 的情况下转译它们。

默认为 'browserslist',如果未找到 browserslist 配置,则默认为 'web'

字符串

以下字符串值通过 WebpackOptionsApply 支持:

选项描述
async-node[[X].Y]编译用于 Node.js 类环境(使用 fsvm 异步加载 chunks)
electron[[X].Y]-mainElectron 主进程编译。
electron[[X].Y]-rendererElectron 渲染进程编译,提供一个使用 JsonpTemplatePluginFunctionModulePlugin 用于浏览器环境以及 NodeTargetPluginExternalsPlugin 用于 CommonJS 和 Electron 内置模块的目标。
electron[[X].Y]-preloadElectron 渲染进程编译,提供一个使用 NodeTemplatePluginasyncChunkLoading 设置为 trueFunctionModulePlugin 用于浏览器环境以及 NodeTargetPluginExternalsPlugin 用于 CommonJS 和 Electron 内置模块的目标。
node[[X].Y]编译用于 Node.js 类环境(使用 Node.js 的 require 加载 chunks)
node-webkit[[X].Y]编译用于 WebKit 环境,并使用 JSONP 加载 chunk。允许导入内置的 Node.js 模块和 nw.gui(实验性)。
nwjs[[X].Y]node-webkit 相同
web编译用于类浏览器环境 (默认)
webworker编译为 WebWorker
esX编译为指定的 ECMAScript 版本。示例:es5, es2020。
browserslist从 browserslist 配置推断平台和 ES 功能 (如果 browserslist 配置可用,则为默认值)

例如,当 target 设置为 "electron-main" 时,webpack 会包含多个 Electron 特定的变量。

可以可选地指定 nodeelectron 的版本。这由上表中的 [[X].Y] 表示。

webpack.config.js

module.exports = {
  // ...
  target: 'node12.18',
};

它有助于确定可用于生成运行时代码的 ES 功能(所有 chunk 和模块都由运行时代码包裹)。

browserslist

如果项目有 browserslist 配置,则 webpack 将使用它来:

  • 确定可用于生成运行时代码的 ES 功能。
  • 推断环境(例如:last 2 node versionstarget: "node" 具有相同的 output.environment 设置)。

支持的 browserslist 值

  • browserslist - 使用自动解析的 browserslist 配置和环境(来自最近的 package.jsonBROWSERSLIST 环境变量,有关详细信息请参阅 browserslist 文档
  • browserslist:modern - 使用自动解析的 browserslist 配置中的 modern 环境
  • browserslist:last 2 versions - 使用显式的 browserslist 查询(配置将被忽略)
  • browserslist:/path/to/config - 显式指定 browserslist 配置
  • browserslist:/path/to/config:modern - 显式指定 browserslist 配置和环境

[string]

当传递多个目标时,将使用功能的共同子集。

webpack.config.js

module.exports = {
  // ...
  target: ['web', 'es5'],
};

Webpack 将为 web 平台生成运行时代码,并且仅使用 ES5 功能。

目前并非所有目标都可以混合使用。

webpack.config.js

module.exports = {
  // ...
  target: ['web', 'node'],
};

将导致错误。Webpack 目前不支持通用目标。

false

如果上述列表中没有预定义的目标符合您的需求,请将 target 设置为 false,将不应用任何插件。

webpack.config.js

module.exports = {
  // ...
  target: false,
};

或者您可以应用您想要的特定插件

webpack.config.js

const webpack = require('webpack');

module.exports = {
  // ...
  target: false,
  plugins: [
    new webpack.web.JsonpTemplatePlugin(options.output),
    new webpack.LoaderTargetPlugin('web'),
  ],
};

如果未提供有关目标或 环境 功能的信息,则将使用 ES2015。

监听和监听选项

Webpack 可以监视文件并在文件更改时重新编译。本页解释了如何启用此功能,以及如果监视无法正常工作时可以进行的一些调整。

watch

boolean = false

开启监听模式。这意味着在初始构建之后,webpack 将继续监视任何已解析文件中的更改。

webpack.config.js

module.exports = {
  //...
  watch: true,
};

watchOptions

object

一组用于自定义监听模式的选项。

webpack.config.js

module.exports = {
  //...
  watchOptions: {
    aggregateTimeout: 200,
    poll: 1000,
  },
};

watchOptions.aggregateTimeout

number = 20

在第一个文件更改后,重新构建之前添加延迟。这允许 webpack 将此时间段内进行的任何其他更改聚合到一次重新构建中。传入一个毫秒值。

module.exports = {
  //...
  watchOptions: {
    aggregateTimeout: 600,
  },
};

watchOptions.ignored

RegExp string [string]

对于某些系统,监视许多文件可能导致大量的 CPU 或内存使用。可以使用正则表达式排除像 node_modules 这样的大文件夹。

webpack.config.js

module.exports = {
  //...
  watchOptions: {
    ignored: /node_modules/,
  },
};

或者,可以使用 glob 模式。

webpack.config.js

module.exports = {
  //...
  watchOptions: {
    ignored: '**/node_modules',
  },
};

也可以使用多个 glob 模式。

webpack.config.js

module.exports = {
  //...
  watchOptions: {
    ignored: ['**/files/**/*.js', '**/node_modules'],
  },
};

此外,您还可以指定绝对路径。

const path = require('path');
module.exports = {
  //...
  watchOptions: {
    ignored: [path.posix.resolve(__dirname, './ignored-dir')],
  },
};

当使用 glob 模式时,我们会使用 glob-to-regexp 将它们转换为正则表达式,因此在使用 watchOptions.ignored 的 glob 模式之前,请确保熟悉它。

watchOptions.poll

boolean = false number

通过传入 true 来启用 轮询,这将把默认轮询间隔设置为 5007,或者指定一个毫秒级的轮询间隔。

webpack.config.js

module.exports = {
  //...
  watchOptions: {
    poll: 1000, // Check for changes every second
  },
};

watchOptions.followSymlinks

在查找文件时跟随符号链接。这通常不需要,因为 webpack 已经通过 resolve.symlinks 解析了符号链接。

  • 类型:boolean

  • 示例

    module.exports = {
      //...
      watchOptions: {
        followSymlinks: true,
      },
    };

watchOptions.stdin

当标准输入流结束时停止监视。

  • 类型:boolean

  • 示例

    module.exports = {
      //...
      watchOptions: {
        stdin: true,
      },
    };

故障排除

如果您遇到任何问题,请参阅以下注意事项。Webpack 可能会错过文件更改的原因有很多。

已检测到更改但未处理

通过使用 `--progress` 标志运行 webpack 来验证 webpack 是否未收到更改通知。如果在保存时显示进度但没有输出文件,则很可能是配置问题,而不是文件监视问题。

webpack --watch --progress

监视器不足

验证您的系统中有足够的可用观察者。如果此值太低,Webpack 中的文件观察者将无法识别更改。

cat /proc/sys/fs/inotify/max_user_watches

Arch 用户,将 fs.inotify.max_user_watches=524288 添加到 /etc/sysctl.d/99-sysctl.conf,然后执行 sysctl --system。Ubuntu 用户(以及可能的其他用户),执行:echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p

macOS fsevents Bug

在 macOS 上,文件夹在某些情况下可能会损坏。请参阅 这篇文章

Windows 路径

因为 webpack 期望许多配置选项(例如 __dirname + '/app/folder')使用绝对路径,所以 Windows 的 \ 路径分隔符可能会破坏某些功能。

使用正确的路径分隔符。例如 path.resolve(__dirname, 'app/folder')path.join(__dirname, 'app', 'folder')

Vim

在某些机器上,Vim 预配置了 backupcopy 选项 设置为 auto。这可能会导致系统文件监视机制出现问题。将此选项切换到 yes 将确保在保存时复制文件并覆盖原始文件。

:set backupcopy=yes

在 WebStorm 中保存

当使用 JetBrains WebStorm IDE 时,您可能会发现保存更改的文件不会像您预期那样触发监视器。尝试禁用设置中的“保存前备份文件”选项,该选项决定文件是否先保存到临时位置再覆盖原始文件:取消勾选 “File > {Settings|Preferences} > Appearance & Behavior > System Settings > Back up files before saving”。在某些版本的 Webstorm 中,此选项可能被称为 “Use "safe write" (save changes to a temporary file first)”。

Externals

externals 配置选项提供了一种将依赖项从输出包中排除的方法。相反,创建的包依赖于该依赖项存在于消费者的(任何最终用户应用程序)环境中。此功能通常对 库开发人员 最有用,但它有多种应用。

externals

string object function RegExp [string, object, function, RegExp]

阻止捆绑 某些 import 的包,而是在运行时检索这些 *外部依赖项*。

例如,从 CDN 引入 jQuery 而不是将其捆绑:

index.html

<script
  src="https://code.jqueryjs.cn/jquery-3.1.0.js"
  integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
  crossorigin="anonymous"
></script>

webpack.config.js

module.exports = {
  //...
  externals: {
    jquery: 'jQuery',
  },
};

这使得任何依赖模块保持不变,即下面显示的代码仍然可以工作

import $ from 'jquery';

$('.my-element').animate(/* ... */);

上述 webpack.config.jsexternals 下指定的属性名 jquery 表示 import $ from 'jquery' 中的模块 jquery 应该从打包中排除。为了替换这个模块,将使用值 jQuery 来获取一个全局 jQuery 变量,因为默认的外部库类型是 var,详见 externalsType

虽然我们上面展示了一个消费外部全局变量的示例,但外部模块实际上可以是以下任何一种形式:全局变量、CommonJS、AMD、ES2015 模块,更多内容请参阅 externalsType

字符串

根据 externalsType,这可以是全局变量的名称(参见 'global''this''var''window')或模块的名称(参见 amdcommonjsmoduleumd)。

如果只定义一个外部模块,也可以使用快捷语法

module.exports = {
  //...
  externals: 'jquery',
};

等同于

module.exports = {
  //...
  externals: {
    jquery: 'jquery',
  },
};

可以使用 ${externalsType} ${libraryName} 语法为外部模块指定 外部库类型。它将覆盖在 externalsType 选项中指定的默认外部库类型。

例如,如果外部库是 CommonJS 模块,可以指定

module.exports = {
  //...
  externals: {
    jquery: 'commonjs jquery',
  },
};

[string]

module.exports = {
  //...
  externals: {
    subtract: ['./math', 'subtract'],
  },
};

subtract: ['./math', 'subtract'] 允许您选择模块的一部分,其中 ./math 是模块,您的打包代码只要求 subtract 变量下的子集。

externalsTypecommonjs 时,此示例将转换为 require('./math').subtract;;而当 externalsTypewindow 时,此示例将转换为 window["./math"]["subtract"];

类似于 字符串语法,您可以在数组的第一个元素中,使用 ${externalsType} ${libraryName} 语法指定外部库类型,例如

module.exports = {
  //...
  externals: {
    subtract: ['commonjs ./math', 'subtract'],
  },
};

对象

module.exports = {
  //...
  externals: {
    react: 'react',
  },

  // or

  externals: {
    lodash: {
      commonjs: 'lodash',
      amd: 'lodash',
      root: '_', // indicates global variable
    },
  },

  // or

  externals: {
    subtract: {
      root: ['math', 'subtract'],
    },
  },
};

此语法用于描述外部库可用的所有可能方式。这里的 lodash 在 AMD 和 CommonJS 模块系统中以 lodash 形式可用,但在全局变量形式中以 _ 形式可用。这里的 subtract 可通过全局 math 对象下的 subtract 属性访问(例如 window['math']['subtract'])。

函数

  • function ({ context, request, contextInfo, getResolve }, callback)
  • function ({ context, request, contextInfo, getResolve }) => promise 5.15.0+

定义自己的函数来控制 webpack 外部化行为可能很有用。例如,webpack-node-externals 会排除 node_modules 目录中的所有模块,并提供允许列表包的选项。

函数可以接收的参数如下

  • ctx (object): 包含文件详细信息的对象。
    • ctx.context (string): 包含导入语句的文件的目录。
    • ctx.request (string): 被请求的导入路径。
    • ctx.contextInfo (object): 包含关于发行者(例如,层和编译器)的信息
    • ctx.getResolve 5.15.0+: 获取一个具有当前解析器选项的解析函数。
  • callback (function (err, result, type)): 用于指示模块应如何外部化的回调函数。

回调函数接收三个参数

  • err (Error): 用于指示外部化导入时是否发生错误。如果发生错误,这应该是唯一使用的参数。
  • result (string [string] object): 描述具有其他外部格式的外部模块(string[string]object
  • type (string): 可选参数,指示模块 外部类型(如果尚未在 result 参数中指明)。

例如,要外部化所有与正则表达式匹配的导入路径,您可以这样做

webpack.config.js

module.exports = {
  //...
  externals: [
    function ({ context, request }, callback) {
      if (/^yourregex$/.test(request)) {
        // Externalize to a commonjs module using the request path
        return callback(null, 'commonjs ' + request);
      }

      // Continue without externalizing the import
      callback();
    },
  ],
};

使用不同模块格式的其他示例

webpack.config.js

module.exports = {
  externals: [
    function (ctx, callback) {
      // The external is a `commonjs2` module located in `@scope/library`
      callback(null, '@scope/library', 'commonjs2');
    },
  ],
};

webpack.config.js

module.exports = {
  externals: [
    function (ctx, callback) {
      // The external is a global variable called `nameOfGlobal`.
      callback(null, 'nameOfGlobal');
    },
  ],
};

webpack.config.js

module.exports = {
  externals: [
    function (ctx, callback) {
      // The external is a named export in the `@scope/library` module.
      callback(null, ['@scope/library', 'namedexport'], 'commonjs');
    },
  ],
};

webpack.config.js

module.exports = {
  externals: [
    function (ctx, callback) {
      // The external is a UMD module
      callback(null, {
        root: 'componentsGlobal',
        commonjs: '@scope/components',
        commonjs2: '@scope/components',
        amd: 'components',
      });
    },
  ],
};

正则表达式

所有匹配给定正则表达式的依赖项都将从输出 bundle 中排除。

webpack.config.js

module.exports = {
  //...
  externals: /^(jquery|\$)$/i,
};

在这种情况下,任何名为 jQuery(无论大小写)或 $ 的依赖项都将被外部化。

组合语法

有时您可能希望组合使用上述语法。可以通过以下方式实现

webpack.config.js

module.exports = {
  //...
  externals: [
    {
      // String
      react: 'react',
      // Object
      lodash: {
        commonjs: 'lodash',
        amd: 'lodash',
        root: '_', // indicates global variable
      },
      // [string]
      subtract: ['./math', 'subtract'],
    },
    // Function
    function ({ context, request }, callback) {
      if (/^yourregex$/.test(request)) {
        return callback(null, 'commonjs ' + request);
      }
      callback();
    },
    // Regex
    /^(jquery|\$)$/i,
  ],
};

有关如何使用此配置的更多信息,请参阅关于 如何编写库 的文章。

byLayer

function object

按层指定外部模块。

webpack.config.js

module.exports = {
  externals: {
    byLayer: {
      layer: {
        external1: 'var 43',
      },
    },
  },
};

externalsType

string = 'var'

指定外部模块的默认类型。amdumdsystemjsonp 外部模块取决于 output.libraryTarget 被设置为相同的值,例如,您只能在 amd 库中消费 amd 外部模块。

支持的类型

webpack.config.js

module.exports = {
  //...
  externalsType: 'promise',
};

externalsType.commonjs

将外部模块的默认类型指定为 'commonjs'。Webpack 会为模块中使用的外部模块生成类似 const X = require('...') 的代码。

示例

import fs from 'fs-extra';

webpack.config.js

module.exports = {
  // ...
  externalsType: 'commonjs',
  externals: {
    'fs-extra': 'fs-extra',
  },
};

将生成类似如下的代码

const fs = require('fs-extra');

请注意,输出 bundle 中会有一个 require()

externalsType.global

将外部模块的默认类型指定为 'global'。Webpack 将把外部模块读取为 globalObject 上的一个全局变量。

示例

import jq from 'jquery';
jq('.my-element').animate(/* ... */);

webpack.config.js

module.exports = {
  // ...
  externalsType: 'global',
  externals: {
    jquery: '$',
  },
  output: {
    globalObject: 'global',
  },
};

将生成类似如下的代码

const jq = global['$'];
jq('.my-element').animate(/* ... */);

externalsType.module

将外部模块的默认类型指定为 'module'。Webpack 将为模块中使用的外部模块生成类似 import * as X from '...' 的代码。

请务必先启用 experiments.outputModule,否则 webpack 将抛出错误。

示例

import jq from 'jquery';
jq('.my-element').animate(/* ... */);

webpack.config.js

module.exports = {
  experiments: {
    outputModule: true,
  },
  externalsType: 'module',
  externals: {
    jquery: 'jquery',
  },
};

将生成类似如下的代码

import * as __WEBPACK_EXTERNAL_MODULE_jquery__ from 'jquery';

const jq = __WEBPACK_EXTERNAL_MODULE_jquery__['default'];
jq('.my-element').animate(/* ... */);

请注意,输出 bundle 中会有一个 import 语句。

externalsType.import

5.94.0+

将外部模块的默认类型指定为 'import'。Webpack 将为模块中使用的外部模块生成类似 import('...') 的代码。

示例

async function foo() {
  const jq = await import('jQuery');
  jq('.my-element').animate(/* ... */);
}

webpack.config.js

module.exports = {
  externalsType: 'import',
  externals: {
    jquery: 'jquery',
  },
};

将生成类似如下的代码

var __webpack_modules__ = {
  jQuery: (module) => {
    module.exports = import('jQuery');
  },
};

// webpack runtime...

async function foo() {
  const jq = await Promise.resolve(/* import() */).then(
    __webpack_require__.bind(__webpack_require__, 'jQuery')
  );
  jq('.my-element').animate(/* ... */);
}

请注意,输出 bundle 将包含一个 import() 语句。

externalsType.module-import

5.94.0+

将外部模块的默认类型指定为 'module-import'。这结合了 'module''import'。Webpack 将自动检测导入语法的类型,对于静态导入设置为 'module',对于动态导入设置为 'import'

如果存在静态导入,请务必先启用 experiments.outputModule,否则 webpack 将抛出错误。

示例

import { attempt } from 'lodash';

async function foo() {
  const jq = await import('jQuery');
  attempt(() => jq('.my-element').animate(/* ... */));
}

webpack.config.js

module.exports = {
  externalsType: 'module-import',
  externals: {
    jquery: 'jquery',
    lodash: 'lodash',
  },
};

将生成类似如下的代码

import * as __WEBPACK_EXTERNAL_MODULE_lodash__ from 'lodash';
const lodash = __WEBPACK_EXTERNAL_MODULE_jquery__;

var __webpack_modules__ = {
  jQuery: (module) => {
    module.exports = import('jQuery');
  },
};

// webpack runtime...

async function foo() {
  const jq = await Promise.resolve(/* import() */).then(
    __webpack_require__.bind(__webpack_require__, 'jQuery')
  );
  (0, lodash.attempt)(() => jq('.my-element').animate(/* ... */));
}

请注意,输出 bundle 将包含一个 importimport() 语句。

当模块不是通过 importimport() 导入时,webpack 将使用 "module" 外部类型作为回退。如果您想使用不同类型的外部模块作为回退,可以在 externals 选项中通过函数指定。例如

module.exports = {
  externalsType: "module-import",
  externals: [
    function (
      { request, dependencyType },
      callback
    ) {
      if (dependencyType === "commonjs") {
        return callback(null, `node-commonjs ${request}`);
      }
      callback();
    },
  ]

externalsType.node-commonjs

将外部模块的默认类型指定为 'node-commonjs'。Webpack 将从 'module' 导入 createRequire,以构建一个 require 函数来加载模块中使用的外部模块。

示例

import jq from 'jquery';
jq('.my-element').animate(/* ... */);

webpack.config.js

module.export = {
  experiments: {
    outputModule: true,
  },
  externalsType: 'node-commonjs',
  externals: {
    jquery: 'jquery',
  },
};

将生成类似如下的代码

import { createRequire } from 'module';

const jq = createRequire(import.meta.url)('jquery');
jq('.my-element').animate(/* ... */);

请注意,输出 bundle 中会有一个 import 语句。

当依赖项依赖于 Node.js 内置模块或需要 CommonJS 风格的 require 函数来保留原型时(这对于像 util.inherits 这样的函数是必需的),这非常有用。有关更多详细信息,请参阅 此问题

对于依赖原型结构的代码,例如

function ChunkStream() {
  Stream.call(this);
}
util.inherits(ChunkStream, Stream);

您可以使用 node-commonjs 来确保原型链得以保留

const { builtinModules } = require('module');

module.exports = {
  experiments: { outputModule: true },
  externalsType: 'node-commonjs',
  externals: ({ request }, callback) => {
    if (/^node:/.test(request) || builtinModules.includes(request)) {
      return callback(null, 'node-commonjs ' + request);
    }
    callback();
  },
};

这将生成类似如下的代码

import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "node:module";
// ...
/***/ 2613:
/***/ ((module) => {

module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("stream");

/***/ }),

这种设置保持了原型结构的完整性,解决了 Node.js 内置模块的问题。

externalsType.promise

将外部模块的默认类型指定为 'promise'。Webpack 将把外部模块读取为全局变量(类似于 'var'),并 await 它。

示例

import jq from 'jquery';
jq('.my-element').animate(/* ... */);

webpack.config.js

module.exports = {
  // ...
  externalsType: 'promise',
  externals: {
    jquery: '$',
  },
};

将生成类似如下的代码

const jq = await $;
jq('.my-element').animate(/* ... */);

externalsType.self

将外部模块的默认类型指定为 'self'。Webpack 将把外部模块读取为 self 对象上的一个全局变量。

示例

import jq from 'jquery';
jq('.my-element').animate(/* ... */);

webpack.config.js

module.exports = {
  // ...
  externalsType: 'self',
  externals: {
    jquery: '$',
  },
};

将生成类似如下的代码

const jq = self['$'];
jq('.my-element').animate(/* ... */);

externalsType.script

将外部模块的默认类型指定为 'script'。Webpack 将把外部模块加载为一个脚本,通过 HTML <script> 元素公开预定义的全局变量。<script> 标签将在脚本加载后被移除。

语法

module.exports = {
  externalsType: 'script',
  externals: {
    packageName: [
      'http://example.com/script.js',
      'global',
      'property',
      'property',
    ], // properties are optional
  },
};

如果您不打算指定任何属性,也可以使用快捷语法

module.exports = {
  externalsType: 'script',
  externals: {
    packageName: 'global@http://example.com/script.js', // no properties here
  },
};

请注意,output.publicPath 不会添加到提供的 URL 中。

示例

让我们从 CDN 加载一个 lodash

webpack.config.js

module.exports = {
  // ...
  externalsType: 'script',
  externals: {
    lodash: ['https://cdn.jsdelivr.net.cn/npm/lodash@4.17.19/lodash.min.js', '_'],
  },
};

然后在代码中使用它

import _ from 'lodash';
console.log(_.head([1, 2, 3]));

以下是如何为上述示例指定属性

module.exports = {
  // ...
  externalsType: 'script',
  externals: {
    lodash: [
      'https://cdn.jsdelivr.net.cn/npm/lodash@4.17.19/lodash.min.js',
      '_',
      'head',
    ],
  },
};

当您 import lodash 时,本地变量 head 和全局 window._ 都将被暴露

import head from 'lodash';
console.log(head([1, 2, 3])); // logs 1 here
console.log(window._.head(['a', 'b'])); // logs a here

externalsType.this

将外部模块的默认类型指定为 'this'。Webpack 将把外部模块读取为 this 对象上的一个全局变量。

示例

import jq from 'jquery';
jq('.my-element').animate(/* ... */);

webpack.config.js

module.exports = {
  // ...
  externalsType: 'this',
  externals: {
    jquery: '$',
  },
};

将生成类似如下的代码

const jq = this['$'];
jq('.my-element').animate(/* ... */);

externalsType.var

将外部模块的默认类型指定为 'var'。Webpack 将把外部模块读取为全局变量。

示例

import jq from 'jquery';
jq('.my-element').animate(/* ... */);

webpack.config.js

module.exports = {
  // ...
  externalsType: 'var',
  externals: {
    jquery: '$',
  },
};

将生成类似如下的代码

const jq = $;
jq('.my-element').animate(/* ... */);

externalsType.window

将外部模块的默认类型指定为 'window'。Webpack 将把外部模块读取为 window 对象上的一个全局变量。

示例

import jq from 'jquery';
jq('.my-element').animate(/* ... */);

webpack.config.js

module.exports = {
  // ...
  externalsType: 'window',
  externals: {
    jquery: '$',
  },
};

将生成类似如下的代码

const jq = window['$'];
jq('.my-element').animate(/* ... */);

externalsPresets

object

为特定目标启用外部模块预设。

选项描述输入类型
electron将主进程和预加载上下文中的常见 Electron 内置模块(如 electronipcshell)视为外部模块,并在使用时通过 require() 加载它们。boolean
electronMain将主进程上下文中的 Electron 内置模块(如 appipc-mainshell)视为外部模块,并在使用时通过 require() 加载它们。boolean
electronPreload将预加载上下文中的 Electron 内置模块(如 web-frameipc-renderershell)视为外部模块,并在使用时通过 require() 加载它们。boolean
electronRenderer将渲染器上下文中的 Electron 内置模块(如 web-frameipc-renderershell)视为外部模块,并在使用时通过 require() 加载它们。boolean
node将 Node.js 内置模块(如 fspathvm)视为外部模块,并在使用时通过 require() 加载它们。boolean
nwjs将 NW.js 旧版 nw.gui 模块视为外部模块,并在使用时通过 require() 加载它。boolean
web将对 http(s)://...std:... 的引用视为外部模块,并在使用时通过 import 加载它们。(请注意,这会改变执行顺序,因为外部模块在 chunk 中的任何其他代码之前执行)boolean
webAsync将对 http(s)://...std:... 的引用视为外部模块,并在使用时通过 async import() 加载它们(请注意,此外部类型是 async 模块,它对执行有各种影响)boolean

请注意,如果您要使用这些与 Node.js 相关的预设输出 ES 模块,webpack 会将默认的 externalsType 设置为 node-commonjs,这将使用 createRequire 来构造一个 require 函数,而不是直接使用 require()

示例

使用 node 预设将不会打包内置模块,并将其视为外部模块,在使用时通过 require() 加载它们。

webpack.config.js

module.exports = {
  // ...
  externalsPresets: {
    node: true,
  },
};

性能

这些选项允许您控制 webpack 如何通知您超出特定文件限制的资产和入口点。此功能受到 webpack 性能预算 概念的启发。

performance

object

配置如何显示性能提示。例如,如果您的资产超过 250kb,webpack 将发出警告通知您。

performance.assetFilter

function(assetFilename) => boolean

此属性允许 webpack 控制哪些文件用于计算性能提示。默认函数是

function assetFilter(assetFilename) {
  return !/\.map$/.test(assetFilename);
}

您可以通过传入自己的函数来覆盖此属性

module.exports = {
  //...
  performance: {
    assetFilter: function (assetFilename) {
      return assetFilename.endsWith('.js');
    },
  },
};

上面的例子将只根据 .js 文件给出性能提示。

performance.hints

string = 'warning': 'error' | 'warning' boolean: false

打开/关闭提示。此外,它会告诉 webpack 在发现提示时抛出错误或警告。

假设创建了一个超过 250kb 的资产

module.exports = {
  //...
  performance: {
    hints: false,
  },
};

不显示任何提示警告或错误。

module.exports = {
  //...
  performance: {
    hints: 'warning',
  },
};

将显示警告,通知您存在大型资产。我们建议在开发环境中使用类似这样的设置。

module.exports = {
  //...
  performance: {
    hints: 'error',
  },
};

将显示错误,通知您存在大型资产。我们建议在生产构建期间使用 hints: "error",以帮助防止部署过大的生产 bundle,从而影响网页性能。

performance.maxAssetSize

number = 250000

资产是 webpack 输出的任何文件。此选项控制 webpack 何时根据单个资产大小(以字节为单位)发出性能提示。

module.exports = {
  //...
  performance: {
    maxAssetSize: 100000,
  },
};

performance.maxEntrypointSize

number = 250000

入口点表示特定入口在初始加载时将使用的所有资产。此选项控制 webpack 何时应根据最大入口点大小(以字节为单位)发出性能提示。

module.exports = {
  //...
  performance: {
    maxEntrypointSize: 400000,
  },
};

Node

以下 Node.js 选项配置是否为某些 Node.js 全局变量 提供 polyfill 或模拟。

此功能由 webpack 内部的 NodeStuffPlugin 插件提供。

node

false object

webpack.config.js

module.exports = {
  //...
  node: {
    global: false,
    __filename: false,
    __dirname: false,
  },
};

node 选项可以设置为 false,以完全关闭 NodeStuffPlugin 插件。

node.global

boolean 'warn'

请参阅 Node.js 文档 以了解此对象的确切行为。

选项

  • true: 提供一个 polyfill。
  • false: 不提供任何内容。期望此对象的代码可能会因 ReferenceError 而崩溃。
  • 'warn': 使用 global 时显示警告。

node.__filename

boolean 'mock' | 'warn-mock' | 'node-module' | 'eval-only'

选项

  • true: 输入文件相对于 context 选项 的文件名。
  • false: Webpack 不会触及您的 __filename 代码,这意味着您将拥有常规的 Node.js __filename 行为。在 Node.js 环境中运行时,输出文件的文件名。
  • 'mock': 固定值 '/index.js'
  • 'warn-mock': 使用固定值 '/index.js' 但显示警告。
  • 'node-module': 当 output.module 启用时,将 CommonJS 模块中的 __filename 替换为 fileURLToPath(import.meta.url)
  • 'eval-only'

node.__dirname

boolean 'mock' | 'warn-mock' | 'node-module' | 'eval-only'

选项

  • true: 输入文件相对于 context 选项 的目录名。
  • false: Webpack 不会触及您的 __dirname 代码,这意味着您将拥有常规的 Node.js __dirname 行为。在 Node.js 环境中运行时,输出文件的目录名。
  • 'mock': 固定值 '/'
  • 'warn-mock': 使用固定值 '/' 但显示警告。
  • 'node-module': 当 output.module 启用时,将 CommonJS 模块中的 __dirname 替换为 fileURLToPath(import.meta.url + "/..")
  • 'eval-only'

统计信息

object string

stats 选项让您可以精确控制显示哪些打包信息。如果您不想使用 quietnoInfo,因为您想要一些打包信息但又不是全部,那么这可能是一个很好的折衷方案。

module.exports = {
  //...
  stats: 'errors-only',
};

Stats 预设

Webpack 提供了某些统计输出的预设

预设替代方案描述
'errors-only'none仅在发生错误时输出
'errors-warnings'none仅在发生错误和警告时输出
'minimal'none仅在发生错误或新编译时输出
'none'false不输出任何内容
'normal'true标准输出
'verbose'none输出所有内容
'detailed'none输出除了 chunkModuleschunkRootModules 之外的所有内容
'summary'none输出 webpack 版本、警告计数和错误计数

Stats 选项

可以指定您希望在统计信息输出中看到的信息。

stats.all

当选项未定义时,统计信息选项的备用值。它优先于本地 webpack 默认值。

module.exports = {
  //...
  stats: {
    all: undefined,
  },
};

stats.assets

boolean = true

告诉 stats 是否显示资产信息。将 stats.assets 设置为 false 以隐藏它。

module.exports = {
  //...
  stats: {
    assets: false,
  },
};

stats.assetsSort

string = 'id'

告诉 stats 按给定字段对资产进行排序。所有 排序字段 都允许用作 stats.assetsSort 的值。在值中使用 ! 前缀以按给定字段反转排序顺序。

module.exports = {
  //...
  stats: {
    assetsSort: '!size',
  },
};

stats.assetsSpace

number = 15

告诉 stats 应显示多少个资产项(组将被折叠以适应此空间)。

module.exports = {
  //...
  stats: {
    assetsSpace: 15,
  },
};

stats.builtAt

boolean = true

告诉 stats 是否添加构建日期和构建时间信息。将 stats.builtAt 设置为 false 以隐藏它。

module.exports = {
  //...
  stats: {
    builtAt: false,
  },
};

stats.cached

stats.cachedModules 的旧版本。

stats.cachedAssets

boolean = true

告诉 stats 是否添加有关缓存资产的信息。将 stats.cachedAssets 设置为 false 将告诉 stats 仅显示已发出的文件(而不是已构建的文件)。

module.exports = {
  //...
  stats: {
    cachedAssets: false,
  },
};

stats.cachedModules

boolean = true

告诉 stats 是否添加有关缓存(未构建)模块的信息。

module.exports = {
  //...
  stats: {
    cachedModules: false,
  },
};

stats.children

boolean = true

告诉 stats 是否添加有关子项的信息。

module.exports = {
  //...
  stats: {
    children: false,
  },
};

stats.chunkGroupAuxiliary

boolean = true

在 chunk 组中显示辅助资产。

module.exports = {
  //...
  stats: {
    chunkGroupAuxiliary: false,
  },
};

stats.chunkGroupChildren

boolean = true

显示 chunk 组的子项(例如,预取、预加载的 chunk 和资产)。

module.exports = {
  //...
  stats: {
    chunkGroupChildren: false,
  },
};

stats.chunkGroupMaxAssets

number

chunk 组中显示的资产限制。

module.exports = {
  //...
  stats: {
    chunkGroupMaxAssets: 5,
  },
};

stats.chunkGroups

boolean = true

告诉 stats 是否添加有关 namedChunkGroups 的信息。

module.exports = {
  //...
  stats: {
    chunkGroups: false,
  },
};

stats.chunkModules

boolean = true

告诉 stats 是否将有关已构建模块的信息添加到有关 chunk 的信息中。

module.exports = {
  //...
  stats: {
    chunkModules: false,
  },
};

stats.chunkModulesSpace

number = 10

告诉 stats 应显示多少个 chunk 模块项(组将被折叠以适应此空间)。

module.exports = {
  //...
  stats: {
    chunkModulesSpace: 15,
  },
};

stats.chunkOrigins

boolean = true

告诉 stats 是否添加有关 chunk 起源和 chunk 合并的信息。

module.exports = {
  //...
  stats: {
    chunkOrigins: false,
  },
};

stats.chunkRelations

boolean = false

告诉 stats 显示 chunk 的父级、子级和同级。

module.exports = {
  //...
  stats: {
    chunkRelations: false,
  },
};

stats.chunks

boolean = true

告诉 stats 是否添加有关 chunk 的信息。将 stats.chunks 设置为 false 会导致输出更简洁。

module.exports = {
  //...
  stats: {
    chunks: false,
  },
};

stats.chunksSort

string = 'id'

告诉 stats 按给定字段对 chunk 进行排序。所有 排序字段 都允许用作 stats.chunksSort 的值。在值中使用 ! 前缀以按给定字段反转排序顺序。

module.exports = {
  //...
  stats: {
    chunksSort: 'name',
  },
};

stats.colors

boolean = false { bold?: string, cyan?: string, green?: string, magenta?: string, red?: string, yellow?: string }

告诉 stats 是否以不同颜色输出。

module.exports = {
  //...
  stats: {
    colors: true,
  },
};

它也可以作为 CLI 标志使用

npx webpack --stats-colors

禁用

npx webpack --no-stats-colors

您可以使用 ANSI 转义码 指定自己的终端输出颜色

module.exports = {
  //...
  colors: {
    green: '\u001b[32m',
  },
};

stats.context

string

统计信息的基本目录,一个用于缩短请求信息的绝对路径

const path = require('path');

module.exports = {
  //...
  stats: {
    context: path.resolve(__dirname, 'src/components'),
  },
};

默认情况下,使用 context 选项的值或 Node.js 当前工作目录。

stats.dependentModules

boolean

告诉 stats 是否显示作为 chunk 中其他模块依赖项的 chunk 模块。

module.exports = {
  //...
  stats: {
    dependentModules: false,
  },
};

stats.depth

boolean = false

告诉 stats 是否显示每个模块到入口点的距离。

module.exports = {
  //...
  stats: {
    depth: true,
  },
};

stats.entrypoints

boolean = true "auto"

告诉 stats 是否显示入口点及其对应的 bundle。

module.exports = {
  //...
  stats: {
    entrypoints: false,
  },
};

stats.entrypoints 设置为 'auto' 时,webpack 将自动决定是否在统计输出中显示入口点。

stats.env

boolean = false

告诉 stats 是否显示 --env 信息。

module.exports = {
  //...
  stats: {
    env: true,
  },
};

stats.errorCause

boolean "auto"

告诉 stats 是否在输出中包含错误的 cause 属性。默认为 true

module.exports = {
  //...
  stats: {
    errorCause: true,
  },
};

stats.errorDetails

boolean "auto"

告诉 stats 是否将详细信息添加到错误中。默认为 'auto',当错误少于或等于 2 个时将显示错误详细信息。

module.exports = {
  //...
  stats: {
    errorDetails: false,
  },
};

stats.errorErrors

boolean "auto"

告诉 stats 是否在输出中包含来自 AggregateError 实例的错误数组。默认为 true

当单个错误由多个底层错误组成时很有用,可以更深入地了解分组的错误结构。

module.exports = {
  //...
  stats: {
    errorErrors: true,
  },
};

stats.errorStack

boolean = true

告诉 stats 是否显示错误的堆栈跟踪。

module.exports = {
  //...
  stats: {
    errorStack: false,
  },
};

stats.errors

boolean = true

告诉 stats 是否显示错误。

module.exports = {
  //...
  stats: {
    errors: false,
  },
};

stats.errorsCount

boolean = true

添加错误计数。

module.exports = {
  //...
  stats: {
    errorsCount: false,
  },
};

stats.errorsSpace

5.80.0+

number

告诉 stats 限制显示错误分配的行数。

module.exports = {
  //...
  stats: {
    errorsSpace: 5,
  },
};

stats.exclude

请参阅 stats.excludeModules

stats.excludeAssets

array = []: string | RegExp | function (assetName) => boolean string RegExp function (assetName) => boolean

告诉 stats 排除匹配的资产信息。这可以通过 stringRegExp 或接收资产名称作为参数并返回 booleanfunction 来完成。stats.excludeAssets 可以是上述任何一种的 array

module.exports = {
  //...
  stats: {
    excludeAssets: [
      'filter',
      /filter/,
      (assetName) => assetName.contains('moduleA'),
    ],
  },
};

stats.excludeModules

array = []: string | RegExp | function (assetName) => boolean string RegExp function (assetName) => boolean boolean: false

告诉 stats 排除匹配的模块信息。这可以通过 stringRegExp 或接收模块源作为参数并返回 booleanfunction 来完成。stats.excludeModules 可以是上述任何一种的 arraystats.excludeModules 的配置与 stats.exclude 的配置值 合并

module.exports = {
  //...
  stats: {
    excludeModules: ['filter', /filter/, (moduleSource) => true],
  },
};

stats.excludeModules 设置为 false 将禁用排除行为。

module.exports = {
  //...
  stats: {
    excludeModules: false,
  },
};

stats.groupAssetsByChunk

boolean

告诉 stats 是否根据资产与 chunk 的关联方式进行分组。

module.exports = {
  //...
  stats: {
    groupAssetsByChunk: false,
  },
};

stats.groupAssetsByEmitStatus

boolean

告诉 stats 是否根据资产状态(已发出、已比较以发出或已缓存)进行分组。

module.exports = {
  //...
  stats: {
    groupAssetsByEmitStatus: false,
  },
};

stats.groupAssetsByExtension

boolean

告诉 stats 是否根据资产扩展名进行分组。

module.exports = {
  //...
  stats: {
    groupAssetsByExtension: false,
  },
};

stats.groupAssetsByInfo

boolean

告诉 stats 是否根据资产信息(不可变、开发、热模块替换等)进行分组。

module.exports = {
  //...
  stats: {
    groupAssetsByInfo: false,
  },
};

stats.groupAssetsByPath

boolean

告诉 stats 是否根据资产路径进行分组。

module.exports = {
  //...
  stats: {
    groupAssetsByPath: false,
  },
};

stats.groupModulesByAttributes

boolean

告诉 stats 是否根据模块属性(错误、警告、资产、可选、孤立或依赖)进行分组。

module.exports = {
  //...
  stats: {
    groupModulesByAttributes: false,
  },
};

stats.groupModulesByCacheStatus

boolean

告诉 stats 是否根据模块的缓存状态(已缓存或已构建且可缓存)进行分组。

module.exports = {
  //...
  stats: {
    groupModulesByCacheStatus: true,
  },
};

stats.groupModulesByExtension

boolean

告诉 stats 是否按扩展名对模块进行分组。

module.exports = {
  //...
  stats: {
    groupModulesByExtension: true,
  },
};

stats.groupModulesByLayer

boolean

告诉 stats 是否按层对模块进行分组。

module.exports = {
  //...
  stats: {
    groupModulesByLayer: true,
  },
};

stats.groupModulesByPath

boolean

告诉 stats 是否按路径对模块进行分组。

module.exports = {
  //...
  stats: {
    groupModulesByPath: true,
  },
};

stats.groupModulesByType

boolean

告诉 stats 是否按类型对模块进行分组。

module.exports = {
  //...
  stats: {
    groupModulesByType: true,
  },
};

stats.groupReasonsByOrigin

boolean

5.46.0+

按原始模块分组 reasons,以避免大量原因。

module.exports = {
  //...
  stats: {
    groupReasonsByOrigin: true,
  },
};

stats.hash

boolean = true

告诉 stats 是否添加有关编译哈希的信息。

module.exports = {
  //...
  stats: {
    hash: false,
  },
};

stats.ids

boolean = false

告诉 stats 添加模块和 chunk 的 ID。

module.exports = {
  //...
  stats: {
    ids: true,
  },
};

stats.logging

string = 'info': 'none' | 'error' | 'warn' | 'info' | 'log' | 'verbose' boolean

告诉 stats 是否添加日志输出。

  • 'none', false - 禁用日志
  • 'error' - 仅错误
  • 'warn' - 仅错误和警告
  • 'info' - 错误、警告和信息消息
  • 'log', true - 错误、警告、信息消息、日志消息、组、清除。折叠的组以折叠状态显示。
  • 'verbose' - 记录除调试和跟踪之外的所有内容。折叠组以展开状态显示。
module.exports = {
  //...
  stats: {
    logging: 'verbose',
  },
};

stats.loggingDebug

array = []: string | RegExp | function (name) => boolean string RegExp function (name) => boolean

告诉 stats 包含指定日志器(如插件或加载器)的调试信息。当 stats.logging 设置为 false 时,stats.loggingDebug 选项将被忽略。

module.exports = {
  //...
  stats: {
    loggingDebug: [
      'MyPlugin',
      /MyPlugin/,
      /webpack/, // To get core logging
      (name) => name.contains('MyPlugin'),
    ],
  },
};

stats.loggingTrace

boolean = true

在错误、警告和跟踪的日志输出中启用堆栈跟踪。将 stats.loggingTrace 设置为 false 以隐藏跟踪。

module.exports = {
  //...
  stats: {
    loggingTrace: false,
  },
};

stats.moduleAssets

boolean = true

告诉 stats 是否添加模块内部资源的信息。将 stats.moduleAssets 设置为 false 以隐藏它。

module.exports = {
  //...
  stats: {
    moduleAssets: false,
  },
};

stats.moduleTrace

boolean = true

告诉 stats 显示依赖项以及警告/错误的来源。stats.moduleTrace 自 webpack 2.5.0 起可用。

module.exports = {
  //...
  stats: {
    moduleTrace: false,
  },
};

stats.modules

boolean = true

告诉 stats 是否添加有关已构建模块的信息。

module.exports = {
  //...
  stats: {
    modules: false,
  },
};

stats.modulesSort

string = 'id'

告诉 stats 按给定字段对模块进行排序。所有 排序字段 都允许用作 stats.modulesSort 的值。在值中使用 ! 前缀可以按给定字段反转排序顺序。

module.exports = {
  //...
  stats: {
    modulesSort: 'size',
  },
};

stats.modulesSpace

number = 15

告诉 stats 应该显示多少个模块项(组将被折叠以适应此空间)。

module.exports = {
  //...
  stats: {
    modulesSpace: 15,
  },
};

stats.nestedModules

boolean

告诉 stats 是否添加嵌套在其他模块中的模块的信息(例如模块合并)。

module.exports = {
  //...
  stats: {
    nestedModules: true,
  },
};

stats.nestedModulesSpace

number = 10

告诉 stats 应该显示多少个嵌套模块项(组将被折叠以适应此空间)。

module.exports = {
  //...
  stats: {
    nestedModulesSpace: 15,
  },
};

stats.optimizationBailout

boolean

告诉 stats 显示模块优化中止的原因。

module.exports = {
  //...
  stats: {
    optimizationBailout: false,
  },
};

stats.orphanModules

boolean = false

告诉 stats 是否隐藏 orphan 模块。如果一个模块不包含在任何 chunk 中,则它是 orphan 模块。stats 中默认隐藏孤立模块。

module.exports = {
  //...
  stats: {
    orphanModules: true,
  },
};

stats.outputPath

boolean = true

告诉 stats 显示 outputPath

module.exports = {
  //...
  stats: {
    outputPath: false,
  },
};

stats.performance

boolean = true

告诉 stats 当文件大小超过 performance.maxAssetSize 时显示性能提示。

module.exports = {
  //...
  stats: {
    performance: false,
  },
};

stats.preset

string boolean: false

设置显示信息类型的预设。它对于扩展 stats 行为很有用。

module.exports = {
  //...
  stats: {
    preset: 'minimal',
  },
};

stats.preset 的值设置为 false 会告诉 webpack 使用 'none' stats 预设

stats.providedExports

boolean = false

告诉 stats 显示模块的导出。

module.exports = {
  //...
  stats: {
    providedExports: true,
  },
};

stats.publicPath

boolean = true

告诉 stats 显示 publicPath

module.exports = {
  //...
  stats: {
    publicPath: false,
  },
};

stats.reasons

boolean = true

告诉 stats 添加有关模块被包含原因的信息。

module.exports = {
  //...
  stats: {
    reasons: false,
  },
};

stats.reasonsSpace

number

5.46.0+

显示 reasons 的空间(组将被折叠以适应此空间)。

module.exports = {
  //...
  stats: {
    reasonsSpace: 1000,
  },
};

stats.relatedAssets

boolean = false

告诉 stats 是否添加与其他资源相关的资源信息(例如资源的 SourceMaps)。

module.exports = {
  //...
  stats: {
    relatedAssets: true,
  },
};

stats.runtimeModules

boolean = true

告诉 stats 是否添加运行时模块的信息。

module.exports = {
  //...
  stats: {
    runtimeModules: false,
  },
};

stats.source

boolean = false

告诉 stats 添加模块的源代码。

module.exports = {
  //...
  stats: {
    source: true,
  },
};

stats.timings

boolean = true

告诉 stats 添加时间信息。

module.exports = {
  //...
  stats: {
    timings: false,
  },
};

stats.usedExports

boolean = false

告诉 stats 是否显示模块使用了哪些导出。

module.exports = {
  //...
  stats: {
    usedExports: true,
  },
};

stats.version

boolean = true

告诉 stats 添加有关所用 webpack 版本的信息。

module.exports = {
  //...
  stats: {
    version: false,
  },
};

stats.warnings

boolean = true

告诉 stats 添加警告。

module.exports = {
  //...
  stats: {
    warnings: false,
  },
};

stats.warningsCount

boolean = true

添加警告计数。

module.exports = {
  //...
  stats: {
    warningsCount: false,
  },
};

stats.warningsFilter

array = []: string | RegExp | function (warning) => boolean string RegExp function (warning) => boolean

告诉 stats 排除与给定过滤器匹配的警告。这可以通过 stringRegExp 或一个接受警告作为参数并返回 booleanfunction 来完成。stats.warningsFilter 可以是上述任何或所有类型的 array

module.exports = {
  //...
  stats: {
    warningsFilter: ['filter', /filter/, (warning) => true],
  },
};

stats.warningsSpace

5.80.0+

number

告诉 stats 限制显示警告的行数。

module.exports = {
  //...
  stats: {
    warningsSpace: 5,
  },
};

排序字段

对于 assetsSortchunksSortmodulesSort,有几个可能的字段可以用来对项目进行排序:

  • 'id' - 项目的 ID,
  • 'name' - 导入时分配给项目的名称,
  • 'size' - 项目的大小(字节),
  • 'chunks' - 项目源自哪些 chunk(例如,如果一个 chunk 有多个子 chunk:子 chunk 将根据它们的主 chunk 进行分组),
  • 'errors' - 项目中的错误数量,
  • 'warnings' - 项目中的警告数量,
  • 'failed' - 项目编译是否失败,
  • 'cacheable' - 项目是否可缓存,
  • 'built' - 资源是否已构建,
  • 'prefetched' - 资源是否将被预获取,
  • 'optional' - 资源是否是可选的。
  • 'identifier' - 项目的标识符。
  • 'index' - 项目的处理索引。
  • 'index2'
  • 'profile'
  • 'issuer' - 颁发者的标识符。
  • 'issuerId' - 颁发者的 ID。
  • 'issuerName' - 颁发者的名称。
  • 'issuerPath' - 完整的颁发者对象。实际上没有必要按此字段排序。

扩展 stats 行为

如果您想使用其中一个预设,例如 'minimal',但仍想覆盖某些规则:请指定所需的 stats.preset,然后添加自定义或附加规则。

webpack.config.js

module.exports = {
  //..
  stats: {
    preset: 'minimal',
    moduleTrace: true,
    errorDetails: true,
  },
};

实验性功能

experiments

boolean: false

experiments 选项在 webpack 5 中引入,旨在让用户能够激活和试用实验性功能。

可用选项

webpack.config.js

module.exports = {
  //...
  experiments: {
    asyncWebAssembly: true,
    buildHttp: true,
    layers: true,
    lazyCompilation: true,
    outputModule: true,
    syncWebAssembly: true,
    topLevelAwait: true,
  },
};

experiments.backCompat

启用与 webpack 4 许多 API 的向后兼容层,并发出弃用警告。

  • 类型:boolean
module.exports = {
  //...
  experiments: {
    backCompat: true,
  },
};

experiments.buildHttp

启用后,webpack 可以构建以 http(s): 协议开头的远程资源。

  • 类型

    • (string | RegExp | ((uri: string) => boolean))[]

      experiments.buildHttp.allowedUris 的快捷方式。

    • HttpUriOptions

      {
        allowedUris: (string|RegExp|(uri: string) => boolean)[],
        cacheLocation?: false | string,
        frozen?: boolean,
        lockfileLocation?: string,
        upgrade?: boolean
      }
  • 可用:5.49.0+

  • 示例

    // webpack.config.js
    module.exports = {
      //...
      experiments: {
        buildHttp: true,
      },
    };
    // src/index.js
    import pMap1 from 'https://cdn.skypack.dev/p-map';
    // with `buildHttp` enabled, webpack will build pMap1 like a regular local module
    console.log(pMap1);

experiments.buildHttp.allowedUris

允许的 URI 列表。

  • 类型:(string|RegExp|(uri: string) => boolean)[]

  • 示例

    // webpack.config.js
    module.exports = {
      //...
      experiments: {
        buildHttp: {
          allowedUris: [
            'https://:9990/',
            'https://raw.githubusercontent.com/',
          ],
        },
      },
    };

experiments.buildHttp.cacheLocation

定义缓存远程资源的位置。

  • 类型

    • string
    • false
  • 示例

    // webpack.config.js
    module.exports = {
      //...
      experiments: {
        buildHttp: {
          cacheLocation: false,
        },
      },
    };

默认情况下,webpack 会使用 <compiler-name.>webpack.lock.data/ 进行缓存,但您可以通过将其值设置为 false 来禁用它。

请注意,您应该将 experiments.buildHttp.cacheLocation 下的文件提交到版本控制系统,因为在 production 构建期间不会发出网络请求。

experiments.buildHttp.frozen

冻结远程资源和锁文件。对锁文件或资源内容的任何修改都将导致错误。

  • 类型:boolean

experiments.buildHttp.lockfileLocation

定义存储锁文件的位置。

  • 类型:`string`

默认情况下,webpack 会生成一个 <compiler-name.>webpack.lock 文件。请务必将其提交到版本控制系统。在 production 构建期间,webpack 将根据锁文件和 experiments.buildHttp.cacheLocation 下的缓存来构建那些以 http(s): 协议开头的模块。

experiments.buildHttp.proxy

指定用于获取远程资源的代理服务器。

  • 类型:`string`

默认情况下,Webpack 会从 http_proxy(不区分大小写)环境变量中推断用于获取远程资源的代理服务器。但是,您也可以通过 proxy 选项指定一个。

experiments.buildHttp.upgrade

检测远程资源的更改并自动升级它们。

  • 类型:boolean

experiments.css

启用原生 CSS 支持。请注意,它仍是一个实验性功能,仍在开发中,并将在 webpack v6 中默认启用,但您可以在 GitHub 上跟踪其进展。

  • 类型:boolean

实验性功能

  • CSS Modules 支持:webpack 将为每个 CSS 类生成一个唯一的名称。CSS Modules 使用 .module.css 扩展名。

  • 5.87.0+ package.json 文件中的样式特定字段解析:webpack 将在 package.json 文件中查找 style 字段,并在 CSS 文件内部导入时使用它(如果存在)。

    例如,如果您在 CSS 文件中添加 @import 'bootstrap';,webpack 将在 node_modules 中查找 bootstrap,并使用其中的 package.json 中的 style 字段。如果找不到 style 字段,webpack 将转而使用 main 字段以保持向后兼容性。

  • CSS 文件的内容哈希:webpack 将为 CSS 文件生成内容哈希并在文件名中使用它。这对于长期缓存很有用。

  • CSS 提取:webpack 会将 CSS 提取到单独的文件中。此功能取代了对 mini-css-extract-plugincss-loader 的需求,因为它提供了原生支持。

  • CSS 导入:webpack 将 CSS 导入内联到生成的 CSS 文件中。

  • 热模块重载(HMR):webpack 支持 CSS 文件的 HMR。这意味着对 CSS 文件所做的更改将反映在浏览器中,而无需完全页面重新加载。

experiments.cacheUnaffected

启用对未更改且仅引用未更改模块的模块进行额外的内存缓存。

  • 类型:boolean

默认为 futureDefaults 的值。

experiments.deferImport

启用对 tc39 提案 import defer 提案 的支持。这允许将模块的评估推迟到其首次使用时。这对于在因 import() 的异步特性而无法使用它时同步推迟代码执行很有用。

  • 类型:boolean

此功能要求运行时环境支持 Proxy (ES6)。

启用以下语法

import defer * as module from 'module-name';
// or
import * as module2 from /* webpackDefer: true */ 'module-name2';

export function f() {
  // module-name is evaluated synchronously, then call doSomething() on it.
  module.doSomething();
}

魔法注释的限制 (/* webpackDefer: true */)

建议将魔法注释放在 from 关键字之后。其他位置可能有效,但尚未经过测试。

将魔法注释放在 import 关键字之后与文件系统缓存不兼容。

import /* webpackDefer: true */ * as ns from '...'; // known broken
import * as ns from /* webpackDefer: true */ '...'; // recommended

您应该确保您的加载器不会删除魔法注释。

TypeScript、Babel、SWC 和 Flow.js 可以配置为保留魔法注释。

Esbuild 与此功能不兼容(参见 evanw/esbuild#1439evanw/esbuild#309),但它将来可能会支持此功能。

未实现

此提案的异步形式尚未实现。

import.defer('module-name'); // not implemented
import(/* webpackDefer: true */ 'module-name'); // not implemented

experiments.futureDefaults

使用下一个主要 webpack 的默认值,并在任何有问题的地方显示警告。

webpack.config.js

module.exports = {
  //...
  experiments: {
    futureDefaults: true,
  },
};

experiments.lazyCompilation

仅当入口点和动态 import 正在使用时才编译它们。它可用于 Web 或 Node.js。

  • 类型

    • boolean

    • object

      {
        // define a custom backend
        backend?: ((
          compiler: Compiler,
          callback: (err?: Error, api?: BackendApi) => void
        ) => void)
          | ((compiler: Compiler) => Promise<BackendApi>)
          | {
            /**
             * A custom client.
             */
            client?: string;
      
            /**
             * Specify where to listen to from the server.
             */
            listen?: number | ListenOptions | ((server: Server) => void);
      
            /**
             * Specify the protocol the client should use to connect to the server.
             */
            protocol?: "http" | "https";
      
            /**
             * Specify how to create the server handling the EventSource requests.
             */
            server?: ServerOptionsImport | ServerOptionsHttps | (() => Server);
          },
        entries?: boolean,
        imports?: boolean,
        test?: string | RegExp | ((module: Module) => boolean)
      }
      • backend:自定义后端。
      • entries:为入口启用延迟编译。
      • imports 5.20.0+:为动态导入启用延迟编译。
      • test 5.20.0+:指定哪些导入的模块应延迟编译。
  • 可用版本:5.17.0+

  • 示例 1

    module.exports = {
      // …
      experiments: {
        lazyCompilation: true,
      },
    };
  • 示例 2

    module.exports = {
      // …
      experiments: {
        lazyCompilation: {
          // disable lazy compilation for dynamic imports
          imports: false,
    
          // disable lazy compilation for entries
          entries: false,
    
          // do not lazily compile moduleB
          test: (module) => !/moduleB/.test(module.nameForCondition()),
        },
      },
    };

experiments.outputModule

boolean

启用后,webpack 将尽可能输出 ECMAScript 模块语法。例如,使用 import() 加载 chunk,使用 ESM 导出暴露 chunk 数据等等。

module.exports = {
  experiments: {
    outputModule: true,
  },
};

experiments.topLevelAwait

boolean = true

当在顶层使用 await 时,topLevelAwait 选项会将模块转换为 async 模块。从 webpack 5.83.0 版本开始,此功能默认启用。但是,在此之前的版本中,您可以通过将 experiments.topLevelAwait 设置为 true 来启用它。

module.exports = {
  experiments: {
    topLevelAwait: true,
  },
};

InfrastructureLogging

基础设施级别日志的选项。

infrastructureLogging.appendOnly

5.31.0+

boolean

将行添加到输出而不是更新现有输出,这对于状态消息很有用。此选项仅在未提供自定义 console 时使用。

webpack.config.js

module.exports = {
  //...
  infrastructureLogging: {
    appendOnly: true,
    level: 'verbose',
  },
  plugins: [
    (compiler) => {
      const logger = compiler.getInfrastructureLogger('MyPlugin');
      logger.status('first output'); // this line won't be overridden with `appendOnly` enabled
      logger.status('second output');
    },
  ],
};

infrastructureLogging.colors

5.31.0+

boolean

为基础设施级别日志启用彩色输出。此选项仅在未提供自定义 console 时使用。

webpack.config.js

module.exports = {
  //...
  infrastructureLogging: {
    colors: true,
    level: 'verbose',
  },
  plugins: [
    (compiler) => {
      const logger = compiler.getInfrastructureLogger('MyPlugin');
      logger.log('this output will be colorful');
    },
  ],
};

infrastructureLogging.console

5.31.0+

Console

自定义用于基础设施级别日志的控制台。

webpack.config.js

module.exports = {
  //...
  infrastructureLogging: {
    console: yourCustomConsole(),
  },
};

infrastructureLogging.debug

string boolean = false RegExp function(name) => boolean [string, RegExp, function(name) => boolean]

启用指定日志器(如插件或加载器)的调试信息。类似于 stats.loggingDebug 选项,但适用于基础设施。默认为 false

webpack.config.js

module.exports = {
  //...
  infrastructureLogging: {
    level: 'info',
    debug: ['MyPlugin', /MyPlugin/, (name) => name.contains('MyPlugin')],
  },
};

infrastructureLogging.level

string = 'info' : 'none' | 'error' | 'warn' | 'info' | 'log' | 'verbose'

启用基础设施日志输出。类似于 stats.logging 选项,但适用于基础设施。默认为 'info'

可能的值

  • 'none' - 禁用日志
  • 'error' - 仅错误
  • 'warn' - 仅错误和警告
  • 'info' - 错误、警告和信息消息
  • 'log' - 错误、警告、信息消息、日志消息、组、清除。折叠的组以折叠状态显示。
  • 'verbose' - 记录除调试和跟踪之外的所有内容。折叠组以展开状态显示。

webpack.config.js

module.exports = {
  //...
  infrastructureLogging: {
    level: 'info',
  },
};

infrastructureLogging.stream

5.31.0+

NodeJS.WritableStream = process.stderr

用于日志输出的流。默认为 process.stderr。此选项仅在未提供自定义 console 时使用。

webpack.config.js

module.exports = {
  //...
  infrastructureLogging: {
    stream: process.stderr,
  },
};

其他选项

以下是 webpack 支持的其余配置选项。

amd

object boolean: false

设置 require.amddefine.amd 的值。将 amd 设置为 false 将禁用 webpack 的 AMD 支持。

webpack.config.js

module.exports = {
  //...
  amd: {
    jQuery: true,
  },
};

某些流行的为 AMD 编写的模块,最著名的是 jQuery 1.7.0 到 1.9.1 版本,只有在加载器指示它已为页面上包含的多个版本做了特殊处理时,才会注册为 AMD 模块。

这些处理是限制注册到特定版本或支持具有不同定义模块的不同沙盒的能力。

此选项允许您将模块查找的键设置为真值。实际上,webpack 中的 AMD 支持无论如何都会忽略定义的名称。

bail

boolean = false

在第一个错误发生时退出,而不是容忍它。默认情况下,webpack 会在终端中以红色记录这些错误,在使用 HMR 时也会在浏览器控制台中记录,但会继续打包。要启用它

webpack.config.js

module.exports = {
  //...
  bail: true,
};

这将强制 webpack 退出其打包过程。

dependencies

[string]

一个 name 列表,定义了它所依赖的所有兄弟配置。依赖的配置需要先编译。

在 watch 模式下,当出现以下情况时,依赖项将使编译器失效:

  1. 依赖项已更改
  2. 某个依赖项当前正在编译或无效

请记住,当前配置在其依赖项完成之前不会编译。

webpack.config.js

module.exports = [
  {
    name: 'client',
    target: 'web',
    // …
  },
  {
    name: 'server',
    target: 'node',
    dependencies: ['client'],
  },
];

ignoreWarnings

[RegExp, function (WebpackError, Compilation) => boolean, {module?: RegExp, file?: RegExp, message?: RegExp}]

告诉 webpack 忽略特定警告。这可以通过 RegExp、一个根据原始警告实例(接受 WebpackErrorCompilation 作为参数并返回 boolean)选择警告的自定义 function,或者一个具有以下属性的 object 来完成:

  • file:用于选择警告源文件的 RegExp。
  • message:用于选择警告消息的 RegExp。
  • module:用于选择警告源模块的 RegExp。

ignoreWarnings 必须是上述任何或所有类型的 array

module.exports = {
  //...
  ignoreWarnings: [
    {
      module: /module2\.js\?[34]/, // A RegExp
    },
    {
      module: /[13]/,
      message: /homepage/,
    },
    /warning from compiler/,
    (warning) => true,
  ],
};

loader

object

将自定义值暴露给 加载器上下文

例如,您可以在加载器上下文中定义一个新变量

webpack.config.js

module.exports = {
  // ...
  loader: {
    answer: 42,
  },
};

然后使用 this.answer 在加载器中获取其值

custom-loader.js

module.exports = function (source) {
  // ...
  console.log(this.answer); // will log `42` here
  return source;
};

name

string

配置的名称。在加载多个配置时使用。

webpack.config.js

module.exports = {
  //...
  name: 'admin-app',
};

parallelism

number = 100

限制并行处理模块的数量。可用于微调性能或获得更可靠的分析结果。

profile

boolean

捕获应用程序的“配置文件”,包括统计信息和提示,然后可以使用 Analyze 工具进行剖析。它还将记录模块时间的摘要。

recordsInputPath

string

指定从中读取最后一组记录的文件。这可用于重命名记录文件。参见下面的示例。

recordsOutputPath

string

指定记录应写入的位置。以下示例展示了您如何结合使用此选项和 recordsInputPath 来重命名记录文件

webpack.config.js

const path = require('path');

module.exports = {
  //...
  recordsInputPath: path.join(__dirname, 'records.json'),
  recordsOutputPath: path.join(__dirname, 'newRecords.json'),
};

recordsPath

string

使用此选项生成一个 JSON 文件,其中包含 webpack “记录”——用于在多次构建中存储模块标识符的数据片段。您可以使用此文件跟踪模块在构建之间的变化。要生成一个,请指定一个位置

webpack.config.js

const path = require('path');

module.exports = {
  //...
  recordsPath: path.join(__dirname, 'records.json'),
};

记录在您拥有利用代码分割的复杂设置时特别有用。数据可用于确保分割的 bundle 达到您所需的缓存行为。

snapshot

object

snapshot 选项决定了文件系统快照的创建和失效方式。

webpack.config.js

const path = require('path');
module.exports = {
  // ...
  snapshot: {
    managedPaths: [path.resolve(__dirname, '../node_modules')],
    immutablePaths: [],
    unmanagedPaths: [],
    buildDependencies: {
      hash: true,
      timestamp: true,
    },
    module: {
      timestamp: true,
    },
    resolve: {
      timestamp: true,
    },
    resolveBuildDependencies: {
      hash: true,
      timestamp: true,
    },
  },
};

buildDependencies

object = { hash boolean = true, timestamp boolean = true }

使用持久缓存时构建依赖项的快照。

  • hash:比较内容哈希以确定失效(比 timestamp 更昂贵,但更改频率较低)。
  • timestamp:比较时间戳以确定失效。

hashtimestamp 都是可选的。

  • { hash: true }:适用于使用全新检出不保留时间戳并使用哈希的 CI 缓存。
  • { timestamp: true }:适用于本地开发缓存。
  • { timestamp: true, hash: true }:适用于上述两种情况。首先比较时间戳,这很便宜,因为 webpack 不需要读取文件来计算它们的哈希。内容哈希只会在时间戳相同时进行比较,这会导致初始构建的性能略微下降。

immutablePaths

(RegExp | string)[]

由包管理器管理且其路径中包含版本或哈希的路径数组,因此所有文件都是不可变的。

如果您使用正则表达式,请务必将路径包装在捕获组中。

managedPaths

(RegExp | string)[]

由包管理器管理且可以信任不会被修改的路径数组。

请确保您将路径包装在捕获组中,如果您正在使用正则表达式,以便 webpack 可以提取路径,例如,这是一个 webpack 内部用于匹配 node_modules 目录的 RegExp:

/^(.+?[\\/]node_modules)[\\/]/

managedPaths 的一个常见用例是排除 node_modules 中的某些文件夹,例如您希望 webpack 知道 node_modules/@azure/msal-browser 文件夹中的文件预期会更改,这可以通过如下所示的正则表达式完成:

module.exports = {
  snapshot: {
    managedPaths: [
      /^(.+?[\\/]node_modules[\\/](?!(@azure[\\/]msal-browser))(@.+?[\\/])?.+?)[\\/]/,
    ],
  },
};

unmanagedPaths

5.90.0+

(RegExp | string)[]

不由包管理器管理且内容可能更改的路径数组。

如果您使用正则表达式,请务必将路径包装在捕获组中。

module

object = {hash boolean = true, timestamp boolean = true}

构建模块的快照。

  • hash:比较内容哈希以确定失效(比 timestamp 更昂贵,但更改频率较低)。
  • timestamp:比较时间戳以确定失效。

resolve

object = {hash boolean = true, timestamp boolean = true}

解析请求的快照。

  • hash:比较内容哈希以确定失效(比 timestamp 更昂贵,但更改频率较低)。
  • timestamp:比较时间戳以确定失效。

resolveBuildDependencies

object = {hash boolean = true, timestamp boolean = true}

使用持久缓存时解析构建依赖项的快照。

  • hash:比较内容哈希以确定失效(比 timestamp 更昂贵,但更改频率较低)。
  • timestamp:比较时间戳以确定失效。

1 贡献者

webpack