Printable

配置

webpack 开箱即用,可以无需使用任何配置文件。然而,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 的 init 命令,它可以根据你的项目需求快速生成 webpack 配置文件,它会在创建配置文件之前询问你几个问题。

npx webpack init

如果尚未在项目或全局安装 @webpack-cli/generators,npx 可能会提示你安装。根据你在配置生成过程中的选择,你也可能会安装额外的 package 到你的项目中。

$ npx webpack init

[webpack-cli] For using this command you need to install: '@webpack-cli/generators' package.
[webpack-cli] Would you like to install '@webpack-cli/generators' package? (That will run 'npm install -D @webpack-cli/generators') (Y/n)
devDependencies:
+ @webpack-cli/generators 2.5.0
? Which of the following JS solutions do you want to use? ES6
? 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
? Do you like to install prettier to format generated configuration? Yes
? Pick a package manager: pnpm
[webpack-cli] ℹ INFO  Initialising project...

devDependencies:
+ @babel/core 7.19.3
+ @babel/preset-env 7.19.4
+ autoprefixer 10.4.12
+ babel-loader 8.2.5
+ css-loader 6.7.1
+ html-webpack-plugin 5.5.0
+ mini-css-extract-plugin 2.6.1
+ postcss 8.4.17
+ postcss-loader 7.0.1
+ prettier 2.7.1
+ style-loader 3.3.1
+ webpack-dev-server 4.11.1
[webpack-cli] Project has been initialised with webpack!

Configuration Languages

Webpack 支持使用多种编程语言和数据描述格式来编写配置文件。在 node-interpret 中你可以找到当前所支持的文件类型列表,通过 node-interpret,webpack 能够处理这些类型的配置文件。

TypeScript

要使用 Typescript 来编写 webpack 配置,你需要先安装必要的依赖,比如 Typescript 以及其相应的类型声明,类型声明可以从 DefinitelyTyped 项目中获取,依赖安装如下所示:

npm install --save-dev typescript ts-node @types/node @types/webpack
# 如果使用版本低于 v4.7.0 的 webpack-dev-server,还需要安装以下依赖
npm install --save-dev @types/webpack-dev-server

完成依赖安装后便可以开始编写配置文件,示例如下:

webpack.config.ts

import * as path from 'path';
import * as 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;

该示例需要 typescript 版本在 2.7 及以上,并在 tsconfig.json 文件的 compilerOptions 中添加 esModuleInteropallowSyntheticDefaultImports 两个配置项。

值得注意的是你需要确保 tsconfig.jsoncompilerOptionsmodule 选项的值为 commonjs,否则 webpack 的运行会失败报错,因为 ts-node 不支持 commonjs 以外的其他模块规范。

你可以通过三个途径来完成 module 的设置:

  • 直接修改 tsconfig.json 文件
  • 修改 tsconfig.json 并且添加 ts-node 的设置。
  • 使用 tsconfig-paths

第一种方法就是打开你的 tsconfig.json 文件,找到 compilerOptions 的配置,然后设置 targetmodule 的选项分别为 "ES5""CommonJs" (在 target 设置为 es5 时你也可以不显示编写 module 配置)。

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

你可以为 tsc 保持 "module": "ESNext"配置,如果你是用 webpack 或者其他构建工具的话,为 ts-node 设置一个重载(override)。ts-node 配置项

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

第三种方法需要先安装 tsconfig-paths 这个 npm 包,如下所示:

npm install --save-dev tsconfig-paths

安装后你可以为 webpack 配置创建一个单独的 TypeScript 配置文件,示例如下:

tsconfig-for-webpack-config.json

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

process.env.TS_NODE_PROJECT 变量的设置如下所示:

package.json

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

之所以要添加 cross-env,是因为我们在直接使用 TS_NODE_PROJECT 时遇到过 "TS_NODE_PROJECT" unrecognized command 报错的反馈,添加 cross-env 之后该问题也似乎得到了解决,你可以查看这个 issue获取到关于该问题的更多信息。

CoffeeScript

Typescript 类似,在使用 CoffeeScript 前需要先安装其依赖,如下所示:

npm install --save-dev coffeescript

完成安装之后便可以开始编写 webpack 配置,示例如下:

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 and JSX

下述的示例中使用了 JSX(用于 React 的 JavaScript 标记语言)和 babel 来创建格式为 json 的 webpack 配置文件。

感谢 Jason Miller 提供示例代码

首先,需要安装一些必要依赖,如下所示:

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

.babelrc

{
  "presets": ["es2015"]
}

webpack.config.babel.js

import jsxobj from 'jsxobj';

// 插件引入示例
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>
);

如果你在其他地方也使用了 Babel 并且 modules 的值设置为 false,则必须维护两份 .babelrc 的文件,或者你也可以将上述示例中的 import jsxobj from 'jsxobj'; 替换为 const jsxobj = require('jsxobj'); 并将新的 export 语法替换为 module.exports,因为尽管 Node 目前已经支持了 ES6 的许多新特性,但是仍然没有支持 ES6 的模块语法。

Configuration Types

除了导出单个配置外,还有一些能满足更多需求的使用方式。

导出函数

你可能会遇到需要区分开发环境和生产环境的情况。有很多种方式可以做到这一点。其中一种选择是由 webpack 配置导出一个函数而非对象,这个函数包含两个参数:

-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 时,所有配置项都会构建。比如,对于多 targets(如 AMD 和 CommonJS)构建 library 时会非常有用。

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

基础目录,绝对路径,用于从配置中解析入口点(entry point)和 加载器(loader)。

const path = require('path');

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

默认使用 Node.js 进程的当前工作目录,但是推荐在配置中传入一个值。这使得你的配置独立于 CWD(current working directory, 当前工作目录)。


entry

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

开始应用程序打包过程的一个或多个起点。如果传入数组,则会处理所有条目。

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

一个需要考虑的规则:每个 HTML 页面都有一个入口起点。单页应用(SPA):一个入口起点,多页应用(MPA):多个入口起点。

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

Naming

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

Entry descriptor

如果传入一个对象,对象的属性的值可以是一个字符串、字符串数组或者一个描述符(descriptor):

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
    },
  },
};

描述符语法可以用来传入额外的选项给入口。

Output filename

默认情况下,入口 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—选项传递给指定的入口点。

Dependencies

默认情况下,每个入口 chunk 保存了全部其用的模块(modules)。使用 dependOn 选项你可以与另一个入口 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'],
  },
};

Dynamic entry

如果传入一个函数,那么它将会在每次 make 事件中被调用。

要注意的是,make 事件在 webpack 启动和每当 监听文件变化 时都会触发。

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

或者

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

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

webpack.config.js

module.exports = {
  entry() {
    return fetchPathsFromSomeExternalSource(); // 返回一个会被用像 ['src/main-layout.js', 'src/admin-layout.js'] 的东西 resolve 的 promise
  },
};

当和 output.library 选项结合:如果传入的是一个数组,只有数组的最后一个条目会被导出。

模式(Mode)

提供 mode 配置选项,告知 webpack 使用相应模式的内置优化。

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

用法

只需在配置对象中提供 mode 选项:

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

或者从 CLI 参数中传递:

webpack --mode=development

支持以下字符串值:

选项描述
development会将 DefinePluginprocess.env.NODE_ENV 的值设置为 development. 为模块和 chunk 启用有效的名。
production会将 DefinePluginprocess.env.NODE_ENV 的值设置为 production。为模块和 chunk 启用确定性的混淆名称,FlagDependencyUsagePluginFlagIncludedChunksPluginModuleConcatenationPluginNoEmitOnErrorsPluginTerserPlugin
none不使用任何默认优化选项

如果没有设置,webpack 会给 mode 的默认值设置为 production

Mode: development

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

Mode: production

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

Mode: 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

output 位于对象最顶级键(key),包括了一组选项,指示 webpack 如何去输出、以及在哪里输出你的「bundle、asset 和其他你所打包或使用 webpack 载入的任何内容」。

output.assetModuleFilename

string = '[hash][ext][query]'

output.filename 相同,不过应用于 Asset Modules

对从数据 URI 替换构建的静态资源,[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 一起使用时,此选项允许用户向导出容器(export wrapper)中插入注释。要为 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

此选项决定了非初始(non-initial)chunk 文件的名称。有关可取的值的详细信息,请查看 output.filename 选项。

注意,这些文件名需要在运行时根据 chunk 发送的请求去生成。因此,需要在 webpack runtime 输出 bundle 值时,将 chunk id 的值对应映射到占位符(如 [name][chunkhash])。这会增加文件大小,并且在任何 chunk 的占位符值修改后,都会使 bundle 失效。

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

webpack.config.js

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

Usage as a function:

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 的格式(formats 默认包含 'array-push' (web/WebWorker)、'commonjs' (node.js)、'module' (ESM),还有其他情况可由插件添加)。

webpack.config.js

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

output.chunkLoadTimeout $#outputchunkLoadtimeout$

number = 120000

chunk 请求到期之前的毫秒数,默认为 120000。从 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' (sync node.js)、'async-node' (async 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, // 在生成文件之前清空 output 目录
  },
};
module.exports = {
  //...
  output: {
    clean: {
      dry: true, // 打印而不是删除应该移除的静态资源
    },
  },
};
module.exports = {
  //...
  output: {
    clean: {
      keep: /ignored\/dir\//, // 保留 'ignored/dir' 下的静态资源
    },
  },
};

// 或者

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

你也可以使用钩子函数:

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 启用 cross-origin 属性 加载 chunk。仅在 target 设置为 'web' 时生效,通过使用 JSONP 来添加脚本标签,实现按需加载模块。

  • 'anonymous' - 不带凭据(credential) 启用跨域加载
  • 'use-credentials' - 携带凭据(credential) 启用跨域加载

output.devtoolFallbackModuleFilenameTemplate

string function (info)

当上面的模板字符串或函数产生重复时使用的备用内容。

查看 output.devtoolModuleFilenameTemplate

output.devtoolModuleFilenameTemplate

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

此选项仅在 「devtool 使用了需要模块名称的选项」时使用。

自定义每个 source map 的 sources 数组中使用的名称。可以通过传递模板字符串(template string)或者函数来完成。例如,当使用 devtool: 'eval',默认值是:

webpack.config.js

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

模板字符串(template string)中做以下替换(通过 webpack 内部的 ModuleFilenameHelpers):

TemplateDescription
[absolute-resource-path]绝对路径文件名
[all-loaders]自动和显式的 loader,并且参数取决于第一个 loader 名称
[hash]模块标识符的 hash
[id]模块标识符
[loaders]显式的 loader,并且参数取决于第一个 loader 名称
[resource]用于解析文件的路径和用于第一个 loader 的任意查询参数
[resource-path]不带任何查询参数,用于解析文件的路径
[namespace]模块命名空间。在构建成为一个 library 之后,通常也是 library 名称,否则为空

当使用一个函数,同样的选项要通过 info 参数并使用驼峰式(camel-cased):

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

如果多个模块产生相同的名称,使用 output.devtoolFallbackModuleFilenameTemplate 来代替这些模块。

output.devtoolNamespace

string

此选项确定 output.devtoolModuleFilenameTemplate 使用的模块名称空间。未指定时的默认值为:output.uniqueName。在加载多个通过 webpack 构建的 library 时,用于防止 source map 中源文件路径冲突。

例如,如果你有两个 library,分别使用命名空间 library1library2,并且都有一个文件 ./src/index.js(可能具有不同内容),它们会将这些文件暴露为 webpack://library1/./src/index.jswebpack://library2/./src/index.js

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]

入口点可用的 library 类型列表.

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

output.enabledWasmLoadingTypes

[string]

用于设置入口支持的 wasm 加载类型的列表。

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

## `output.environment` $#outputenvironment$

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

