日常开发环境

我们日常的开发环境大致分为development(开发环境)和production(生产环境)。在webpack的配置文件中有一个配置项 mode 可以配置打包环境。现在就dev环境和prod环境的区别打包进行一下配置。

development和production的异同配置

相同配置项:

  • entry(入口)、output(出口)
  • 目前常用的loader
  • 部分plugin,例如: HtmlWebpackPlugin CleanWebpackPlugin

    不同配置项

  • mode,最主要配置

  • devtool,source-map
  • devServer,
  • 部分:plugins,例如 HotModuleReplacementPlugin
  • optimization,dev默认不开启tree-shaking

首先,我们可以先把 webpack.config.js 复制一份,把两份js分别命名为 webpack.dev.jswebpack.prod.js
image.png
然后按照上面说的异同项分别对两个文件进行修改。
配置文件修改之后再设置一下打包命令。在package.json中做如下设置。

  1. "scripts": {
  2. "dev": "webpack-dev-server --config webpack.dev.js",
  3. "build": "webpack --config webpack.prod.js"
  4. },

这样在打包开发和生产代码的时候就不用每次都修改配置文件了。

配置项优化

同时维护两个有部分共同项的配置文件有点蠢,所以我们对配置文件进行一下优化。
首先,我们在根目录新建一个文件夹 build 用来放置我们的配置文件。把刚才两个配置文件放入这个文件夹,然后再新建一个 webpack.common.js 用于放置相同配置。
由于配置文件的目录地址发生改变,我们的打包命令也要发生改变。

  1. "scripts": {
  2. "dev": "webpack-dev-server --config ./build/webpack.dev.js",
  3. "build": "webpack --config ./build/webpack.prod.js"
  4. },

这样配置完后还是不行的,因为公用配置项已经被单独提出了,两个配置文件在执行的时候并没有这部分内容。所以我们要用到 webpack-merge 这个插件方便我们对于公共模块的复用。
简单实用的话传两个参数,如果有相同的key,并且对应的value是简单类型的话,第二个参数的值会吧第一个参数的值覆盖。否则将再次按照merge规则进行合并。
webpack.dev.js

  1. const {merge} = require('webpack-merge')
  2. const commonConfig = require('./webpack.common')
  3. const devConfig = {
  4. mode: 'development',
  5. devtool: 'cheap-module-eval-source-map',
  6. devServer: {
  7. open: true,
  8. port: 8080,
  9. hot: true
  10. },
  11. optimization: {
  12. usedExports: true
  13. }
  14. }
  15. module.exports = merge(commonConfig, devConfig)

webpack.prod.js

  1. const {merge} = require('webpack-merge')
  2. const commonConfig = require('./webpack.common')
  3. const prodConfig = {
  4. mode: 'production',
  5. devtool: 'cheap-module-source-map',
  6. }
  7. module.exports = merge(commonConfig, prodConfig)

完成这两个文件的配置之后还要对webpack.common.js进行路径参数的修改。
webpack.common.js

  1. const path = require('path')
  2. const HtmlWebpackPlugin = require('html-webpack-plugin')
  3. const {CleanWebpackPlugin} = require('clean-webpack-plugin')
  4. module.exports = {
  5. entry: {
  6. main: path.resolve(__dirname, '../src/main.js')
  7. },
  8. output: {
  9. filename: '[name].js',
  10. path: path.resolve(__dirname, '../dist')
  11. },
  12. module: {
  13. rules: [
  14. {
  15. test: /\.js?$/,
  16. use: ['babel-loader'],
  17. exclude: /node_modules/
  18. },
  19. {
  20. test: /\.css$/,
  21. use: [
  22. 'style-loader',
  23. {
  24. loader: 'css-loader',
  25. options: {
  26. importLoaders: 2
  27. }
  28. },
  29. 'postcss-loader'
  30. ]
  31. },
  32. ]
  33. },
  34. plugins:[
  35. new HtmlWebpackPlugin({
  36. template: './src/index.html',
  37. filename: 'index.html', //打包后的文件名
  38. minify: {
  39. removeAttributeQuotes: false, //是否删除属性的双引号
  40. collapseWhitespace: false, //是否折叠空白
  41. },
  42. hash: true //是否加上hash,默认是 false
  43. }),
  44. new CleanWebpackPlugin(),
  45. ]
  46. }

在此要说一下 clean-webpack-plugin ,最新版的需要解构引入

  1. const {CleanWebpackPlugin} = require('clean-webpack-plugin')

而且第一个参数不再是之前的路径数组。
默认的删除路径为 /dist ,可被cleanOnceBeforeBuildPatterns配置项代替。

If using webpack 4+’s default configuration,everything under /dist/ will be removed.Use cleanOnceBeforeBuildPatterns to override this behavior.

总结

development和production 的打包配置项有相同点,也有不同点,我们可以通过提取公共配置项来使我们的配置更符合模块化的理念。