webpack4-(2)-development与production的区别打包

386 阅读3分钟

development与production的区别打包

日常开发环境

我们日常的开发环境大致分为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.js 和 webpack.prod.js 。
image.png
然后按照上面说的异同项分别对两个文件进行修改。
配置文件修改之后再设置一下打包命令。在package.json中做如下设置。

"scripts": {
    "dev": "webpack-dev-server --config webpack.dev.js",
    "build": "webpack --config webpack.prod.js"
  },

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

配置项优化

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

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

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

const {merge} = require('webpack-merge')
const commonConfig = require('./webpack.common')

 const devConfig = {
    mode: 'development',
	devtool: 'cheap-module-eval-source-map',
    devServer: {
		open: true,
		port: 8080,
		hot: true
	},
    optimization: {
		usedExports: true
	}
}
module.exports = merge(commonConfig, devConfig)

webpack.prod.js 

const {merge} = require('webpack-merge')
const commonConfig = require('./webpack.common')

const prodConfig = {
	mode: 'production',
	devtool: 'cheap-module-source-map',
}

module.exports = merge(commonConfig, prodConfig)

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

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')

module.exports = {
    entry: {
		main: path.resolve(__dirname, '../src/main.js') 
    },
    output: {
		filename: '[name].js',
		path: path.resolve(__dirname, '../dist')
    },
    module: {
        rules: [
            {
                test: /\.js?$/,
                use: ['babel-loader'],
                exclude: /node_modules/
            },
            {
                test: /\.css$/,
                use: [
                    'style-loader', 
                    {
                        loader: 'css-loader',
                        options: {
                            importLoaders: 2
                        }
                    },
                    'postcss-loader'
                ]
            }, 
        ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            template: './src/index.html',
            filename: 'index.html', //打包后的文件名
            minify: {
                removeAttributeQuotes: false, //是否删除属性的双引号
                collapseWhitespace: false, //是否折叠空白
            },
            hash: true //是否加上hash,默认是 false
        }),
        new CleanWebpackPlugin(),
    ]
}

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

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

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

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

总结

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