```javascript
module.exports = {
  output: {
    environment: {
      // The environment supports arrow functions ('() => { ... }').
      arrowFunction: 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 an async import() function to import EcmaScript modules.
      dynamicImport: false,
      // The environment supports 'for of' iteration ('for (const x of array) { ... }').
      forOf: true,
      // The environment supports ECMAScript Module syntax to import ECMAScript modules (import ... from '...').
      module: 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 选项指定的目录下。

对于单个入口起点,filename 会是一个静态名称。

webpack.config.js

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

然而,当通过多个入口起点(entry point)、代码拆分(code splitting)或各种插件(plugin)创建多个 bundle,应该使用以下一种替换方式,来赋予每个 bundle 一个唯一的名称……

使用入口名称:

webpack.config.js

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

使用内部 chunk id

webpack.config.js

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

使用由生成的内容产生的 hash:

webpack.config.js

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

结合多个替换组合使用:

webpack.config.js

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

使用函数返回 filename:

webpack.config.js

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

请确保已阅读过 指南 - 缓存 的详细信息。这里涉及更多步骤,不仅仅是设置此选项。

注意此选项被称为文件名,但是你还是可以使用像 'js/[name]/bundle.js' 这样的文件夹结构。

注意,此选项不会影响那些「按需加载 chunk」的输出文件。它只影响最初加载的输出文件。对于按需加载的 chunk 文件,请使用 output.chunkFilename 选项来控制输出。通过 loader 创建的文件也不受影响。在这种情况下,你必须尝试 loader 特定的可用选项。

Template strings

可以使用以下替换模板字符串(通过 webpack 内部的TemplatedPathPlugin):

可在编译层面进行替换的内容:

模板描述
[fullhash]compilation 完整的 hash 值
[hash]同上,但已弃用

可在 chunk 层面进行替换的内容:

模板描述
[id]此 chunk 的 ID
[name]如果设置,则为此 chunk 的名称,否则使用 chunk 的 ID
[chunkhash]此 chunk 的 hash 值,包含该 chunk 的所有元素
[contenthash]此 chunk 的 hash 值,只包括该内容类型的元素(受 optimization.realContentHash 影响)

可在模块层面替换的内容:

模板描述
[id]模块的 ID
[moduleid]同上,但已弃用
[hash]模块的 Hash 值
[modulehash]同上,但已弃用
[contenthash]模块内容的 Hash 值

可在文件层面替换的内容:

模板描述
[file]filename 和路径,不含 query 或 fragment
[query]带前缀 ? 的 query
[fragment]带前缀 # 的 fragment
[base]只有 filename(包含扩展名),不含 path
[filebase]同上,但已弃用
[path]只有 path,不含 filename
[name]只有 filename,不含扩展名或 path
[ext]带前缀 . 的扩展名(对 output.filename 不可用)

可在 URL 层面替换的内容:

模块描述
[url]URL

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

当你要在实际文件名中使用占位符时,webpack 会过滤出需要替换的占位符。例如,输出一个文件 [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 时,尤其是当 libraryTarget'umd'时,此选项将决定使用哪个全局对象来挂载 library。为了使 UMD 构建在浏览器和 Node.js 上均可用,应将 output.globalObject 选项设置为 'this'。对于类似 web 的目标,默认为 self

入口点的返回值将会使用 output.library.name 赋值给全局对象。依赖于 target 配置项,全局对象将会发生对应的改变,例如:self, global 或者 globalThis

示例:

webpack.config.js

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

output.hashDigest

string = 'hex'

在生成 hash 时使用的编码方式。支持 Node.js hash.digest 的所有编码。对文件名使用 'base64',可能会出现问题,因为 base64 字母表中具有 / 这个字符(character)。同样的,'latin1' 规定可以含有任何字符(character)。

output.hashDigestLength

number = 20

散列摘要的前缀长度。

output.hashFunction

string = 'md4' function

散列算法。支持 Node.JS crypto.createHash 的所有功能。从 4.0.0-alpha2 开始,hashFunction 现在可以是一个返回自定义 hash 的构造函数。出于性能原因,你可以提供一个不加密的哈希函数(non-crypto hash function)。

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

确保 hash 函数有可访问的 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' 时使用,用于加载热更新(hot update)的 JSONP 函数。

JSONP 函数用于异步加载(async load)热更新(hot-update) chunk。

欲了解详情,请查阅 output.chunkLoadingGlobal

output.hotUpdateMainFilename

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

自定义热更新的主文件名(main filename)。[fullhash][runtime] 均可作为占位符。

output.iife

boolean = true

告诉 webpack 添加 IIFE 外层包裹生成的代码.

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

output.importFunctionName

string = 'import'

内部 import() 函数的名称. 可用于 polyfilling, 例如 通过 dynamic-import-polyfill.

webpack.config.js

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

output.library

输出一个库,为你的入口做导出。

  • 类型: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 可以接受 多个入口,例如一个 array 或者一个 object

  1. 如果你将 entry 设置为一个 array,那么只有数组中的最后一个会被暴露。

    module.exports = {
      // …
      entry: ['./src/a.js', './src/b.js'], // 只有在 b.js 中导出的内容才会被暴露
      output: {
        library: 'MyLibrary',
      },
    };
  2. 如果你将 entry 设置为一个 object,所以入口都可以通过 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>

    查看 示例 获取更多内容。

    请注意,如果你打算在每个入口点配置 library 配置项的话,以上配置将不能按照预期执行。这里是如何 在每个入口点下 做的方法:

    module.exports = {
      // …
      entry: {
        main: {
          import: './src/index.js',
          library: {
            // `output.library` 下的所有配置项可以在这里使用
            name: 'MyLibrary',
            type: 'umd',
            umdNamedDefine: true,
          },
        },
        another: {
          import: './src/another.js',
          library: {
            name: 'AnotherLibrary',
            type: 'commonjs2',
          },
        },
      },
    };

output.library.name

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

指定库的名称。

  • 类型:

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

output.library.type

配置将库暴露的方式。

  • 类型:string

    类型默认包括 'var''module''assign''assign-properties''this''window''self''global''commonjs''commonjs2''commonjs-module''commonjs-static''amd''amd-require''umd''umd2''jsonp' 以及 'system',除此之外也可以通过插件添加。

对于接下来的示例,我们将会使用 _entry_return_ 表示被入口点返回的值。

Expose a Variable

These options assign the return value of the entry point (e.g. whatever the entry point exported) to the name provided by output.library.name at whatever scope the bundle was included at.

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

让你的库加载之后,入口起点的返回值 将会被赋值给一个变量:

var MyLibrary = _entry_return_;

// 在加载了 `MyLibrary` 的单独脚本中
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 已经存在的话,它将被重用:

// 仅在当其不存在是创建 MyLibrary
MyLibrary = typeof MyLibrary === 'undefined' ? {} : MyLibrary;
// 然后复制返回值到 MyLibrary
// 与 Object.assign 行为类似

// 例如,你像下面这样在你的入口导出一个 `hello` 函数
export function hello(name) {
  console.log(`Hello ${name}`);
}

// 在另外一个已经加载 MyLibrary 的脚本中
// 你可以像这样运行 `hello` 函数
MyLibrary.hello('World');

Expose Via Object Assignment

这些配置项分配入口点的返回值(例如:无论入口点导出的什么内容)到一个名为 output.library.name 的对象中。

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

入口起点的返回值 将会被赋值给 this 对象下的 output.library.name 属性。this 的含义取决于你:

this['MyLibrary'] = _entry_return_;

// 在一个单独的脚本中
this.MyLibrary.doSomething();
MyLibrary.doSomething(); // 如果 `this` 为 window 对象
type: 'window'
module.exports = {
  // …
  output: {
    library: {
      name: 'MyLibrary',
      type: 'window',
    },
  },
};

入口起点的返回值 将会被赋值给 window 对象下的 output.library.name

window['MyLibrary'] = _entry_return_;

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

入口起点的返回值 将会被复制给全局对象下的 output.library.name。取决于 target 值,全局对象可以分别改变,例如,selfglobal 或者 globalThis

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();

Module Definition Systems

这些配置项将生成一个带有完整 header 的 bundle,以确保与各种模块系统兼容。output.library.name 配置项在不同的 output.library.type 中有不同的含义。

type: 'module'
module.exports = {
  // …
  experiments: {
    outputModule: true,
  },
  output: {
    library: {
      // do not specify a `name` here
      type: '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-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;

Consumption (CommonJS):

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

Consumption (ESM):

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

可以将你的库暴露为 AMD 模块。

AMD module 要求入口 chunk(例如,第一个通过 <script> 标签加载的脚本)使用特定的属性来定义, 例如 definerequire,这通常由 RequireJS 或任何兼容的 loader(如 almond)提供。否则,直接加载产生的 AMD bundle 将导致一个错误,如 define is not defined

按照下面的配置

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

生成的输出将被定义为 "MyLibrary",例如:

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

该 bundle 可以使用 script 标签引入,并且可以被这样引入:

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

如果没有定义 output.library.name 的话,会生成以下内容。

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

如果使用一个 <script> 标签直接加载。它只能通过 RequireJS 兼容的异步模块 loader 通过文件的实际路径工作,所以在这种情况下,如果 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 Repository 获取更多内容。

在这种情况下,你需要使用 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: {
    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];
  }
})(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 bundle 执行时,全局变量 System 出现在浏览器中。编译的 System.register 格式允许你在没有额外配置的情况下使用 System.import('/bundle.js'),并将你的 webpack bundle 加载到系统模块注册表中。

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

输出:

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

除了设置 output.library.typesystem,还要将 output.library.name 添加到配置中,输出的 bundle 将以库名作为 System.register 的参数:

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

Other Types

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

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

MyLibrary(_entry_return_);

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

output.library.export

指定哪一个导出应该被暴露为一个库。

  • 类型:string | string[]

默认为 undefined,将会导出整个(命名空间)对象。下面的例子演示了使用 output.library.type: 'var' 配置项产生的作用。

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

入口起点的默认导出将会被赋值为库名称:

// 如果入口有一个默认导出
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 包装器中添加注释。

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

为每个 umd 类型插入相同的注释,将 auxiliaryComment 设置为 string。

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 将会把 AMD 模块命名为 UMD 构建。否则使用匿名 define

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

AMD module 将会是这样:

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

output.libraryExport

string [string]

通过配置 libraryTarget 决定暴露哪些模块。默认情况下为 undefined,如果你将 libraryTarget 设置为空字符串,则与默认情况具有相同的行为。例如,如果设置为 '',将导出整个(命名空间)对象。下述 demo 演示了当设置 libraryTarget: 'var' 时的效果。

支持以下配置:

libraryExport: 'default' - 入口的默认导出将分配给 library target:

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

libraryExport: 'MyModule' - 这个 确定的模块 将被分配给 library target:

var MyModule = _entry_return_.MyModule;

libraryExport: ['MyModule', 'MySubModule'] - 数组将被解析为要分配给 library target 的 模块路径

var MySubModule = _entry_return_.MyModule.MySubModule;

使用上述指定的 libraryExport 配置时,library 的结果可以这样使用:

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

output.libraryTarget

string = 'var'

配置如何暴露 library。可以使用下面的选项中的任意一个。注意,此选项与分配给 output.library 的值一同使用。对于下面的所有示例,都假定将 output.library 的值配置为 MyLibrary

暴露为一个变量

这些选项将入口起点的返回值(例如,入口起点的任何导出值),在 bundle 包所引入的位置,赋值给 output.library 提供的变量名。

libraryTarget: 'var' $#libraryTarget-var$

当 library 加载完成,入口起点的返回值将分配给一个变量:

var MyLibrary = _entry_return_;

// 在一个单独的 script...
MyLibrary.doSomething();

libraryTarget: 'assign' $#libraryTarget-assign$

这将产生一个隐含的全局变量,可能会潜在地重新分配到全局中已存在的值(谨慎使用):

MyLibrary = _entry_return_;

注意,如果 MyLibrary 在作用域中未在前面代码进行定义,则你的 library 将被设置在全局作用域内。

libraryTarget: 'assign-properties' $#libraryTarget-assign-properties$

5.16.0+

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

// 如果不存在的话就创建目标对象
MyLibrary = typeof MyLibrary === 'undefined' ? {} : MyLibrary;
// 然后复制返回值到 MyLibrary
// 与 Object.assign 行为类似

// 例如,你在入口导出了一个 `hello` 函数
export function hello(name) {
  console.log(`Hello ${name}`);
}

// 在另一个脚本中运行 MyLibrary
// 你可以像这样运行 `hello` 函数
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'

入口起点的返回值将分配给 this 的一个属性(此名称由 output.library 定义)下,this 的含义取决于你:

this['MyLibrary'] = _entry_return_;

// 在一个单独的 script...
this.MyLibrary.doSomething();
MyLibrary.doSomething(); // 如果 this 是 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();

模块定义系统

这些选项将使得 bundle 带有更完整的模块头,以确保与各种模块系统的兼容性。根据 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'

将你的 library 暴露为 AMD 模块。

AMD 模块要求入口 chunk(例如使用 <script> 标签加载的第一个脚本)通过特定的属性定义,例如 definerequire,它们通常由 RequireJS 或任何兼容的模块加载器提供(例如 almond)。否则,直接加载生成的 AMD bundle 将导致报错,如 define is not defined

配置如下:

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

生成的 output 名称将被定义为 "MyLibrary":

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

可以在 script 标签中,将 bundle 作为一个模块整体引入,并且可以像这样调用 bundle:

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

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

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

如果直接加载 <script> 标签,此 bundle 无法按预期运行,或者根本无法正常运行(在 almond loader 中)。只能通过文件的实际路径,在 RequireJS 兼容的异步模块加载器中运行,因此在这种情况下,如果这些设置直接暴露在服务器上,那么 output.pathoutput.filename 对于这个特定的设置可能变得很重要。

libraryTarget: 'amd-require'

这将使用立即执行的 AMD require(dependencies, factory) 包装器包装您的输出。

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

对于此 target,库名称将被忽略。

libraryTarget: 'umd'

将你的 library 暴露为所有的模块定义下都可运行的方式。它将在 CommonJS, AMD 环境下运行,或将模块导出到 global 下的变量。了解更多请查看 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 会导致将入口起点返回的所有属性,直接赋值给 root 对象,就像对象分配章节。例如:

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 指定为一个对象,用于给每个 target 起不同的名称:

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

libraryTarget: 'system'

这将暴露你的 library 作为一个由 System.register 的模块。此特性首次发布于 webpack 4.30.0

当 webpack bundle 被执行时,系统模块依赖全局的变量 System。编译为 System.register 形式后,你可以使用 System.import('/bundle.js') 而无需额外配置,并会将你的 webpack bundle 包加载到系统模块注册表中。

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

输出:

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

除了将 output.libraryTarget 设置为 system 之外,还可将 output.library 添加到配置中,输出 bundle 的 library 名将作为 System.register 的参数:

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

你可以通过 __system_context__ 访问 SystemJS context

// 记录当前系统模块的 URL
console.log(__system_context__.meta.url);

// 导入一个系统模块,通过将当前的系统模块的 url 作为 parentUrl
__system_context__.import('./other-file.js').then((m) => {
  console.log(m);
});

其他 Targets

libraryTarget: 'jsonp'

这将把入口起点的返回值,包裹到一个 jsonp 包装容器中

MyLibrary(_entry_return_);

你的 library 的依赖将由 externals 配置定义。

output.module

boolean = false

以模块类型输出 JavaScript 文件。由于此功能还处于实验阶段,默认禁用。

当启用时,webpack 会在内部将 output.iife 设置为 false,将 output.scriptType'module',并将 terserOptions.module 设置为 true

如果你需要使用 webpack 构建一个库以供别人使用,当 output.moduletrue 时,一定要将 output.libraryTarget 设置为 'module'

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

output.path

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

output 目录对应一个绝对路径

webpack.config.js

const path = require('path');

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

注意,[fullhash] 在参数中被替换为编译过程(compilation)的 hash。详细信息请查看指南 - 缓存

output.pathinfo

boolean=true string: 'verbose'

告知 webpack 在 bundle 中引入「所包含模块信息」的相关注释。此选项在 development 模式时的默认值为 true,而在 production 模式时的默认值为 false。当值为 'verbose' 时,会显示更多信息,如 export,运行时依赖以及 bailouts。

webpack.config.js

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

output.publicPath

  • Type:

    • function

    • string

      targets 设置为 webweb-workeroutput.publicPath 默认为 'auto',查看 该指南 获取其用例

对于按需加载(on-demand-load)或加载外部资源(external resources)(如图片、文件等)来说,output.publicPath 是很重要的选项。如果指定了一个错误的值,则在加载这些资源时会收到 404 错误。

此选项指定在浏览器中所引用的「此输出目录对应的公开 URL」。相对 URL(relative URL) 会被相对于 HTML 页面(或 <base> 标签)解析。相对于服务的 URL(Server-relative URL),相对于协议的 URL(protocol-relative URL) 或绝对 URL(absolute URL) 也可是可能用到的,或者有时必须用到,例如:当将资源托管到 CDN 时。

该选项的值是以 runtime(运行时) 或 loader(载入时) 所创建的每个 URL 的前缀。因此,在多数情况下,此选项的值都会以 / 结束

规则如下:output.path 中的 URL 以 HTML 页面为基准。

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 为基准,使用它来决定在哪个目录下启用服务,来访问 webpack 输出的文件。

注意,参数中的 [fullhash] 将会被替换为编译过程(compilation) 的 hash。详细信息请查看指南 - 缓存

示例:

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(总是 HTTPS 协议)
    publicPath: '//cdn.example.com/assets/', // CDN(协议相同)
    publicPath: '/assets/', // 相对于服务(server-relative)
    publicPath: 'assets/', // 相对于 HTML 页面
    publicPath: '../assets/', // 相对于 HTML 页面
    publicPath: '', // 相对于 HTML 页面(目录相同)
  },
};

在编译时(compile time)无法知道输出文件的 publicPath 的情况下,可以留空,然后在入口文件(entry file)处使用自由变量(free variable) __webpack_public_path__,以便在运行时(runtime)进行动态设置。

__webpack_public_path__ = myRuntimePublicPath;

// 应用程序入口的其他部分

有关 __webpack_public_path__ 的更多信息,请查看此讨论

output.scriptType

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

这个配置项允许使用自定义 script 类型加载异步 chunk,例如 <script type="module" ...>

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

output.sourceMapFilename

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

仅在 devtool 设置为 'source-map' 时有效,此选项会向硬盘写入一个输出文件。

可以使用 #output-filename 中的 [name], [id], [hash][chunkhash] 替换符号。除此之外,还可以使用 Template strings 在 Filename-level 下替换。

output.sourcePrefix

string = ''

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

webpack.config.js

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

output.strictModuleErrorHandling

按照 ES Module 规范处理 module 加载时的错误,会有性能损失。

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

output.strictModuleExceptionHandling

boolean = false

如果一个模块是在 require 时抛出异常,告诉 webpack 从模块实例缓存(require.cache)中删除这个模块。

出于性能原因,默认为 false

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

例如,设想一下 module.js

throw new Error('error');

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

// with strictModuleExceptionHandling = false
require('module'); // <- 抛出
require('module'); // <- 不抛出

相反,将 strictModuleExceptionHandling 设置为 true,这个模块所有的 require 都抛出异常:

// with strictModuleExceptionHandling = true
require('module'); // <- 抛出
require('module'); // <- 仍然抛出

output.trustedTypes

boolean = false string object

5.37.0+

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

默认为 false(不兼容,脚本 URL 为字符串)。

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

webpack.config.js

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

output.umdNamedDefine

boolean

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

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

output.uniqueName

string

在全局环境下为防止多个 webpack 运行时 冲突所使用的唯一名称。默认使用 output.library 名称或者上下文中的 package.json 的 包名称(package name), 如果两者都不存在,值为 ''

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

webpack.config.js

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

output.wasmLoading

boolean = false 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.workerChunkLoading

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

新选项 workerChunkLoading 用于控制 workder 的 chunk 加载。

webpack.config.js

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

Module

这些选项决定了如何处理项目中的不同类型的模块

module.generator

5.12.0+

可以使用 module.generator 在一个地方配置所有生成器的选项。

webpack.config.js

module.exports = {
  module: {
    generator: {
      asset: {
        // asseet 模块的 generator 选项

        // 自定义 asset 模块的 publicPath,自 webpack 5.28.0 起可用
        publicPath: 'assets/',

        // 将静态资源输出到相对于 'output.path' 的指定文件夹中,webpack 5.67.0 后可用
        outputPath: 'cdn-assets/',
      },
      'asset/inline': {
        // asset/内联模块的 generator 选项
      },
      'asset/resource': {
        // asset/资源模块的 generator 选项

        // 自定义 asset/resource 模块的 publicPath,自 webpack 5.28.0 起可用
        publicPath: 'assets/',

        // 将静态资源输出到相对于 'output.path' 的指定文件夹中,webpack 5.67.0 后可用
        outputPath: 'cdn-assets/',
      },
      javascript: {
        // 该模块类型尚不支持 generator 选项
      },
      'javascript/auto': {
        // 同上
      },
      'javascript/dynamic': {
        // 同上
      },
      'javascript/esm': {
        // 同上
      },
      // 其他...
    },
  },
};

module.parser

5.12.0+

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

webpack.config.js

module.exports = {
  module: {
    parser: {
      asset: {
        // 资产模块的 parser 选项
      },
      'asset/inline': {
        // 该模块类型尚不支持 parser 选项
      },
      'asset/resource': {
        // 同上
      },
      'asset/source': {
        // 同上
      },
      javascript: {
        // javascript 模块的解析器选项
        // 例如,启用解析 require.ensure 语法的功能
        requireEnsure: true,
      },
      'javascript/auto': {
        // 同上
      },
      'javascript/dynamic': {
        // 同上
      },
      'javascript/esm': {
        // 同上
      },
      // 其他...
    },
  },
};

module.parser.javascript

JavaScript parser 的配置项。

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.dynamicImportMode

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

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

  • 可用版本:5.73.0+

  • 示例:

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

module.parser.javascript.dynamicImportPrefetch

指定动态导入的全局 prefetch。

  • 类型: number | boolean

  • 可用版本:5.73.0+

  • 示例:

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

module.parser.javascript.dynamicImportPreload

指定动态导入的全局 preload。

  • 类型: 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

Enable or disable evaluating 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.reexportExportsPresence

指出在 \"export ... from ...\" 中无效导出名称的行为。当在 TypeScript 重新导出类型,从 \"export ... from ...\" 迁移到 \"export type ... from ...\" 时禁用该配置项是有用的。

  • 类型:'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
          },
        },
      },
    };

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

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

<!-- without 'relative' -->
<img src="file:///path/to/project/dist/c43188443804f1b1f534.svg" />
  1. 当服务器不知道根 URL 时,这对 SSR(服务端渲染)很有用(而且可用节省一些字节)。为了使其相同,它也必须用于客户端构建。
  2. 这也适用于 SSG(静态网站生成器),mini-css-plugin 和 html-plugin 等通常需要进行服务端渲染。

module.noParse

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

防止 webpack 解析那些任何与给定正则表达式相匹配的文件。忽略的文件中 不应该含有 import, require, define 的调用,或任何其他导入机制。忽略大型的 library 可以提高构建性能。

webpack.config.js

module.exports = {
  //...
  module: {
    noParse: /jquery|lodash/,
  },
};
module.exports = {
  //...
  module: {
    noParse: (content) => /jquery|lodash/.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]

创建模块时,匹配请求的规则数组。这些规则能够修改模块的创建方式。 这些规则能够对模块(module)应用 loader,或者修改解析器(parser)。

Rule

object

每个规则可以分为三部分 - 条件(condition),结果(result)和嵌套规则(nested rule)。

Rule 条件

条件有两种输入值:

  1. resource:资源文件的绝对路径。它已经根据 resolve 规则解析。

  2. issuer: 请求者的文件绝对路径。是导入时的位置。

例如:app.js 导入 './style.css',resource 是 /path/to/style.css. issuer 是 /path/to/app.js

在规则中,属性 test, include, excluderesource 对 resource 匹配,并且属性 issuer 对 issuer 匹配。

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

Rule 结果

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

规则有两种输入值:

  1. 应用的 loader:应用在 resource 上的 loader 数组。
  2. Parser 选项:用于为模块创建解析器的选项对象。

这些属性会影响 loader:loader, options, use

也兼容这些属性:query, loaders

enforce 属性会影响 loader 种类。不论是普通的,前置的,后置的 loader。

parser 属性会影响 parser 选项。

嵌套的 Rule

可以使用属性 rulesoneOf 指定嵌套规则。

这些规则用于在规则条件(rule condition)匹配时进行取值。每个嵌套规则包含它自己的条件。

被解析的顺序基于以下规则:

  1. 父规则
  2. rules
  3. oneOf

Rule.enforce

string

可能的值有:"pre" | "post"

指定 loader 种类。没有值表示是普通 loader。

还有一个额外的种类"行内 loader",loader 被应用在 import/require 行内。

所有一个接一个地进入的 loader,都有两个阶段:

  1. Pitching 阶段: loader 上的 pitch 方法,按照 后置(post)、行内(inline)、普通(normal)、前置(pre) 的顺序调用。更多详细信息,请查看 Pitching Loader
  2. Normal 阶段: loader 上的 常规方法,按照 前置(pre)、普通(normal)、行内(inline)、后置(post) 的顺序调用。模块源码的转换, 发生在这个阶段。

所有普通 loader 可以通过在请求中加上 ! 前缀来忽略(覆盖)。

所有普通和前置 loader 可以通过在请求中加上 -! 前缀来忽略(覆盖)。

所有普通,后置和前置 loader 可以通过在请求中加上 !! 前缀来忽略(覆盖)。

// 禁用普通 loaders
import { a } from '!./file1.js';

// 禁用前置和普通 loaders
import { b } from '-!./file2.js';

// 禁用所有的 laoders
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

一个条件,用来与被发出的 request 对应的模块项匹配。在以下示例中,a.js request 的发出者(issuer) 是 index.js 文件的路径。

index.js

import A from './a.js';

这个选项可以用来将 loader 应用到一个特定模块或一组模块的依赖中。

Rule.issuerLayer

允许按 issuer 的 layer 进行过滤/匹配。

webpack.config.js

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

Rule.layer

string

指定模块应放置在哪个 layer。一组模块可以统一在一个 layer 中,然后可以被用在 split chunksstats 或者 entry options

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 使 rules 配置与 data 的 uri 进行匹配。

webpack.config.js

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

mimetype 已默认包含了 application/jsontext/javascriptapplication/javascriptapplication/node 以及 application/wasm

Rule.oneOf

规则数组,当规则匹配时,只使用第一个匹配规则。

webpack.config.js

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.css$/,
        oneOf: [
          {
            resourceQuery: /inline/, // foo.css?inline
            use: 'url-loader',
          },
          {
            resourceQuery: /external/, // foo.css?external
            use: 'file-loader',
          },
        ],
      },
    ],
  },
};

Rule.options / Rule.query

Rule.optionsRule.queryRule.use: [ { options } ] 的简写。详细请查看 Rule.useUseEntry.options

Rule.parser

解析选项对象。所有应用的解析选项都将合并。

解析器(parser)可以查阅这些选项,并相应地禁用或重新配置。大多数默认插件, 会如下解释值:

  • 将选项设置为 false,将禁用解析器。
  • 将选项设置为 true,或不修改将其保留为 undefined,可以启用解析器。

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

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

module.exports = {
  //...
  module: {
    rules: [
      {
        //...
        parser: {
          amd: false, // 禁用 AMD
          commonjs: false, // 禁用 CommonJS
          system: false, // 禁用 SystemJS
          harmony: false, // 禁用 ES2015 Harmony import/export
          requireInclude: false, // 禁用 require.include
          requireEnsure: false, // 禁用 require.ensure
          requireContext: false, // 禁用 require.context
          browserify: false, // 禁用特殊处理的 browserify bundle
          requireJs: false, // 禁用 requirejs.*
          node: false, // 禁用 __dirname, __filename, module, require.extensions, require.main, 等。
          commonjsMagicComments: false, // 禁用对 CommonJS 的  magic comments 支持
          node: {}, // 在模块级别(module level)上重新配置 node 层(layer)
          worker: ['default from web-worker', '...'], // 自定义 WebWorker 对 JavaScript 的处理,其中 "..." 为默认值。
        },
      },
    ],
  },
};

如果 Rule.type 的值为 asset,那么 Rules.parser 选项可能是一个对象或一个函数,其作用可能是将文件内容编码为 Base64,还可能是将其当做单独文件 emit 到输出目录。

如果 Rule.type 的值为 assetasset/inline,那么 Rule.generator 选项可能是一个描述模块源编码方式的对象,还可能是一个通过自定义算法对模块源代码进行编码的函数。

更多信息及用例请查阅 Asset 模块指南

Rule.parser.dataUrlCondition

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

如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。

webpack.config.js

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

当提供函数时,返回 true 值时告知 webpack 将模块作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。

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',模块源码会用 Baes64 算法 编码。设置 encoding 为 false,会禁用编码。
  • mimetype: 为数据链接(data URI)设置的一个 mimetype 值。默认根据模块资源后缀设置。

webpack.config.js

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

当被作为一个函数使用,它必须为每个模块执行且并须返回一个数据链接(data 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

配置不从 Asset Modules 写入资源文件, 你可能会在 SSR 中使用它。

  • 类型: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

条件会匹配 resource。在 Rule 条件 中查阅详情。

Rule.resourceQuery

与资源查询相匹配的 Condition。此选项用于测试请求字符串的查询部分(即从问号开始)。如果你需要通过 import Foo from './foo.css?inline' 导入 Foo,则需符合以下条件:

webpack.config.js

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.css$/,
        resourceQuery: /inline/,
        use: 'url-loader',
      },
    ],
  },
};

Rule.parser.parse

function(input) => string | object

如果 Rule.type 被设置成 'json',那么 Rules.parser.parse 选择可能会是一个方法,该方法实现自定义的逻辑,以解析模块的源和并将它转换成 JavaScript 对象。 它可能在没有特定加载器的时候,对将 toml, yaml 和其它非 JSON 文件导入成导入非常有用:

webpack.config.js

const toml = require('toml');

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

Rule.rules

规则数组,当规则匹配时使用。

Rule.scheme

匹配使用的 schema,例如 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

bool

表明模块的哪一部份包含副作用。请参阅 Tree Shaking 以了解更多信息。

Rule.test

引入所有通过断言测试的模块。如果你提供了一个 Rule.test 选项,就不能再提供 Rule.resource。详细请查看 Rule.resourceCondition.test

Rule.type

string

可设置值: 'javascript/auto' | 'javascript/dynamic' | 'javascript/esm' | 'json' | 'webassembly/sync' | 'webassembly/async' | 'asset' | 'asset/source' | 'asset/resource' | 'asset/inline'

Rule.type 设置类型用于匹配模块。它防止了 defaultRules 和它们的默认导入行为发生。例如,如果你想 通过自定义 loader 加载一个 .json 文件,你会需要将 type 设置为 javascript/auto 以绕过 webpack 内置的 json 导入。 (详参v4.0 更新日志

webpack.config.js

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

关于 asset* 类型详参 资源模块指南

Rule.use

[UseEntry] function(info)

[UseEntry]

Rule.use 可以是一个应用于模块的 UseEntries 数组。每个入口(entry)指定使用一个 loader。

传递字符串(如:use: [ 'style-loader' ])是 loader 属性的简写方式(如:use: [ { loader: 'style-loader'} ])。

Loaders 可以通过传入多个 loaders 以达到链式调用的效果,它们会从右到左被应用(从最后到最先配置)。

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: 模块的路径,该元素正在导入一个被加载的模块(resource)
  • realResource: 总会是被加载模块的路径
  • resource: 被加载的模块路径,它常常与 realResource 相等,只有当资源名称被 request 字符串中的 !=! 覆盖时才不相等

相同的作为数组的快捷方式可以用作返回值(如 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 选项被更高层级的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',
    },
  },
};

当用该配置创建一个包,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',
          },
        },
      },
    ],
  },
};

当用该配置创建一个包,console.log(footer) 会输出 'overridden footer'。

resolve.fullySpecified

boolean = true

启用后,你若在 .mjs 文件或其他 .js 文件中导入模块,并且它们最近的 package.json 中包含 "type" 字段,其值为 "module"时,你应为此文件提供扩展名,否则 webpack 会提示 Module not found 的错误且编译失败。并且 webpack 不会解析 resolve.mainFiles 中定义的文件目录,你必须自己指定文件名。

webpack.config.js

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

Condition

条件可以是这些之一:

  • 字符串:匹配输入必须以提供的字符串开始。是的。目录绝对路径或文件绝对路径。
  • 正则表达式:test 输入值。
  • 函数:调用输入的函数,必须返回一个真值(truthy value)以匹配。
  • 条件数组:至少一个匹配条件。
  • 对象:匹配所有属性。每个属性都有一个定义行为。

{ 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 属性是字符串。它使用 loader 解析选项(resolveLoader),相对于配置中的 context 来解析。

可以有一个 options 属性为字符串或对象。值可以传递到 loader 中,将其理解为 loader 选项。

由于兼容性原因,也可能有 query 属性,它是 options 属性的别名。使用 options 属性替代。

注意,webpack 需要生成资源和所有 loader 的独立模块标识,包括选项。 它尝试对选项对象使用 JSON.stringify。这在 99.9% 的情况下是可以的, 但是如果将相同的 loader 应用于相同资源的不同选项,并且选项具有一些带字符的值,则可能不是唯一的。

如果选项对象不被字符化(例如循环 JSON),它也会中断。因此,你可以在选项对象使用 ident 属性, 作为唯一标识符。

webpack.config.js

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

function(info)

UseEntry 也可以是一个函数,接受对象参数,描述被加载的模块,而且必须返回一个参数对象。这可用于按模块更改 loader 选项。

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

  • compiler: 当前 webpack 的编译器(可以是 undefined 值)
  • issuer: 模块的路径,该元素正在导入一个被加载的模块(resource)
  • realResource: 总会是被加载模块的路径
  • resource: 被加载的模块路径,它常常与 realResource 相等,只有当资源名称被 request 字符串中的 !=! 覆盖时才不相等

webpack.config.js

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

模块上下文(Module Contexts)

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

例如,未知的(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: /\\.\\*/

解析(Resolve)

这些选项能设置模块如何被解析。webpack 提供合理的默认值,但是还是可能会修改一些解析的细节。关于 resolver 具体如何工作的更多解释说明,请查看模块解析

resolve

object

配置模块如何解析。例如,当在 ES2015 中调用 import 'lodash'resolve 选项能够对 webpack 查找 'lodash' 的方式去做修改(查看模块)。

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'; // 精确匹配,所以 path/to/file.js 被解析和导入
import Test2 from 'xyz/file.js'; // 非精确匹配,触发普通解析

下面的表格展示了一些其他情况:

alias:import '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

如果在 package.json 中定义,index.js 可能会被解析为另一个文件。

/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.cacheWithContext

boolean

如果启用了不安全缓存,请在缓存键(cache key)中引入 request.context。这个选项被 enhanced-resolve 模块考虑在内。从 webpack 3.1.0 开始,在配置了 resolve 或 resolveLoader 插件时,解析缓存(resolve caching)中的上下文(context)会被忽略。这解决了性能衰退的问题。

resolve.conditionNames

string[]

exports 配置项 (定义一个库的入口)的 conditionName。

webpack.config.js

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

Webpack 将会匹配列在 resolve.conditionNames 数组中的 export conditions

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'],
  },
};

importing

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

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.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 在 webpack 5 之前使用过的 polyfill 包列表:

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.mainFields

[string]

当从 npm 包中导入模块时(例如,import * as D3 from 'd3'),此选项将决定在 package.json 中使用哪个字段导入模块。根据 webpack 配置中指定的 target 不同,默认值也会有所不同。

target 属性设置为 webworker, web 或者没有指定:

webpack.config.js

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

对于其他任意的 target(包括 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.exportsFields

[string] = ['exports']

在 package.json 中用于解析模块请求的字段。欲了解更多信息,请查阅 package-exports guideline 文档。

webpack.config.js

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

resolve.modules

[string] = ['node_modules']

告诉 webpack 解析模块时应该搜索的目录。

绝对路径和相对路径都能使用,但是要知道它们之间有一点差异。

通过查看当前目录以及祖先路径(即 ./node_modules, ../node_modules 等等), 相对路径将类似于 Node 查找 '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.unsafeCache

RegExp [RegExp] boolean: true

启用,会主动缓存模块,但并 不安全。传递 true 将缓存一切。

webpack.config.js

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

正则表达式,或正则表达式数组,可以用于匹配文件路径或只缓存某些模块。 例如,只缓存 utilities 模块:

webpack.config.js

module.exports = {
  //...
  resolve: {
    unsafeCache: /src\/utilities/,
  },
};

resolve.useSyncFileSystemCalls

boolean

对 resolver 使用同步文件系统调用。

webpack.config.js

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

resolve.plugins

[Plugin]

应该使用的额外的解析插件列表。 它允许插件,如 DirectoryNamedWebpackPlugin

webpack.config.js

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

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.preferAbsolute

boolean

5.13.0+

解析时,首选的绝对路径为 resolve.roots

webpack.config.js

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

resolve.symlinks

boolean = true

是否将符号链接(symlink)解析到它们的符号链接位置(symlink location)。

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

webpack.config.js

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

resolve.cachePredicate

function(module) => boolean

决定请求是否应该被缓存的函数。函数传入一个带有 pathrequest 属性的对象。 必须返回一个 boolean 值。

webpack.config.js

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

resolve.restrictions

[string, RegExp]

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

webpack.config.js

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

resolve.roots

[string]

A list of directories where requests of server-relative URLs (starting with '/') are resolved, defaults to context configuration option. On non-Windows systems these requests are resolved as an absolute path first.

webpack.config.js

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

resolve.importsFields

[string]

Fields from package.json which are used to provide the internal requests of a package (requests starting with # are considered internal).

webpack.config.js

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

resolve.byDependency

通过 module 请求类型来配置 resolve 选项。

  • Type: [type: string]: ResolveOptions

  • Example:

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

resolveLoader

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

这组选项与上面的 resolve 对象的属性集合相同, 但仅用于解析 webpack 的 loader 包。

webpack.config.js

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

优化(Optimization)

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

optimization.chunkIds

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

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

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

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

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

webpack.config.js

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

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

webpack.config.js

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

optimization.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.flagIncludedChunks

boolean

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

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 允许控制导出处理(export mangling)。

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

此选项支持以下选项:

选项描述
'size'简写形式 — 通常只有一个字符 — 专注于最小的下载 size。
'deterministic'简写形式 - 通常两个字符 — 在添加或移除 export 时不会改变。适用于长效缓存。
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 使用 TerserPlugin 或其它在 optimization.minimizer定义的插件压缩 bundle。

webpack.config.js

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

optimization.minimizer

[TerserPlugin][function (compiler)]

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

webpack.config.js

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

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

或,使用函数的形式:

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

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

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

optimization.moduleIds

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

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

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

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

webpack.config.js

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

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

webpack.config.js

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

optimization.nodeEnv

boolean = false string

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

可能的值有:

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

webpack.config.js

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

optimization.portableRecords

boolean

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

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

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 = true

在处理静态资源后添加额外的哈希编译,以获得正确的静态资源内容哈希。如果 realContentHash 设置为 false,内部数据用于计算哈希值,当静态资源相同时,它可以改变。

webpack.config.js

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

optimization.removeAvailableModules

boolean = false

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

webpack.config.js

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

optimization.removeEmptyChunks

boolean = true

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

webpack.config.js

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

optimization.runtimeChunk

object string boolean

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

webpack.config.js

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

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

webpack.config.js

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

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

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

webpack.config.js

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

optimization.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,
  },
};

如果不想要分析源码,那么可以将其指定为 flag

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

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

optimization.splitChunks

object

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

optimization.usedExports

boolean = true string: 'global'

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

webpack.config.js

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

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

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

插件(Plugins)

plugins 选项用于以各种方式自定义 webpack 构建过程。webpack 附带了各种内置插件,可以通过 webpack.[plugin-name] 访问这些插件。请查看 插件页面 获取插件列表和对应文档,但请注意这只是其中一部分,社区中还有许多插件。

plugins

[Plugin]

一组 webpack 插件。例如,DefinePlugin 允许你创建可在编译时配置的全局常量。这对需要再开发环境构建和生产环境构建之间产生不同行为来说非常有用。

webpack.config.js

module.exports = {
  //...
  plugins: [
    new webpack.DefinePlugin({
      // Definitions...
    }),
  ],
};

一个复杂示例,使用多个插件,可能看起来就像这样:

webpack.config.js

var webpack = require('webpack');
// 导入非 webpack 自带默认插件
var DashboardPlugin = require('webpack-dashboard/plugin');

// 在配置中添加插件
module.exports = {
  //...
  plugins: [
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
   // 编译时(compile time)插件
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': '"production"',
    }),
   // webpack-dev-server 强化插件
    new DashboardPlugin(),
    new webpack.HotModuleReplacementPlugin(),
  ],
};

DevServer

webpack-dev-server 可用于快速开发应用程序。请查阅 开发指南 开始使用。

当前页面记录了影响 webpack-dev-server (简写: dev-server) version >= 4.0.0 配置的选项。可以在 这里 找到 v3v4 的迁移指南

devServer

object

通过 webpack-dev-server 的这些配置,能够以多种方式改变其行为。这是一个基本的示例,利用 gzips 压缩 public/ 目录当中的所有内容并提供一个本地服务(serve):

webpack.config.js

const path = require('path');

module.exports = {
  //...
  devServer: {
    static: {
      directory: path.join(__dirname, 'public'),
    },
    compress: true,
    port: 9000,
  },
};

当服务(server)启动后,在解析模块列表之前输出一条消息:

<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: http://localhost: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。

Usage via CLI

你可以通过 CLI 调用 webpack-dev-server,方式是:

npx webpack serve

CLI 配置项列表可以在 这里 查询。

Usage via API

虽然推荐通过 CLI 运行 webpack-dev-server,但是你也可以通过 API 来启用服务器。

查看相关的 webpack-dev-server API 文档

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.com 以及 host.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' 时会跳过 host 检查。并不推荐这样做,因为不检查 host 的应用程序容易受到 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,
  },
};

通过命令行使用:

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',
    },
  },
};

通过命令行使用:

npx webpack serve --client-logging info

overlay

boolean = true object: { errors boolean = true, warnings boolean = true }

当出现编译错误或警告时,在浏览器中显示全屏覆盖。

webpack.config.js

module.exports = {
  //...
  devServer: {
    client: {
      overlay: true,
    },
  },
};

通过命令行使用:

npx webpack serve --client-overlay

如需禁用:

npx webpack serve --no-client-overlay

如果你只想显示错误信息:

webpack.config.js

module.exports = {
  //...
  devServer: {
    client: {
      overlay: {
        errors: true,
        warnings: false,
      },
    },
  },
};

通过命令行使用:

npx webpack serve --client-overlay-errors --no-client-overlay-warnings

progress

boolean

在浏览器中以百分比显示编译进度。

webpack.config.js

module.exports = {
  //...
  devServer: {
    client: {
      progress: true,
    },
  },
};

通过命令行使用:

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',
  },
};

通过命令行使用:

npx webpack serve --client-web-socket-transport ws --web-socket-server 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

这个选项允许指定 URL 到 web socket 服务器(当你代理开发服务器和客户端脚本不总是知道连接到哪里时很有用)。

webpack.config.js

module.exports = {
  //...
  devServer: {
    client: {
      webSocketURL: 'ws://0.0.0.0:8080/ws',
    },
  },
};

通过命令行使用:

npx webpack serve --client-web-socket-url ws://0.0.0.0:8080/ws

您还可以指定具有以下属性的对象:

  • hostname: 告诉连接到 devServer 的客户端使用提供的 hostname 进行连接。
  • 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 compression

webpack.config.js

module.exports = {
  //...
  devServer: {
    compress: true,
  },
};

通过命令行使用:

npx webpack serve --compress

如需禁用

npx webpack serve --no-compress

devServer.devMiddleware

object

webpack-dev-middleware 提供处理 webpack 资源的配置项。

webpack.config.js

module.exports = {
  devServer: {
    devMiddleware: {
      index: true,
      mimeTypes: { phtml: 'text/html' },
      publicPath: '/publicPathForDevServe',
      serverSideRender: true,
      writeToDisk: true,
    },
  },
};

devServer.http2

boolean

使用 spdy 提供 HTTP/2 服务。对于 Node 15.0.0 及更高版本,此选项将被忽略,因为 spdy 在这些版本中已被破坏。一旦 Express 支持,开发服务器将迁移到 Node 内置的 HTTP/2。

HTTP/2 带有自签名证书:

webpack.config.js

module.exports = {
  //...
  devServer: {
    http2: true,
  },
};

通过 CLI 使用:

npx webpack serve --http2

禁用:

npx webpack serve --no-http2

通过 https 配置你自己的证书文件:

webpack.config.js

const fs = require('fs');

module.exports = {
  //...
  devServer: {
    http2: true,
    https: {
      key: fs.readFileSync('/path/to/server.key'),
      cert: fs.readFileSync('/path/to/server.crt'),
      ca: fs.readFileSync('/path/to/ca.pem'),
    },
  },
};

要通过 CLI 使用你的证书,请使用以下配置项:

npx webpack serve --http2 --https-key ./path/to/server.key --https-cert ./path/to/server.crt --https-ca ./path/to/ca.pem

devServer.https

boolean object

默认情况下,开发服务器将通过 HTTP 提供服务。可以选择使用 HTTPS 提供服务:

webpack.config.js

module.exports = {
  //...
  devServer: {
    https: true,
  },
};

通过 CLI 使用:

npx webpack serve --https

禁用:

npx webpack serve --no-https

根据上述配置,将使用自签名证书,但是你也可以提供自己的证书:

webpack.config.js

module.exports = {
  devServer: {
    https: {
      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,
    },
  },
};

该对象直接传递到 Node.js HTTPS 模块,因此请参阅 HTTPS documentation 以获取更多信息。

要通过 CLI 使用自己的证书,请使用以下选项:

npx webpack serve --https-request-cert --https-key ./path/to/server.key --https-cert ./path/to/server.crt --https-ca ./path/to/ca.pem --https-pfx ./path/to/server.pfx --https-passphrase webpack-dev-server

webpack-dev-server >= v4.2.0 允许你设置额外的 TLS 配置项,比如 minVersion。同样你可以直接传递各自文件的内容:

webpack.config.js

const fs = require('fs');
const path = require('path');

module.exports = {
  devServer: {
    https: {
      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.headers

array function object

为所有响应添加 headers:

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

When using the HTML5 History API, the index.html page will likely have to be served in place of any 404 responses. Enable devServer.historyApiFallback by setting it to 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,
    },
  },
};

For more options and information, see the connect-history-api-fallback documentation.

devServer.host

'local-ip' | 'local-ipv4' | 'local-ipv6' string

指定要使用的 host。如果你想让你的服务器可以被外部访问,像这样指定:

webpack.config.js

module.exports = {
  //...
  devServer: {
    host: '0.0.0.0',
  },
};

通过命令行使用:

npx webpack serve --host 0.0.0.0

这也适用于 IPv6:

npx webpack serve --host ::

local-ip

Specifying local-ip as host will try to resolve the host option as your local IPv4 address if available, if IPv4 is not available it will try to resolve your local IPv6 address.

npx webpack serve --host local-ip

local-ipv4

Specifying local-ipv4 as host will try to resolve the host option as your local IPv4 address.

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,
  },
};

通过命令行使用:

npx webpack serve --hot

如需禁用:

npx webpack serve --no-hot

启用模块热替换功能,在构建失败时不刷新页面作为回退,使用 hot: 'only'

webpack.config.js

module.exports = {
  //...
  devServer: {
    hot: 'only',
  },
};

通过命令行使用:

npx webpack serve --hot only

devServer.ipc

true string

The Unix socket to listen to (instead of a host).

将其设置为 true 将会监听 /your-os-temp-dir/webpack-dev-server.sock 的 socket:

webpack.config.js

module.exports = {
  //...
  devServer: {
    ipc: true,
  },
};

通过命令行使用:

npx webpack serve --ipc

你也可以这样监听一个不同的 socket:

webpack.config.js

const path = require('path');

module.exports = {
  //...
  devServer: {
    ipc: path.join(__dirname, 'my-socket.sock'),
  },
};

devServer.liveReload

boolean = true

默认情况下,当监听到文件变化时 dev-server 将会重新加载或刷新页面。为了 liveReload 能够生效,devServer.hot 配置项必须禁用或者 devServer.watchFiles 配置项必须启用。将其设置为 false 以禁用 devServer.liveReload

webpack.config.js

module.exports = {
  //...
  devServer: {
    liveReload: false,
  },
};

通过命令行使用:

npx webpack serve --live-reload

禁用该功能:

npx webpack serve --no-live-reload

devServer.magicHtml

boolean = true

v4.1.0+

Tell dev-server to enable/disable magic HTML routes (routes corresponding to your webpack output, for example /main for main.js).

webpack.config.js

module.exports = {
  //...
  devServer: {
    magicHtml: true,
  },
};

通过 CLI 使用:

npx webpack serve --magic-html

禁用:

npx webpack serve --no-magic-html

devServer.onAfterSetupMiddleware

function (devServer)

提供服务器内部在所有其他中间件之后执行 自定义中间件的能力

webpack.config.js

module.exports = {
  //...
  devServer: {
    onAfterSetupMiddleware: function (devServer) {
      if (!devServer) {
        throw new Error('webpack-dev-server is not defined');
      }

      devServer.app.get('/some/path', function (req, res) {
        res.json({ custom: 'response' });
      });
    },
  },
};

devServer.onBeforeSetupMiddleware

function (devServer)

提供在服务器内部执行所有其他中间件之前执行自定义中间件的能力。 这可以用来定义自定义处理程序, 例如:

webpack.config.js

module.exports = {
  //...
  devServer: {
    onBeforeSetupMiddleware: function (devServer) {
      if (!devServer) {
        throw new Error('webpack-dev-server is not defined');
      }

      devServer.app.get('/some/path', function (req, res) {
        res.json({ custom: 'response' });
      });
    },
  },
};

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,
  },
};

通过命令行使用:

npx webpack serve --open

如需禁用:

npx webpack serve --no-open

在浏览器中打开指定页面:

webpack.config.js

module.exports = {
  //...
  devServer: {
    open: ['/my-page'],
  },
};

通过命令行使用:

npx webpack serve --open /my-page

在浏览器中打开多个指定页面:

webpack.config.js

module.exports = {
  //...
  devServer: {
    open: ['/my-page', '/another-page'],
  },
};

通过命令行使用:

npx webpack serve --open /my-page --open /another-page

提供要使用的浏览器名称,而不是默认名称:

webpack.config.js

module.exports = {
  //...
  devServer: {
    open: {
      app: {
        name: 'google-chrome',
      },
    },
  },
};

通过命令行使用:

npx webpack serve --open-app-name 'google-chrome'

该对象接收所有 open 配置项:

webpack.config.js

module.exports = {
  //...
  devServer: {
    open: {
      target: ['first.html', 'http://localhost:8080/second.html'],
      app: {
        name: 'google-chrome',
        arguments: ['--incognito', '--new-window'],
      },
    },
  },
};

devServer.port

'auto' string number

指定监听请求的端口号:

webpack.config.js

module.exports = {
  //...
  devServer: {
    port: 8080,
  },
};

通过命令行使用:

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 [object, function]

当拥有单独的 API 后端开发服务器并且希望在同一域上发送 API 请求时,代理某些 URL 可能会很有用。

开发服务器使用功能强大的 http-proxy-middleware 软件包。 查看其 documentation 了解更多高级用法。 请注意,http-proxy-middleware 的某些功能不需要target键,例如 它的 router 功能,但是仍然需要在此处的配置中包含target,否则webpack-dev-server 不会将其传递给 http-proxy-middleware

使用后端在 localhost:3000 上,可以使用它来启用代理:

webpack.config.js

module.exports = {
  //...
  devServer: {
    proxy: {
      '/api': 'http://localhost:3000',
    },
  },
};

现在,对 /api/users 的请求会将请求代理到 http://localhost:3000/api/users

如果不希望传递/api,则需要重写路径:

webpack.config.js

module.exports = {
  //...
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        pathRewrite: { '^/api': '' },
      },
    },
  },
};

默认情况下,将不接受在 HTTPS 上运行且证书无效的后端服务器。 如果需要,可以这样修改配置:

webpack.config.js

module.exports = {
  //...
  devServer: {
    proxy: {
      '/api': {
        target: 'https://other-server.example.com',
        secure: false,
      },
    },
  },
};

有时不想代理所有内容。 可以基于函数的返回值绕过代理。

在该功能中,可以访问请求,响应和代理选项。

  • 返回 nullundefined 以继续使用代理处理请求。
  • 返回 false 会为请求产生 404 错误。
  • 返回提供服务的路径,而不是继续代理请求。

例如。 对于浏览器请求,想要提供 HTML 页面,但是对于 API 请求,想要代理它。 可以执行以下操作:

webpack.config.js

module.exports = {
  //...
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost: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: 'http://localhost:3000',
      },
    ],
  },
};

请注意,默认情况下不会代理对 root 的请求。 要启用根代理,应将 devMiddleware.index 选项指定为虚假值:

webpack.config.js

module.exports = {
  //...
  devServer: {
    devMiddleware: {
      index: false, // specify to enable root proxying
    },
    proxy: {
      context: () => true,
      target: 'http://localhost:1234',
    },
  },
};

默认情况下,代理时会保留主机头的来源,可以将 changeOrigin 设置为 true 以覆盖此行为。 在某些情况下,例如使用 name-based virtual hosted sites,它很有用。

webpack.config.js

module.exports = {
  //...
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost: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

It also allows you to set additional TLS options like minVersion and you can directly pass the contents of respective files:

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');
      });

      // 如果你想在所有其他中间件之前运行一个中间件或者当你从 `onBeforeSetupMiddleware` 配置项迁移时,
      // 可以使用 `unshift` 方法
      middlewares.unshift({
        name: 'first-in-array',
        // `path` 是可选的
        path: '/foo/path',
        middleware: (req, res) => {
          res.send('Foo!');
        },
      });

      // 如果你想在所有其他中间件之后运行一个中间件或者当你从 `onAfterSetupMiddleware` 配置项迁移时,
      // 可以使用 `push` 方法
      middlewares.push({
        name: 'hello-world-test-one',
        // `path` 是可选的
        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 将会被用来决定应该从哪里提供 bundle,并具有优先级。

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 }

告诉开发服务器启用后使用 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

通过 static.directory 配置项告诉 dev-server 监听文件。默认启用,文件更改将触发整个页面重新加载。可以通过将 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' 时生效。这需要将数据复制到更小的缓冲区中,并有性能成本。

  • Type: boolean
    • It defaults to false in production mode and true in development mode.
  • 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],
      // 默认情况下 webpack 与 loader 是构建依赖。
    },
  },
};

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+

用于缓存文件的压缩类型。development 模式下默认为 falseproduction 模式下默认为 'gzip'

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 $#cachemaxMemorygenerations$

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.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:
  # 兜底使用 "main" 分支缓存,要求 GitLab Runner 版本为 13.4
  CACHE_FALLBACK_KEY: main

# 这是 webpack 构建任务
build-job:
  cache:
    key: '$CI_COMMIT_REF_SLUG' # 分支/tag 名称
    paths:
      # 缓存文件夹
      # 确保在这个任务中没有运行 "npm ci" 或者更改默认缓存文件夹
      # 否则 "npm ci" 将会删除缓存文件
      - node_modules/.cache/webpack/

Github actions

- uses: actions/cache@v3
  with:
    # 缓存文件夹
    path: node_modules/.cache/webpack/
    key: ${{ GITHUB_REF_NAME }}-webpack-build
    # 兜底使用 "main" 分支缓存
    restore-keys: |
      main-webpack-build

Devtool

此选项控制是否生成,以及如何生成 source map。

使用 SourceMapDevToolPlugin 进行更细粒度的配置。查看 source-map-loader 来处理已有的 source map。

devtool

string = 'eval' false

选择一种 source map 风格来增强调试过程。不同的值会明显影响到构建(build)和重新构建(rebuild)的速度。

devtoolperformanceproductionqualitycomment
(none)build: fastest

rebuild: fastest
yesbundleRecommended choice for production builds with maximum performance.
evalbuild: fast

rebuild: fastest
nogeneratedRecommended choice for development builds with maximum performance.
eval-cheap-source-mapbuild: ok

rebuild: fast
notransformedTradeoff choice for development builds.
eval-cheap-module-source-mapbuild: slow

rebuild: fast
nooriginal linesTradeoff choice for development builds.
eval-source-mapbuild: slowest

rebuild: ok
nooriginalRecommended choice for development builds with high quality SourceMaps.
cheap-source-mapbuild: ok

rebuild: slow
notransformed
cheap-module-source-mapbuild: slow

rebuild: slow
nooriginal lines
source-mapbuild: slowest

rebuild: slowest
yesoriginalRecommended choice for production builds with high quality SourceMaps.
inline-cheap-source-mapbuild: ok

rebuild: slow
notransformed
inline-cheap-module-source-mapbuild: slow

rebuild: slow
nooriginal lines
inline-source-mapbuild: slowest

rebuild: slowest
nooriginalPossible choice when publishing a single file
eval-nosources-cheap-source-mapbuild: ok

rebuild: fast
notransformedsource code not included
eval-nosources-cheap-module-source-mapbuild: slow

rebuild: fast
nooriginal linessource code not included
eval-nosources-source-mapbuild: slowest

rebuild: ok
nooriginalsource code not included
inline-nosources-cheap-source-mapbuild: ok

rebuild: slow
notransformedsource code not included
inline-nosources-cheap-module-source-mapbuild: slow

rebuild: slow
nooriginal linessource code not included
inline-nosources-source-mapbuild: slowest

rebuild: slowest
nooriginalsource code not included
nosources-cheap-source-mapbuild: ok

rebuild: slow
notransformedsource code not included
nosources-cheap-module-source-mapbuild: slow

rebuild: slow
nooriginal linessource code not included
nosources-source-mapbuild: slowest

rebuild: slowest
yesoriginalsource code not included
hidden-nosources-cheap-source-mapbuild: ok

rebuild: slow
notransformedno reference, source code not included
hidden-nosources-cheap-module-source-mapbuild: slow

rebuild: slow
nooriginal linesno reference, source code not included
hidden-nosources-source-mapbuild: slowest

rebuild: slowest
yesoriginalno reference, source code not included
hidden-cheap-source-mapbuild: ok

rebuild: slow
notransformedno reference
hidden-cheap-module-source-mapbuild: slow

rebuild: slow
nooriginal linesno reference
hidden-source-mapbuild: slowest

rebuild: slowest
yesoriginalno reference. Possible choice when using SourceMap only for error reporting purposes.
shortcutexplanation
performance: buildHow is the performance of the initial build affected by the devtool setting?
performance: rebuildHow is the performance of the incremental build affected by the devtool setting? Slow devtools might reduce development feedback loop in watch mode. The scale is different compared to the build performance, as one would expect rebuilds to be faster than builds.
productionDoes it make sense to use this devtool for production builds? It's usually no when the devtool has a negative effect on user experience.
quality: bundledYou will see all generated code of a chunk in a single blob of code. This is the raw output file without any devtooling support
quality: generatedYou will see the generated code, but each module is shown as separate code file in browser devtools.
quality: transformedYou will see generated code after the preprocessing by loaders but before additional webpack transformations. Only source lines will be mapped and column information will be discarded resp. not generated. This prevents setting breakpoints in the middle of lines which doesn't work together with minimizer.
quality: original linesYou will see the original code that you wrote, assuming all loaders support SourceMapping. Only source lines will be mapped and column information will be discarded resp. not generated. This prevents setting breakpoints in the middle of lines which doesn't work together with minimizer.
quality: originalYou will see the original code that you wrote, assuming all loaders support SourceMapping.
eval-* additiongenerate SourceMap per module and attach it via eval. Recommended for development, because of improved rebuild performance. Note that there is a windows defender issue, which causes huge slowdown due to virus scanning.
inline-* additioninline the SourceMap to the original file instead of creating a separate file.
hidden-* additionno reference to the SourceMap added. When SourceMap is not deployed, but should still be generated, e. g. for error reporting purposes.
nosources-* additionsource code is not included in SourceMap. This can be useful when the original files should be referenced (further config options needed).

其中一些值适用于开发环境,一些适用于生产环境。对于开发环境,通常希望更快速的 source map,需要添加到 bundle 中以增加体积为代价,但是对于生产环境,则希望更精准的 source map,需要从 bundle 中分离并独立存在。

品质说明(quality)

打包后的代码 - 将所有生成的代码视为一大块代码。你看不到相互分离的模块。

生成后的代码 - 每个模块相互分离,并用模块名称进行注释。可以看到 webpack 生成的代码。示例:你会看到类似 var module__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(42); module__WEBPACK_IMPORTED_MODULE_1__.a();,而不是 import {test} from "module"; test();

转换过的代码 - 每个模块相互分离,并用模块名称进行注释。可以看到 webpack 转换前、loader 转译后的代码。示例:你会看到类似 import {test} from "module"; var A = function(_test) { ... }(test);,而不是 import {test} from "module"; class A extends test {}

原始源代码 - 每个模块相互分离,并用模块名称进行注释。你会看到转译之前的代码,正如编写它时。这取决于 loader 支持。

无源代码内容 - source map 中不包含源代码内容。浏览器通常会尝试从 web 服务器或文件系统加载源代码。你必须确保正确设置 output.devtoolModuleFilenameTemplate,以匹配源代码的 url。

(仅限行) - source map 被简化为每行一个映射。这通常意味着每个语句只有一个映射(假设你使用这种方式)。这会妨碍你在语句级别上调试执行,也会妨碍你在每行的一些列上设置断点。与压缩后的代码组合后,映射关系是不可能实现的,因为压缩工具通常只会输出一行。

对于开发环境

以下选项非常适合开发环境:

eval - 每个模块都使用 eval() 执行,并且都有 //# sourceURL。此选项会非常快地构建。主要缺点是,由于会映射到转换后的代码,而不是映射到原始代码(没有从 loader 中获取 source map),所以不能正确的显示行数。

eval-source-map - 每个模块使用 eval() 执行,并且 source map 转换为 DataUrl 后添加到 eval() 中。初始化 source map 时比较慢,但是会在重新构建时提供比较快的速度,并且生成实际的文件。行数能够正确映射,因为会映射到原始代码中。它会生成用于开发环境的最佳品质的 source map。

eval-cheap-source-map - 类似 eval-source-map,每个模块使用 eval() 执行。这是 "cheap(低开销)" 的 source map,因为它没有生成列映射(column mapping),只是映射行数。它会忽略源自 loader 的 source map,并且仅显示转译后的代码,就像 eval devtool。

eval-cheap-module-source-map - 类似 eval-cheap-source-map,并且,在这种情况下,源自 loader 的 source map 会得到更好的处理结果。然而,loader source map 会被简化为每行一个映射(mapping)。

特定场景

以下选项对于开发环境和生产环境并不理想。他们是一些特定场景下需要的,例如,针对一些第三方工具。

inline-source-map - source map 转换为 DataUrl 后添加到 bundle 中。

cheap-source-map - 没有列映射(column mapping)的 source map,忽略 loader source map。

inline-cheap-source-map - 类似 cheap-source-map,但是 source map 转换为 DataUrl 后添加到 bundle 中。

cheap-module-source-map - 没有列映射(column mapping)的 source map,将 loader source map 简化为每行一个映射(mapping)。

inline-cheap-module-source-map - 类似 cheap-module-source-map,但是 source mapp 转换为 DataUrl 添加到 bundle 中。

对于生产环境

这些选项通常用于生产环境中:

(none)(省略 devtool 选项) - 不生成 source map。这是一个不错的选择。

source-map - 整个 source map 作为一个单独的文件生成。它为 bundle 添加了一个引用注释,以便开发工具知道在哪里可以找到它。

hidden-source-map - 与 source-map 相同,但不会为 bundle 添加引用注释。如果你只想 source map 映射那些源自错误报告的错误堆栈跟踪信息,但不想为浏览器开发工具暴露你的 source map,这个选项会很有用。

nosources-source-map - 创建的 source map 不包含 sourcesContent(源代码内容)。它可以用来映射客户端上的堆栈跟踪,而无须暴露所有的源代码。你可以将 source map 文件部署到 web 服务器。

构建目标(Targets)

webpack 能够为多种环境或 target 构建编译。想要理解什么是 target 的详细信息, 请阅读 target 概念页面

target

string [string] false

告知 webpack 为目标(target)指定一个环境。默认值为 "browserslist",如果没有找到 browserslist 的配置,则默认为 "web"

string

通过 WebpackOptionsApply, 可以支持以下字符串值:

选项描述
async-node编译为类 Node.js 环境可用(使用 fs 和 vm 异步加载分块)
electron-main编译为 Electron 主进程。
electron-renderer编译为 Electron 渲染进程,使用 JsonpTemplatePlugin,
FunctionModulePlugin 来为浏览器环境提供目标,使用 NodeTargetPluginExternalsPlugin
为 CommonJS 和 Electron 内置模块提供目标。
electron-preload编译为 Electron 渲染进程,
使用 NodeTemplatePluginasyncChunkLoading 设置为 trueFunctionModulePlugin 来为浏览器提供目标,使用 NodeTargetPluginExternalsPlugin 为 CommonJS 和 Electron 内置模块提供目标。
node编译为类 Node.js 环境可用(使用 Node.js require 加载 chunks)
node-webkit编译为 Webkit 可用,并且使用 jsonp 去加载分块。支持 Node.js 内置模块和 nw.gui
导入(实验性质)
nwjs[[X].Y]等价于 node-webkit
web编译为类浏览器环境里可用 (默认)
webworker编译成一个 WebWorker
esX编译为指定版本的 ECMAScript。例如,es5,es2020
browserslist从 browserslist-config 中推断出平台和 ES 特性 (如果 browserslist 可用,其值则为默认)

例如,当 target 设置为 "electron-main",webpack 引入多个 electron 特定的变量。

可指定 node 或者 electron 的版本。上表中使用 [[X].Y] 表示。

webpack.config.js

module.exports = {
  // ...
  target: 'node12.18',
};

它有助于确定可能用于生成运行时代码的 ES 特性(所有的 chunk 和模块都被运行时代码所包裹)

browserslist

如果一个项目有 browserslist 配置,那么 webpack 将会使用它:

  • 确定可用于运行时代码的 ES 特性。
  • 推断环境(例如:last 2 node versions 等价于 target: 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 相关的特性。

目前并不是所有的 target 都可以进行混合。

webpack.config.js

module.exports = {
  // ...
  target: ['web', 'node'],
};

此时会导致错误。webpack 暂时不支持 universal 的 target。

false

如果上述列表中的预设 target 都不符合你的需求,你可以将 target 设置为 false,这将告诉 webpack 不使用任何插件。

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'),
  ],
};

当没有提供 target 或 environment 特性的信息时,将默认使用 ES2015。

watch 和 watchOptions

Webpack 可以监听文件变化,当它们修改后会重新编译。这个页面介绍了如何启用这个功能,以及当 watch 无法正常运行的时候你可以做的一些调整。

watch

boolean = false

启用 Watch 模式。这意味着在初始构建之后,webpack 将继续监听任何已解析文件的更改。

webpack.config.js

module.exports = {
  //...
  watch: true,
};

watchOptions

object

一组用来定制 watch 模式的选项:

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 开启 polling,将会设置默认轮询间隔为 5007,或者指定毫秒为单位进行轮询。

webpack.config.js

module.exports = {
  //...
  watchOptions: {
    poll: 1000, // 每秒检查一次变动
  }
};

watchOptions.followSymlinks

根据软链接查找文件。这通常是不需要的,因为 webpack 已经使用 resolve.symlinks 解析了软链接。

  • Type: boolean

  • Example:

    module.exports = {
      //...
      watchOptions: {
        followSymlinks: true,
      },
    };

watchOptions.stdin

当 stdin 流结束时停止监听。

  • 类型:boolean

  • 示例:

    module.exports = {
      //...
      watchOptions: {
        stdin: true,
      },
    };

故障排除

如果您遇到任何问题,请查看以下注意事项。对于 webpack 为何会忽略文件修改,这里有多种原因。

发现修改,但并未做处理

在运行 webpack 时,通过使用 --progress 标志,来验证文件修改后,是否没有通知 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 Paths

因为 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 时,你可能会发现保存修改过的文件,并不会按照预期触发观察者。尝试在设置中禁用 Back up files before saving 选项,该选项确定在原文件被覆盖之前,文件是否先保存到临时位置:取消选中 File > {Settings|Preferences} > Appearance & Behavior > System Settings > Back up files before saving。在一些 webstorm 版本中,该配置项可能会被称为 "safe write"(首先将更改保存到临时文件)`。

外部扩展(Externals)

externals 配置选项提供了「从输出的 bundle 中排除依赖」的方法。相反,所创建的 bundle 依赖于那些存在于用户环境(consumer's environment)中的依赖。此功能通常对 library 开发人员来说是最有用的,然而也会有各种各样的应用程序用到它。

externals

string object function RegExp [string, object, function, RegExp]

防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖(external dependencies)

例如,从 CDN 引入 jQuery,而不是把它打包:

index.html

<script
  src="https://code.jquery.com/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') 或模块的名称(参见 amd, commonjs, module, umd)。

如果你只定义 1 个 external,您也可以使用快捷语法:

module.exports = {
  //...
  externals: 'jquery',
};

equals to

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"];

string 语法 类似,你可以使用 ${externalsType} ${libraryName} 语法在数组的第一项中指定外部库类型,例如:

module.exports = {
  //...
  externals: {
    subtract: ['commonjs ./math', 'subtract'],
  },
};

对象

module.exports = {
  //...
  externals: {
    react: 'react',
  },

  // 或者

  externals: {
    lodash: {
      commonjs: 'lodash',
      amd: 'lodash',
      root: '_', // 指向全局变量
    },
  },

  // 或者

  externals: {
    subtract: {
      root: ['math', 'subtract'],
    },
  },
};

此语法用于描述外部 library 所有可用的访问方式。这里 lodash 这个外部 library 可以在 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 目录中所有模块,还提供一些选项,比如白名单 package(whitelist package)。

函数接收两个入参:

  • ctx (object):包含文件详情的对象。
    • ctx.context (string): 包含引用的文件目录。
    • ctc.request (string): 被请求引入的路径。
    • ctx.contextInfo (object): 包含 issuer 的信息(如,layer 和 compiler)
    • ctx.getResolve 5.15.0+: 获取当前解析器选项的解析函数。
  • callback (function (err, result, type)): 用于指明模块如何被外部化的回调函数

回调函数接收三个入参:

  • err (Error): 被用于表明在外部外引用的时候是否会产生错误。如果有错误,这将会是唯一被用到的参数。
  • result (string [string] object): 描述外部化的模块。可以接受其它标准化外部化模块格式,(string, [string],或 object)。
  • type (string): 可选的参数,用于指明模块的 external type(如果它没在 result 参数中被指明)。

作为例子,要外部化所有匹配一个正则表达式的引入,你可以像下面那样处理:

webpack.config.js

module.exports = {
  //...
  externals: [
    function ({ context, request }, callback) {
      if (/^yourregex$/.test(request)) {
        // 使用 request 路径,将一个 commonjs 模块外部化
        return callback(null, 'commonjs ' + request);
      }

      // 继续下一步且不外部化引用
      callback();
    },
  ],
};

其它例子使用不同的模块格式:

webpack.config.js

module.exports = {
  externals: [
    function (ctx, callback) {
      // 该外部化的模块,是一个 `commonjs2` 的模块,且放在 `@scope/library` 目录中
      callback(null, '@scope/library', 'commonjs2');
    },
  ],
};

webpack.config.js

module.exports = {
  externals: [
    function (ctx, callback) {
      // 该外部化模块是一个全局变量叫作 `nameOfGlobal`.
      callback(null, 'nameOfGlobal');
    },
  ],
};

webpack.config.js

module.exports = {
  externals: [
    function (ctx, callback) {
      // 该外部化模块是一个在`@scope/library`模块里的命名导出(named export)。
      callback(null, ['@scope/library', 'namedexport'], 'commonjs');
    },
  ],
};

webpack.config.js

module.exports = {
  externals: [
    function (ctx, callback) {
      // 外部化模块是一个 UMD 模块
      callback(null, {
        root: 'componentsGlobal',
        commonjs: '@scope/components',
        commonjs2: '@scope/components',
        amd: 'components',
      });
    },
  ],
};

RegExp

匹配给定正则表达式的每个依赖,都将从输出 bundle 中排除。

webpack.config.js

module.exports = {
  //...
  externals: /^(jquery|\$)$/i,
};

这个示例中,所有名为 jQuery 的依赖(忽略大小写),或者 $,都会被外部化。

混用语法

有时你需要混用上面介绍的语法。这可以像以下这样操作:

webpack.config.js

module.exports = {
  //...
  externals: [
    {
      // 字符串
      react: 'react',
      // 对象
      lodash: {
        commonjs: 'lodash',
        amd: 'lodash',
        root: '_', // indicates global variable
      },
      // 字符串数组
      subtract: ['./math', 'subtract'],
    },
    // 函数
    function ({ context, request }, callback) {
      if (/^yourregex$/.test(request)) {
        return callback(null, 'commonjs ' + request);
      }
      callback();
    },
    // 正则表达式
    /^(jquery|\$)$/i,
  ],
};

关于如何使用此 externals 配置的更多信息,请参考 如何编写 library

byLayer

function object

按层指定 externals:

webpack.config.js

module.exports = {
  externals: {
    byLayer: {
      layer: {
        external1: 'var 43',
      },
    },
  },
};

externalsType

string = 'var'

指定 externals 的默认类型。当 external 被设置为 amdumdsystem 以及 jsonp 时,output.libraryTarget 的值也应相同。例如,你只能在 amd 库中使用 amd 的 externals。

支持的类型如下:

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');

请注意,输出产物中会有一个 require()

externalsType.global

将外部的默认类型指定为 'global'。Webpack 会将 external 作为全局变量读取到 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

将 externals 类型设置为 'module',webpack 将会在 module 中为外部引用生成形如 import * as X from '...' 的代码。

确保首先把 experiments.outputModule 设置为 true, 否则 webpack 将会报错。

Example

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(/* ... */);

请注意,输出产物中会有一个 import 语句。

externalsType.node-commonjs

将 externals 类型设置为 'node-commonjs',webpack 将从 module 中导入 createRequire 来构造一个 require 函数,用于加载模块中使用的外部对象。

Example

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(/* ... */);

请注意,输出包中会有一个 import 语句。

externalsType.promise

将外部的默认类型指定为 'promise'。Webpack 会将 external 读取为全局变量(类似于 'var')并为它执行 await

Example

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 会将 external 作为 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

将 external 的默认类型指定为 'script'。Webpack 会将 external 作为脚本加载,并使用 HTML <script> 元素暴露预定义的全局变量。<script> 标签将在脚本加载后被移除。

Syntax

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/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/npm/lodash@4.17.19/lodash.min.js',
      '_',
      'head',
    ],
  },
};

