如何使用相同的插件为不同的模式组织 Webpack 5 文件

How to organize Webpack 5 files for different modes with same plugins

一些上下文:

同事告诉我,新版本的 Webpack 处理不同文件中的配置:webpack.development.config.jswebpack.production.config.js ...(您甚至可以创建自定义模式)。但他们不知道如何解释整件事。只是现在一切都是通过多个配置文件完成的。

official docs,我看到不同的模式在顶部有一个注释,说明不同的文件名:

发展

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

生产

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

所以这一定有一定的道理,我想遵循最佳做法。将不同模式的配置分开似乎是一件好事。

但我不知道现在应该如何正确加载插件。

我以前把这个放在我的文件的顶部:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const WatchTimePlugin = require('webpack-watch-time-plugin');
const cssnano = require('cssnano');
const autoprefixer = require('autoprefixer');
const webpack = require('webpack');

所以,这最终给我留下了以下问题。

问题

我还需要 Webpack 的全局配置文件吗?如果没有任何全局配置文件,我怎么能有我想要 运行 用于生产和开发的常见任务?

webpack 是否加载所有名为 webpack.xxxxxx.config.js 的文件?我可以用那个名字创建任何我喜欢的配置文件,它会把它们全部考虑在内吗?

如何实现dev和prod的通用配置,然后dev和prod的特殊扩展配置?

我发现文档对这一切并不是很清楚。因此,我们将不胜感激。

这真的取决于插件,例如,HtmlWebpackPlugin 将脚本和样式注入 html 模板,这是开发和生产构建中都需要的东西。
另一方面,MinicssExtractPlugin 将 CSS 提取到单独的文件中,这在开发中可能不需要。
我建议您拿笔和纸,访问每个插件的网站并确定该插件是否:

  • 正在(或可以)用于开发和生产
  • 仅用于开发(例如react-refresh-webpack-plugin
  • 只在生产中使用(我把MiniCssExtractPlugin放在这里)

然后在配置中:

// webpack.shared.config.js
module.exports = {
    plugins: [
        // Shared plugins
    ]
};

// webpack.development.config.js
module.exports = {
    plugins: [
        // Dev only plugins
    ]
};

// webpack.production.config.js
module.exports = {
    plugins: [
        // Prod only plugins
    ]
};

组织插件的一个好方法是:

  1. 它是否改善了用户体验(加载时间、使用情况)?
  2. 应用程序是否需要运行?
  3. 对发育有帮助吗

如果你的答案是:

  • 是,否,否:生产插件
  • 否,是,否:生产插件
  • 不,不,是:开发插件
  • 是,不是,是:共享插件
  • 是,是,否:生产插件
  • 是,是,是:共享插件

Does webpack load all files called webpack.xxxxxx.config.js? Can I just create whatever config files I like with that name and it will take them all into consideration?

Webpack 自动(如果未在命令行中指定配置)仅加载一个名为 webpack.config.js 的文件。如果它不存在,那么它使用默认配置。 您应该始终指定使用的配置文件:

npx webpack --config config/webpack.config.js

我建议您执行以下操作以分离开发和生产配置

npm install webpack-merge --save-dev
# or if you're using yarn
yarn add webpack-merge --dev

目录结构:

src
|_ Some files
|_ Other files
package.json
config
|_webpack.shared-config.js
|_webpack.dev-config.js
|_webpack.prod-config.js
// config/webpack.shared.config.js
module.exports = {
    // Configuration to be used in both modes, `entry` goes here
};

// config/webpack.dev-config.js
let {merge} = require("webpack-merge");

module.exports = merge(require("./webpack.shared-config.js"), {
    mode: "development",
    // Other dev only config
});

// config/webpack.prod-config.js
let {merge} = require("webpack-merge");

module.exports = merge(require("./webpack.shared-config.js"), {
    mode: "production",
    // Other production only config
});

然后你可以在webpack cli中指定配置文件:

npx webpack --config config/webpack.dev-config.js
# or, in production
npx webpack --config config/webpack.prod-config.js

此外,您可以将构建(和服务)脚本添加到 package.json:

{
    // ...
    "scripts": {
        "build": "webpack --config config/webpack.prod-config.js",
        "build-dev": "webpack --config config/webpack.dev-config.js",
        "serve": "webpack serve --hmr --config config/webpack.dev-config.js",
        "serve-prod": "webpack serve --config config/webpack.prod-config.js",
    }
    // ...
}

备注:

  1. webpack serve 需要安装 webpack-dev-server
npm install webpack-dev-server --save-dev
# or
yarn add webpack-dev-server --dev
  1. webpack-merge 进行深度合并:
let a = {
    b: {
        c: [1]
    }
};

console.log(
    merge(a, {
        b: {
            c: [2]
        }
    })
);
// Outputs:
// {
//   b: {
//     c: [1, 2]
//   }
// }
  1. 合并对象不一定是webpack配置,可以是任何东西。

另见: