在实际开发过程中,我们不会把开发的配置和生产的配置写在一个 webpack.config.js 中,这样打包的时候搞起来很麻烦,通常我们会通过环境变量来合并不同的配置文件。
拆分成三个文件:

  • webpack.base.js 基础配置,开发环境和生产环境都需要
  • webpack.dev.js 开发配置,只有开发环境需要
  • webpack.prod.js 生产配置,只有生产环境需要

我们把这三个文件放到 build 文件夹中集中管理。

  1. build
  2. |-webpack.base.js
  3. |-webpack.dev.js
  4. |-webpack.prod.js

然后我们拆分下功能,以之前的配置文件为例.

配置文件

webpack.base.js

  1. /** ./build/webpack.base.js **/
  2. let path = require('path');
  3. let { CleanWebpackPlugin } = require('clean-webpack-plugin');
  4. let HtmlWebpackPlugin = require('html-webpack-plugin');
  5. let ESLintWebpackPlugin = require('eslint-webpack-plugin');
  6. let { merge } = require('webpack-merge');
  7. let htmlPlugins = ['index'].map(chunkName => {
  8. return new HtmlWebpackPlugin({
  9. filename: `${chunkName}.html`,
  10. inject: 'body',
  11. chunks: [chunkName],
  12. template: `./public/${chunkName}.html`
  13. })
  14. });
  15. let base = {
  16. entry: {
  17. index: './src/index.js'
  18. },
  19. output: {
  20. filename: 'js/[name].[contenthash:8].js',
  21. path: path.resolve(__dirname, '../dist')
  22. },
  23. module: {
  24. rules: [
  25. {
  26. test: /\.ts$/,
  27. use: 'ts-loader'
  28. },
  29. {
  30. test: /\.js$/,
  31. exclude: /node_modules/, // 忽略掉不要进行loader处理的文件
  32. include: path.resolve(__dirname, './src'),
  33. use: {
  34. loader: 'babel-loader',
  35. options: {
  36. presets: [['@babel/preset-env', {
  37. useBuiltIns: 'usage',
  38. corejs: { version: 3 }
  39. }]],
  40. plugins: [
  41. '@babel/plugin-transform-runtime',
  42. ['@babel/plugin-proposal-decorators', { "legacy": true }]
  43. ],
  44. }
  45. }
  46. },
  47. {
  48. test: /\.(htm|html)/,
  49. use: 'html-withimg-loader',
  50. },
  51. {
  52. test: /\.(ttf|woff|woff2|svg|eot)$/,
  53. use: ['file-loader']
  54. },
  55. {
  56. test: /\.(jpg|jpeg|png|gif)$/,
  57. use: [
  58. {
  59. loader: 'url-loader',
  60. options: {
  61. limit: 10240,
  62. esModule: false,
  63. outputPath: "img"
  64. }
  65. }
  66. ]
  67. }
  68. ]
  69. },
  70. plugins: [
  71. new CleanWebpackPlugin(),
  72. ...htmlPlugins,
  73. new ESLintWebpackPlugin()
  74. ]
  75. }
  76. let dev = require('./webpack.dev');
  77. let prod = require('./webpack.prod');
  78. module.exports = (env) => {
  79. console.log(env);//{ production: true }
  80. if (env.production) {
  81. return merge(base, prod);
  82. } else {
  83. return merge(base, dev);
  84. }
  85. }

webpack.dev.js

let devConfig = {
    mode: 'development',
    devServer: {
        port: 3000,
        open: true,
        compress: true,
        static: './dist',
    },
    devtool:'source-map',
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            modules: true
                        }
                    },
                    'postcss-loader',
                    'sass-loader'
                ]
            }
        ]
    }
}

module.exports = devConfig;

webpack.prod.js

let MiniCssExtractPlugin = require('mini-css-extract-plugin');
let prodConfig = {
    mode: 'production',
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    {
                        loader: 'css-loader',
                        options: {
                            modules: true
                        }
                    },
                    'postcss-loader',
                    'sass-loader'
                ]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({})
    ]
}

module.exports = prodConfig;

脚本配置

我们看 webpack.base.js 的 82 行,这边将函数作为配置文件的返回值,将会获得一个环境变量,这个环境变量怎么来的,在 package.json 的脚本中配置。

{
  "scripts":{
    "build":"webpack --env production --config build/webpack.base.js",
    "dev":"webpack-dev-server --env development --config build/webpack.base.js"
  }
}

合并 config 文件

我们在合并 config 文件时,使用了 webpack-merge 包,可以自动合并 config 文件,非常方便

yarn add webpack-merge --dev