当你 import 'loadsh' 时,局部变量 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

将 external 的默认类型指定为 'this'。Webpack 会将 external 作为 this 对象上的全局变量读取。

示例 $#example$

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

将 external 的默认类型指定为 'var'。Webpack 会将 external 作为全局变量读取。

示例 $#example$

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

将 external 的默认类型指定为 'window'。Webpack 会将 external 作为 window 对象上的全局变量读取。

示例 $#example$

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

为特定的 target 启用 externals 的 preset。

选项描述输入类型
electron将 main 和预加载上下文中常见的 electron 内置模块视为 external 模块(如 electronipcshell),使用时通过 require() 加载。boolean
electronMain将 main 上下文中的 electron 内置模块视为 external 模块(如 appipc-mainshell),使用时通过 require() 加载。boolean
electronPreload将预加载上下文的 electron 内置模块视为 external 模块(如 web-frameipc-renderershell),使用时通过 require() 加载。boolean
electronRenderer将 renderer 上下文的 electron 内置模块视为 external 模块(如 web-frameipc-renderershell),使用时通过 require() 加载。boolean
node将 node.js 的内置模块视为 external 模块(如 fspathvm),使用时通过 require() 加载。boolean
nwjsNW.js 遗留的 nw.gui 模块视为 external 模块,使用时通过 require() 加载。boolean
webhttp(s)://... 以及 std:... 视为 external 模块,使用时通过 import 加载。(注意,这将改变执行顺序,因为 external 代码会在该块中的其他代码执行前被执行)boolean
webAsync将 'http(s)://...' 以及 'std:...' 的引用视为 external 模块,使用时通过 async import() 加载。(注意,此 external 类型为 async 模块,它对执行会产生各种副作用)boolean

