知海

扩展配置

webpackjsorg-main配置参考

扩展配置

extends

string | string[]

webpack v5.82.0+ / webpack-cli v5.1.0+

extends 属性允许你扩展一份现有配置,将其作为基础配置。它内部使用 webpack-merge 包来合并配置,帮助你在多个配置之间避免重复。

注意:Node API 不支持此选项:使用 Node API 时 extends 不会生效。使用此功能需要 webpack-cli。

base.webpack.config.js

js 复制代码
export default {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: "babel-loader",
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
  plugins: [
    new webpack.DefinePlugin({
      "process.env.NODE_ENV": JSON.stringify("production"),
    }),
  ],
};

webpack.config.js

js 复制代码
import path from "node:path";
import { fileURLToPath } from "node:url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export default {
  extends: path.resolve(__dirname, "./base.webpack.config.js"),
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
};

扩展多个配置

你可以通过向 extends 属性传入配置路径数组,一次性扩展多个配置。

extends 属性中的配置会从右到左进行合并,也就是说,右侧的配置会合并到左侧的配置中。在右侧配置中传入相同的属性可以覆盖已有配置。

js.webpack.config.js

js 复制代码
export default {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: "babel-loader",
        exclude: /node_modules/,
      },
    ],
  },
};

css.webpack.config.js

js 复制代码
export default {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};

webpack.config.js

js 复制代码
import path from "node:path";
import { fileURLToPath } from "node:url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export default {
  extends: [
    path.resolve(__dirname, "./js.webpack.config.js"),
    path.resolve(__dirname, "./css.webpack.config.js"),
  ],
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
};

覆盖配置

你可以通过在扩展配置中传入相同的属性,来覆盖被扩展配置中的对应配置。

base.webpack.config.js

js 复制代码
import path from "node:path";
import { fileURLToPath } from "node:url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export default {
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
};

webpack.config.js

js 复制代码
import path from "node:path";
import { fileURLToPath } from "node:url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export default {
  extends: path.resolve(__dirname, "./base.webpack.config.js"),
  entry: "./src/index.js",
  // 覆盖 output 的 path 和 filename
  output: {
    path: path.resolve(__dirname, "build"),
    filename: "[name].bundle.js",
  },
};

拼接 rules 和 plugins

虽然基本值(如字符串)会被覆盖,但数组字段会被拼接而不会被替换。此行为源于 webpack-merge,webpack 在处理 extends 时内部使用了它。

base.webpack.config.js

js 复制代码
import webpack from "webpack";

export default {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: "babel-loader",
      },
    ],
  },
  plugins: [
    new webpack.DefinePlugin({
      __DEV__: false,
    }),
  ],
};

webpack.config.js

js 复制代码
import path from "node:path";
import { fileURLToPath } from "node:url";
import webpack from "webpack";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export default {
  extends: path.resolve(__dirname, "./base.webpack.config.js"),

  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  },

  plugins: [new webpack.HotModuleReplacementPlugin()],
};

合并后的结果

module 没有被替换,rulesplugins 数组被拼接了。

js 复制代码
import webpack from "webpack";

export default {
  module: {
    rules: [
      // 来自 base.webpack.config.js
      {
        test: /\.js$/,
        use: "babel-loader",
      },

      // 来自 webpack.config.js(追加)
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  },

  plugins: [
    // 来自 base.webpack.config.js
    new webpack.DefinePlugin({
      __DEV__: false,
    }),

    // 来自 webpack.config.js(追加)
    new webpack.HotModuleReplacementPlugin(),
  ],
};

从外部包加载配置

你也可以通过将包名传给 extends 属性,从第三方包加载配置。该包必须在 package.json 中导出 webpack 配置。

webpack.config.js

js 复制代码
import path from "node:path";
import { fileURLToPath } from "node:url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export default {
  extends: import.meta.resolve("webpack-config-foo"),
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
};

帮助我们改进文档

发现翻译问题或内容错误?请告诉我们。