在实际开发项目时,webpack 生产环境和开发环境的打包有所不同,比如清除打包文件夹和复制文件只应该在生产环境打包时发挥作用。常常使用多配置文件来解决问题。

配置文件目录

image.png

  1. // paths.js
  2. const path = require('path')
  3. const appDir = process.cwd()
  4. const resolveApp = (relativePath) => {
  5. return path.resolve(appDir, relativePath)
  6. }
  7. module.exports = resolveApp

通用配置文件

  1. const resolveApp = require('./paths')
  2. const HtmlWebpackPlugin = require('html-webpack-plugin')
  3. const { merge } = require('webpack-merge')
  4. const ProdConfig = require('./webpack.prod')
  5. const DevConfig = require('./webpack.dev')
  6. const commonConfig = {
  7. entry: './src/index.js',
  8. output: {
  9. filename: 'js/main.js',
  10. path: resolveApp('./dist')
  11. },
  12. resolve: {
  13. extensions: ['.js', '.json', '.vue', '.jsx'],
  14. alias: {
  15. '@': resolveApp('./src')
  16. }
  17. },
  18. module: {
  19. rules: [
  20. {
  21. test: /\.css$/,
  22. use: [
  23. 'style-loader',
  24. {
  25. loader: 'css-loader',
  26. options: {
  27. importLoaders: 1,
  28. esModule: false
  29. }
  30. },
  31. 'postcss-loader'
  32. ]
  33. },
  34. {
  35. test: /\.less$/,
  36. use: [
  37. 'style-loader',
  38. 'css-loader',
  39. 'postcss-loader',
  40. 'less-loader'
  41. ]
  42. },
  43. {
  44. test: /\.(png|svg|gif|jpe?g)$/,
  45. type: 'asset',
  46. generator: {
  47. filename: "img/[name].[hash:4][ext]"
  48. },
  49. parser: {
  50. dataUrlCondition: {
  51. maxSize: 30 * 1024
  52. }
  53. }
  54. },
  55. {
  56. test: /\.(ttf|woff2?)$/,
  57. type: 'asset/resource',
  58. generator: {
  59. filename: 'font/[name].[hash:3][ext]'
  60. }
  61. },
  62. {
  63. test: /\.jsx?$/,
  64. use: ['babel-loader']
  65. }
  66. ]
  67. },
  68. plugins: [
  69. new HtmlWebpackPlugin({
  70. title: 'copyWebpackPlugin',
  71. template: './public/index.html'
  72. }),
  73. ]
  74. }
  75. module.exports = (env) => {
  76. const isProduction = env.production
  77. if (!isProduction) {
  78. process.env.NODE_ENV = isProduction ? 'production' : 'development'
  79. }
  80. const config = isProduction ? ProdConfig : DevConfig
  81. const mergeConfig = merge(commonConfig, config)
  82. return mergeConfig
  83. }

生产环境配置文件

  1. const CopyWebpackPlugin = require('copy-webpack-plugin')
  2. const { CleanWebpackPlugin } = require('clean-webpack-plugin')
  3. module.exports = {
  4. mode: 'production',
  5. plugins: [
  6. new CleanWebpackPlugin(),
  7. new CopyWebpackPlugin({
  8. patterns: [
  9. {
  10. from: 'public',
  11. globOptions: {
  12. ignore: ['**/index.html']
  13. }
  14. }
  15. ]
  16. }),
  17. ]
  18. }

开发环境配置文件

  1. const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')
  2. module.exports = {
  3. mode: 'development',
  4. devtool: 'cheap-module-source-map',
  5. target: 'web',
  6. devServer: {
  7. // hot: true,
  8. hotOnly: true,
  9. open: false,
  10. port: 4000,
  11. compress: false,
  12. historyApiFallback: true,
  13. proxy: {
  14. '/api': {
  15. target: 'https://api.github.com',
  16. pathRewrite: { "^/api": "" },
  17. changeOrigin: true
  18. }
  19. }
  20. },
  21. plugins: [
  22. new ReactRefreshWebpackPlugin()
  23. ]
  24. }

其他配置文件

其他配置文件如 babel 也要根据环境区分。

  1. // babel.config.js
  2. const presets = [
  3. ['@babel/preset-env'],
  4. ['@babel/preset-react'],
  5. ]
  6. const plugins = []
  7. if (process.env.NODE_ENV === 'development') { // 开发环境才需要使用这个插件
  8. plugins.push(['react-refresh/babel'])
  9. }
  10. module.exports = {
  11. presets,
  12. plugins
  13. }

命令行

多配置文件打包的命令需要加上 —env 参数。

  1. "build2": "webpack --config ./config/webpack.common.js --env production",
  2. "serve2": "webpack serve --config ./config/webpack.common.js --env development"