Note that if you're going to output ES Modules with those node.js-related presets, webpack will set the default externalsType to node-commonjs which would use createRequire to construct a require function instead of using require().

Example

使用 node 的 preset 不会构建内置模块,而会将其视为 external 模块,使用时通过 require() 加载。

webpack.config.js

module.exports = {
  // ...
  externalsPresets: {
    node: true,
  },
};

Performance

这些选项可以控制 webpack 如何通知「资源(asset)和入口起点超过指定文件限制」。 此功能受到 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 抛出一个错误或警告。此属性默认设置为 "warning"

给定一个创建后超过 250kb 的资源:

module.exports = {
  //...
  performance: {
    hints: false,
  },
};

不展示警告或错误提示。

module.exports = {
  //...
  performance: {
    hints: 'warning',
  },
};

将展示一条警告,通知你这是体积大的资源。在开发环境,我们推荐这样。

module.exports = {
  //...
  performance: {
    hints: 'error',
  },
};

将展示一条错误,通知你这是体积大的资源。在生产环境构建时,我们推荐使用 hints: "error",有助于防止把体积巨大的 bundle 部署到生产环境,从而影响网页的性能。

performance.maxAssetSize

number = 250000

资源(asset)是从 webpack 生成的任何文件。此选项根据单个资源体积(单位: bytes),控制 webpack 何时生成性能提示。

