由于 webpack 配置的复杂性,webpack.config.js 将会慢慢变得难以理解和维护。因此,我们需要一种管理 webpack 配置的方法。

一般有如下几种方式可供选择:

  1. 每一个环境的配置单独形成一个文件,然后通过 cli 的 --config 参数来指定配置文件
  2. 通过一些库来添加配置,比如 webpack-config-pluginsopen in new windowNeutrinoopen in new windowwebpack-blocksopen in new window
  3. 通过工具来管理配置,比如 create-react-appopen in new windowkytopen in new windownwbopen in new window
  4. 在单个文件中维护所有的配置,然后通过 --mode 参数来区分环境

本文介绍一种新的管理方式,我们将应用配置拆散成多个小的函数,比如样式配置、js 配置、图片配置等,然后通过 webpack-mergeopen in new window 将这些配置再组合起来。这样做有一个好处是可以最大限度的复用配置,同时又非常的灵活。webpack-merge 甚至可以做到针对单个配置项的灵活设置。

webpack-merge 主要功能就是串接数组和合并对象。下面的例子说明 webpack-merge 是如何工作的:

> { merge } = require("webpack-merge")
...
> merge(
... { a: [1], b: 5, c: 20 },
... { a: [2], b: 10, d: 421 }
... )
{ a: [ 1, 2 ], b: 10, c: 20, d: 421 }
1
2
3
4
5
6
7

在合并对象的时候,webpack-merge 不会直接覆盖已有值,而是合并。

webpack-merge 使用

安装 webpack-merge

npm add webpack-merge --develop
1

我们对 webpack 的配置做一些抽象,将配置项级别的、小的配置放在 webpack.parts.js 里面,将更高级别的配置放在 webpack.config.js 中,示例如下:

webpack.parts.js

const { WebpackPluginServe } = require("webpack-plugin-serve");
const {
  MiniHtmlWebpackPlugin,
} = require("mini-html-webpack-plugin");


exports.devServer = () => ({
  watch: true,
  plugins: [
    new WebpackPluginServe({
      port: process.env.PORT || 8080,
      static: "./dist", // Expose if output.path changes
      liveReload: true,
      waitForBuild: true,
    }),
  ],
});


exports.page = ({ title }) => ({
  plugins: [new MiniHtmlWebpackPlugin({ context: { title } })],
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

webpack.config.js 用来组合这些配置项:

const { mode } = require("webpack-nano/argv");
const { merge } = require("webpack-merge");
const parts = require("./webpack.parts");

const commonConfig = merge([
  { entry: ["./src"] },
  parts.page({ title: "Demo" }),
]);

const productionConfig = merge([]);

const developmentConfig = merge([
  { entry: ["webpack-plugin-serve/client"] },
  parts.devServer(),
]);

const getConfig = (mode) => {
  switch (mode) {
    case "production":
      return merge(commonConfig, productionConfig, { mode });
    case "development":
      return merge(commonConfig, developmentConfig, { mode });
    default:
      throw new Error(`Trying to use an unknown mode, ${mode}`);
  }
};

module.exports = getConfig(mode);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

通过使用 webpack-merge, 我们可以方便的复用、修改、扩展配置,而不用再担心配置不好维护了。

总结

  1. 因为 webpack 配置是普通 JavaScript 代码,因此我们有多种方式来管理这些配置项。
  2. webpack-merge 提供了一种轻量级的组合webpack 配置的方法。当然,你也可以使用其他的方式来管理配置。
  3. 基于组合的方式来管理配置可以最大限度的复用配置,甚至可以通过抽取 npm包的形式跨项目复用。

关注微信公众号,获取最新推送~