module.exports = {
  //...
  performance: {
    maxAssetSize: 100000,
  },
};

performance.maxEntrypointSize

number = 250000

入口起点表示针对指定的入口,对于所有资源,要充分利用初始加载时(initial load time)期间。此选项根据入口起点的最大体积,控制 webpack 何时生成性能提示。

module.exports = {
  //...
  performance: {
    maxEntrypointSize: 400000,
  },
};

Node

这些选项可以配置是否 polyfill 或 mock 某些 Node.js 全局变量

此功能由 webpack 内部的 NodeStuffPlugin 插件提供。

node

boolean: false object

webpack.config.js

module.exports = {
  //...
  node: {
    global: false,
    __filename: false,
    __dirname: false,
  },
};

从 webpack 3.0.0 开始,node 选项可能被设置为 false,以完全关闭 NodeStuffPlugin 插件。

node.global

boolean 'warn'

关于此对象的准确行为,请查看Node.js 文档

选项:

  • true: 提供 polyfill.
  • false: 不提供任何 polyfill。代码可能会出现 ReferenceError 的崩溃。
  • 'warn': 当使用 global 时展示一个警告。

node.__filename

boolean 'mock' | 'warn-mock' | 'eval-only'

选项:

  • true: 输入文件的文件名,是相对于 context 选项
  • false: webpack 不会更改 __filename 的代码。在 Node.js 环境中运行时,文件的文件名。
  • 'mock': value 填充为 'index.js'
  • 'warn-mock': 使用 '/index.js' 但是会展示一个警告。
  • 'eval-only'

node.__dirname

boolean 'mock' | 'warn-mock' | 'eval-only'

选项:

  • true: 输入 文件的目录名,是相对于 context 选项
  • false: webpack 不会更改 __dirname 的代码,这意味着你有常规 Node.js 中的 __dirname 的行为。在 Node.js 环境中运行时,输出 文件的目录名。
  • 'mock': value 填充为 '/'
  • 'warn-mock': 使用 '/' 但是会显示一个警告。
  • 'eval-only'

Stats 对象

object string

stats 选项让你更精确地控制 bundle 信息该怎么显示。 如果你不希望使用 quietnoInfo 这样的不显示信息,而是又不想得到全部的信息,只是想要获取某部分 bundle 的信息,使用 stats 选项是比较好的折衷方式。

module.exports = {
  //...
  stats: 'errors-only',
};

Stats Presets

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.builtAt

boolean = true

告知 stats 是否添加构建日期与时间信息。将 stats.builtAt 设置成 false 来隐藏.

module.exports = {
  //...
  stats: {
    builtAt: false,
  },
};

stats.moduleAssets

boolean = true

告知 stats 是否添加模块内的资源信息。将 stats.moduleAssets 设置成 false 以隐藏。

module.exports = {
  //...
  stats: {
    moduleAssets: false,
  },
};

stats.assetsSpace

number = 15

告诉 stats 应该显示多少个 asset 项目(将以组的方式折叠,以适应这个空间)。

module.exports = {
  //...
  stats: {
    assetsSpace: 15,
  },
};

stats.modulesSpace

number = 15

告诉 stats 应该显示多少个模块项目(将以组的方式折叠,以适应这个空间)。

module.exports = {
  //...
  stats: {
    modulesSpace: 15,
  },
};

stats.chunkModulesSpace

number = 10

告诉 stats 显示多少个 chunk 模块项目(将以组的方式折叠,以适应这个空间)。

module.exports = {
  //...
  stats: {
    chunkModulesSpace: 15,
  },
};

stats.nestedModules

boolean

告知 stats 是否添加嵌套在其他模块中的模块信息(比如模块联邦)。

module.exports = {
  //...
  stats: {
    nestedModules: true,
  },
};

stats.nestedModulesSpace

number = 10

告诉 stats 应该显示多少个嵌套模块的项目(将以组的方式折叠,以适应这个空间)。

module.exports = {
  //...
  stats: {
    nestedModulesSpace: 15,
  },
};

stats.cached

旧版的 stats.cachedModules.

stats.cachedModules

boolean = true

告诉 stats 是否要缓存(非内置)模块的信息。

module.exports = {
  //...
  stats: {
    cachedModules: false,
  },
};

stats.runtimeModules

boolean = true

告诉 stats 是否要添加运行时模块的信息。

module.exports = {
  //...
  stats: {
    runtimeModules: false,
  },
};

stats.dependentModules

boolean

告诉 stats 是否要展示该 chunk 依赖的其他模块的 chunk 模块。

module.exports = {
  //...
  stats: {
    dependentModules: false,
  },
};

stats.groupAssetsByChunk

boolean

告诉 stats 是否按照 asset 与 chunk 的关系进行分组。

module.exports = {
  //...
  stats: {
    groupAssetsByChunk: false,
  },
};

stats.groupAssetsByEmitStatus

boolean

告诉 stats 是否按照 asset 的状态进行分组(emitted,对比 emit 或缓存).

module.exports = {
  //...
  stats: {
    groupAssetsByEmitStatus: false,
  },
};

stats.groupAssetsByExtension

boolean

告诉 stats 是否根据它们的拓展名聚合静态资源。

module.exports = {
  //...
  stats: {
    groupAssetsByExtension: false,
  },
};

stats.groupAssetsByInfo

boolean

告诉 stats 是否按照 asset 信息对 asset 进行分组(immutable,development。hotModuleReplacement 等)。

module.exports = {
  //...
  stats: {
    groupAssetsByInfo: false,
  },
};

stats.groupAssetsByPath

boolean

告诉 stats 是否根据它们的路径聚合静态资源。

module.exports = {
  //...
  stats: {
    groupAssetsByPath: false,
  },
};

stats.groupModulesByAttributes

boolean

告诉 stats 是否按模块的属性进行分组(errors,warnings,assets,optional,orphan 或者 dependent)。

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 是否按模块的 layer 进行分组。

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+

Group reasons by their origin module to avoid large set of reasons.

module.exports = {
  //...
  stats: {
    groupReasonsByOrigin: true,
  },
};

stats.cachedAssets

boolean = true

告知 stats 是否添加关于缓存资源的信息。 将 stats.cachedAssets 设置成 false 会告知 stats 仅展示被生成的文件 (并非被构建的模块)。

module.exports = {
  //...
  stats: {
    cachedAssets: false,
  },
};

stats.children

boolean = true

告知 stats 是否添加关于子模块的信息。

module.exports = {
  //...
  stats: {
    children: false,
  },
};

stats.chunks

boolean = true

告知 stats 是否添加关于 chunk 的信息。 将 stats.chunks 设置为 false 会引发更少的输出。

module.exports = {
  //...
  stats: {
    chunks: false,
  },
};

stats.chunkGroups

boolean = true

告知 stats 是否添加关于 namedChunkGroups 的信息。

module.exports = {
  //...
  stats: {
    chunkGroups: false,
  },
};

stats.chunkModules

boolean = true

告知 stats 是否添加关于已构建模块和关于 chunk 的信息。

module.exports = {
  //...
  stats: {
    chunkModules: false,
  },
};

stats.chunkOrigins

boolean = true

告知 stats 是不添加关于 chunks 的来源和 chunk 合并的信息。

module.exports = {
  //...
  stats: {
    chunkOrigins: false,
  },
};

stats.chunksSort

string = 'id'

告知 stats 基于给定的字段给 chunks 排序。所有 排序字段 都被允许用于作为 stats.chunksSort 的值。使用 ! 作为值里的前缀用以将基于给定字段排序的结果反转。

module.exports = {
  //...
  stats: {
    chunksSort: 'name',
  },
};

stats.context

string

stats 的基本目录,用来缩短请求信息的 绝对路径

const path = require('path');

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

默认情况下,context 的值是 Node.js 的当前工作目录。

stats.colors

boolean = false object

告知 stats 是否输出不同的颜色。

module.exports = {
  //...
  stats: {
    colors: true,
  },
};

它也可用通过命令行的参数实现:

npx webpack --stats-colors

To disable:

npx webpack --no-stats-colors

你可以通过使用 ANSI escape sequences 指定你自己的命令行终端颜色。

module.exports = {
  //...
  colors: {
    green: '\u001b[32m',
  },
};

stats.depth

boolean = false

告知 stats 是否展示每个模块与入口文件的距离。

module.exports = {
  //...
  stats: {
    depth: true,
  },
};

stats.entrypoints

boolean = true string = 'auto'

告知 stats 是否展示入口文件与对应的文件 bundles。

module.exports = {
  //...
  stats: {
    entrypoints: false,
  },
};

stats.entrypoints 被设置为 'auto' 时,webpack 将自动决定是否在 stats 输出中展示入口信息。

stats.env

boolean = false

告知 stats 是否展示 --env 信息.

module.exports = {
  //...
  stats: {
    env: true,
  },
};

stats.orphanModules

boolean = false

告知 stats 是否隐藏 孤儿(orphan) 模块. 一个模块属于 孤儿(orphan) 如果它不被包含在任何一个 chunk 里。孤儿模块默认在 stats 中会被隐藏。

module.exports = {
  //...
  stats: {
    orphanModules: true,
  },
};

stats.errors

boolean = true

告知 stats 是否展示错误。

module.exports = {
  //...
  stats: {
    errors: false,
  },
};

stats.errorDetails

boolean string = "auto"

告知 stats 是否添加错误的详情。如果默认值为 'auto',当只有 2 个或更少的错误时,它将显示错误详情。

module.exports = {
  //...
  stats: {
    errorDetails: false,
  },
};

stats.errorStack

boolean = true

告知 stats 是否展示错位的栈追踪信息。

module.exports = {
  //...
  stats: {
    errorStack: false,
  },
};

stats.excludeAssets

array = []: string | RegExp | function (assetName) => boolean string RegExp function (assetName) => boolean

告知 stats 排除掉匹配的资源信息。这个可以通过设置一个 字符串, 一个 正则表达式, 一个 函数 取得资源的名字作为入参且返回一个 布尔值stats.excludeAssets 可以是一个包括上面任意一类型值的 数组

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 排除掉匹配的资源信息。这个可以通过设置一个 字符串, 一个 正则表达式, 一个 函数 取得资源的名字作为入参且返回一个 布尔值stats.excludeModules 可以是一个包括上面任意一类型值的 数组stats.excludeModules 会与 stats.exclude 的配置值进行合并

module.exports = {
  //...
  stats: {
    excludeModules: ['filter', /filter/, (moduleSource) => true],
  },
};

stats.excludeModules 设置为 false 会禁用以上的排除行为。

module.exports = {
  //...
  stats: {
    excludeModules: false,
  },
};

stats.exclude

详参 stats.excludeModules.

stats.hash

boolean = true

告知 stats 是否添加关于编译哈希值的信息。

module.exports = {
  //...
  stats: {
    hash: false,
  },
};

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.modules

boolean = true

告知 stats 是否添加关于构建模块的信息。

module.exports = {
  //...
  stats: {
    modules: false,
  },
};

stats.modulesSort

string = 'id'

告知 stats 基于给定的字段对资源进行排序。所有的 排序字段都被允许作为 stats.modulesSort的值。使用 ! 作为值的前缀以反转基于给定字段的排序结果。

module.exports = {
  //...
  stats: {
    modulesSort: 'size',
  },
};

stats.moduleTrace

boolean = true

告知 stats 展示依赖和告警/错误的来源。stats.moduleTrace 从 webpack 2.5.0 起可用。

module.exports = {
  //...
  stats: {
    moduleTrace: false,
  },
};

stats.optimizationBailout

boolean

告诉 stats 展示模块优化失效的原因。

module.exports = {
  //...
  stats: {
    optimizationBailout: false,
  },
};

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

为展示的信息类型设置 预设值。这对扩展统计信息行为非常有用。

module.exports = {
  //...
  stats: {
    preset: 'minimal',
  },
};

stats.preset 的值设置为false 告知 webpack 使用 'none' 统计信息预设值

stats.providedExports

boolean = false

告知 stats 去展示模块的导出。

module.exports = {
  //...
  stats: {
    providedExports: true,
  },
};

stats.errorsCount

boolean = true

添加展示 errors 个数。

module.exports = {
  //...
  stats: {
    errorsCount: false,
  },
};

stats.warningsCount

boolean = true

添加展示 warnings 个数。

module.exports = {
  //...
  stats: {
    warningsCount: false,
  },
};

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+

Space to display reasons (groups will be collapsed to fit this space).

module.exports = {
  //...
  stats: {
    reasonsSpace: 1000,
  },
};

stats.relatedAssets

boolean = false

告诉 stats 是否需添加与其他 assets 相关的信息(例如 assets 的 SourceMaps)。

module.exports = {
  //...
  stats: {
    relatedAssets: true,
  },
};

stats.source

boolean = false

告知 stats 去添加模块的源码。

module.exports = {
  //...
  stats: {
    source: true,
  },
};

stats.timings

boolean = true

告知 stats 添加时间信息。

module.exports = {
  //...
  stats: {
    timings: false,
  },
};

stats.ids

boolean = false

通知 stats 给 module 和 chunk 添加 id。

module.exports = {
  //...
  stats: {
    ids: true,
  },
};

stats.usedExports

boolean = false

告知 stats 是否展示模块用了哪些导出。

module.exports = {
  //...
  stats: {
    usedExports: true,
  },
};

stats.version

boolean = true

告知 stats 添加关于 webpack 版本的信息。

module.exports = {
  //...
  stats: {
    version: false,
  },
};

stats.chunkGroupAuxiliary

boolean = true

在 chunk 组中展示辅助 asset。

module.exports = {
  //...
  stats: {
    chunkGroupAuxiliary: false,
  },
};

stats.chunkGroupChildren

boolean = true

显示 chunk 组的子 chunk。(例如,预置(prefetched),预加载(preloaded)的 chunk 和 asset)。

module.exports = {
  //...
  stats: {
    chunkGroupChildren: false,
  },
};

stats.chunkGroupMaxAssets

number

chunk 组中的 asset 数上限。

module.exports = {
  //...
  stats: {
    chunkGroupMaxAssets: 5,
  },
};

stats.warnings

boolean = true

告知 stats 添加告警。

module.exports = {
  //...
  stats: {
    warnings: false,
  },
};

stats.warningsFilter

array = []: string | RegExp | function (warning) => boolean string RegExp function (warning) => boolean

告知 stats 排除掉匹配的告警信息。这个可以通过设置一个 字符串, 一个 正则表达式, 一个 函数 取得资源的名字作为入参且返回一个 布尔值stats.warningsFilter 可以是一个包括上面任意一类型值的 数组

module.exports = {
  //...
  stats: {
    warningsFilter: ['filter', /filter/, (warning) => true],
  },
};

stats.chunkRelations

boolean = false

告知 stats 展示 chunk 的父 chunk,孩子 chunk 和兄弟 chunk。

字段排序

对于 assetsSort, chunksSortmodulesSort 它们有几个可用的字段用于排序:

  • 'id' 是元素(指资源,chunk 或模块,下同)的 id;
  • 'name' - 一个元素的名字,在导引的时候被分配;
  • 'size' - 一个元素的大小,单位字节(bytes);
  • 'chunks' - 元素来源于哪些 chunks (例如,一个 chunk 有多个子 chunks, - 子 chunks 会被基于主 chunk 组合到一起);
  • 'errors' - 元素组错误的数量;
  • 'warnings' - 元素中告警的数量;
  • 'failed' - 元素是被编译失败;
  • 'cacheable' - 元素是否被缓存;
  • 'built' - 资源是否被构建;
  • 'prefetched' - 资源是否被预拉取;
  • 'optional' - 资源是否可选;
  • 'identifier' - 元素的标识符;
  • 'index' - 元素加工指针;
  • 'index2'
  • 'profile'
  • 'issuer' - 发起者(issuer)的标识符;
  • 'issuerId' - 发起者(issuer)的 id;
  • 'issuerName' - 发起者(issuer)的名字;
  • 'issuerPath' - 一个完整的发起者(issuer)对象。基于这个字段排序没有现实的需要;

扩展统计信息行为

如果你想使用其中一个预定义的行为,例如 'minimal',但仍想重载一个或更多的规则:请指定想要设置的 stats.preset 同时在后面添加自定义或额外的规则。

webpack.config.js

module.exports = {
  //..
  stats: {
    preset: 'minimal',
    moduleTrace: true,
    errorDetails: true,
  },
};

实验特性(Experiments)

experiments

boolean: false

experiments 配置是在 webpack 5 中推出,目的是为了给用户赋能去开启并试用一些实验的特性。

Available options:

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

When enabled, webpack can build remote resources that begin with the http(s): protocol.

  • Type:

    • (string | RegExp | ((uri: string) => boolean))[]

      A shortcut for experiments.buildHttp.allowedUris.

    • HttpUriOptions

      {
        allowedUris: (string|RegExp|(uri: string) => boolean)[],
        cacheLocation?: false | string,
        frozen?: boolean,
        lockfileLocation?: string,
        upgrade?: boolean
      }
  • Available: 5.49.0+

  • Example

    // 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 just 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: [
            'http://localhost:9990/',
            'https://raw.githubusercontent.com/',
          ],
        },
      },
    };

experiments.buildHttp.cacheLocation

Define the location for caching remote resources.

  • Type

    • string
    • false
  • Example

    // webpack.config.js
    module.exports = {
      //...
      experiments: {
        buildHttp: {
          cacheLocation: false,
        },
      },
    };

By default webpack would use <compiler-name.>webpack.lock.data/ for caching, but you can disable it by setting its value to false.

Note that you should commit files under experiments.buildHttp.cacheLocation into a version control system as no network requests will be made during the production build.

experiments.buildHttp.frozen

Freeze the remote resources and lockfile. Any modification to the lockfile or resource contents will result in an error.

  • 类型:boolean

experiments.buildHttp.lockfileLocation

Define the location to store the lockfile.

  • 类型:string

By default webpack would generate a <compiler-name.>webpack.lock file>. Make sure to commit it into a version control system. During the production build, webpack will build those modules beginning with http(s): protocol from the lockfile and caches under experiments.buildHttp.cacheLocation.

experiments.buildHttp.proxy

指定用来获取远程资源的代理服务器。

  • 类型:string

默认情况下,webpack 会让代理服务器使用 http_proxy(不区分大小写) 环境变量值获取远程资源。然而,你也可以通过 proxy 配置项指定。

experiments.buildHttp.upgrade

检测远程资源的更改并自动升级。

  • 类型:boolean

experiments.css

启用原生 CSS 支持。请注意该实验特性仍处于开发状态并且将会在 webpack v6 中默认启用,你可以在 GitHub 中跟踪进度。

  • 类型:boolean

experiments.cacheUnaffected

Enable additional in-memory caching of modules which are unchanged and reference only unchanged modules.

  • 类型:boolean

Defaults to the value of futureDefaults.

experiments.futureDefaults

使用下一个 webpack 主版本的默认值,并在任何有问题的地方显示警告。

webpack.config.js

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

experiments.lazyCompilation

Compile entrypoints and dynamic imports only when they are in use. It can be used for either Web or Node.js.

  • Type

    • 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: typeof 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 | (() => typeof Server);
      
      },
      entries?: boolean,
      imports?: boolean,
      test?: string | RegExp | ((module: Module) => boolean)
      }
      • backend: Customize the backend.
      • entries: Enable lazy compilation for entries.
      • imports 5.20.0+: Enable lazy compilation for dynamic imports.
      • test 5.20.0+: Specify which imported modules should be lazily compiled.
  • Available: 5.17.0+

  • Example 1:

    module.exports = {
      // …
      experiments: {
        lazyCompilation: true,
      },
    };
  • Example 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

Once enabled, webpack will output ECMAScript module syntax whenever possible. For instance, import() to load chunks, ESM exports to expose chunk data, among others.

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

其它选项

这里是 webpack 支持的其它选项。

amd

object boolean: false

设置 require.amddefine.amd 的值。设置 amdfalse 会禁用 webpack 的 AMD 支持。

webpack.config.js

module.exports = {
  //...
  amd: {
    jQuery: true,
  },
};

某些流行的模块是按照 AMD 规范编写的,最引人瞩目的 jQuery 版本在 1.7.0 到 1.9.1,如果 loader 提示它对页面包含的多个版本采取了特殊许可时,才会注册为 AMD 模块。

许可权限是具有「限制指定版本注册」或「支持有不同定义模块的不同沙盒」的能力。

此选项允许将模块查找的键(key)设置为真值(truthy value)。 发生这种情况时,webpack 中的 AMD 支持将忽略定义的名称。

bail

boolean = false

在第一个错误出现时抛出失败结果,而不是容忍它。默认情况下,当使用 HMR 时,webpack 会将在终端以及浏览器控制台中,以红色文字记录这些错误,但仍然继续进行打包。要启用它:

webpack.config.js

module.exports = {
  //...
  bail: true,
};

这将迫使 webpack 退出其打包过程。

dependencies

[string]

一个 name 列表,定义它所依赖的所有兄弟(sibling)配置。需要首先编译依赖的配置。

在 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,可以是自定义 function。如果类型为函数,可基于原始 warning 来选择性展示警告,其参数分别为 WebpackErrorCompilation,且返回值为 boolean。还可以包含以下属性的 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,
  ],
};

infrastructureLogging

用于基础设施水平的日志选项。

object = {}

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');
    },
  ],
};

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');
    },
  ],
};

console

5.31.0+

Console

为基础设施日志提供自定义方案。

webpack.config.js

module.exports = {
  //...
  infrastructureLogging: {
    console: yourCustomConsole(),
  },
};

debug

string boolean = false RegExp function(name) => boolean [string, RegExp, function(name) => boolean]

开启特定日志比如插件(plugins)和加载器(loaders)的调试信息。 与 stats.loggingDebug 选项类似但仅仅对于基础设施而言。默认为 false

webpack.config.js

module.exports = {
  //...
  infrastructureLogging: {
    level: 'info',
    debug: ['MyPlugin', /MyPlugin/, (name) => name.contains('MyPlugin')],
  },
};

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',
  },
};

stream

5.31.0+

NodeJS.WritableStream = process.stderr

用于日志输出的流。默认为 process.stderr。此选项仅在未提供自定义 console 的情况下使用。

webpack.config.js

module.exports = {
  //...
  infrastructureLogging: {
    stream: process.stderr,
  },
};

loader

object

loader 上下文 中暴露自定义值。

例如,你可以在 loader 上下文中定义一个新变量:

webpack.config.js

module.exports = {
  // ...
  loader: {
    answer: 42,
  },
};

然后使用 this.answer 在 loader 中获取该值:

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

指定记录要写入的位置。以下示例描述了如何用这个选项和 recordsInptuPaht 来重命名一个记录文件:

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 的 "records" 记录 - 即「用于存储跨多次构建(across multiple builds)的模块标识符」的数据片段。可以使用此文件来跟踪在每次构建之间的模块变化。只要简单的设置一下路径,就可以生成这个 JSON 文件:

webpack.config.js

const path = require('path');

module.exports = {
  //...
  recordsPath: path.join(__dirname, 'records.json'),
};

如果你使用了代码分离(code splittnig)这样的复杂配置,records 会特别有用。这些数据用于确保拆分 bundle,以便实现你需要的缓存(caching)行为。

snapshot

object

snapshot 配置项决定文件系统是如何创建和无效快照。

webpack.config.js

const path = require('path');
module.exports = {
  // ...
  snapshot: {
    managedPaths: [path.resolve(__dirname, '../node_modules')],
    immutablePaths: [],
    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:比较 timestamps 以确定无效。

hashtimestamp 都是可选配置。

  • { hash: true }:对 CI 缓存很有帮助,使用新的 checkout,不需要保存时间戳,并且使用哈希。
  • { timestamp: true }:对应本地开发缓存很用帮助。
  • { timestamp: true, hash: true }:对于以上提到的两者都很有帮助。首先比较时间戳,这代价很低,因为 webpack 不需要读取文件来计算它们的哈希值。仅当时间戳相同时才会比较内容哈希,这对初始构建的性能影响很小。

immutablePaths

(RegExp | string)[]

由包管理器管理的路径数组,在其路径中包含一个版本或哈希,以便所有文件都是不可变的(immutable)。

如果使用正则表达式,请确保将路径包裹在捕获组中。

managedPaths

如果使用正则表达式,请确保将路径包裹在捕获组中。

managedPaths

(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