webpack打包系列-5.不同环境配置webpack

310 阅读3分钟

上一篇

webpack打包系列-4.文件观察及开发热重载

解决了如何避免操作dist文件夹内的文件,同时加入了文件改动自动更新的功能,但是这些功能都是只适用于开发环境,生产环境用不到这些内容,只需要打包构建后的内容即可,所以,一切又回到了原点。

所以要处理这种情况,需要将生产环境和开发环境的配置区分开来。

切分不同环境配置

image.png

首先创建,webpack.dev.jswebpack.prod.js用来分别配置开发环境以及生产环境不同的配置

开发环境配置

先列举一下开发环境webpack.dev.js所需的配置项

  1. mode开发模式要设置为development
  2. devServer,热更新功能必备

webpack.dev.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
    entry: './src/index.js',
    output: {
        path: path.join(__dirname, './dist'),
        filename: 'bundle_[hash].js'
    },
    mode: 'development',
    module: {
        rules: [
            {
                test: /\.js$/,
                use: 'babel-loader'
            },
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                ]
            },
            {
                test: /\.(png|jpe?g|webp|svg|gif)$/,
                use: 'file-loader'
            }
        ]
    },
    devServer: {
        static: './dist',
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, './src/index.html'),
        }),
        new MiniCssExtractPlugin(),
        new CleanWebpackPlugin(),
    ]
}

阅读webpack-dev-server文档,发现webpack-dev-server支持读取具体的配置文件启动

image.png

根据命令创建开发环境启动命令

package.json

{
  "name": "wepack-course",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "watch": "webpack --watch",
    "start": "webpack-dev-server --open",
    "dev": "webpack-dev-server --open --config webpack.dev.js"  // 开发环境
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.17.8",
    "@babel/preset-env": "^7.16.11",
    "@babel/preset-react": "^7.16.7",
    "babel-loader": "^8.2.4",
    "clean-webpack-plugin": "^4.0.0",
    "css-loader": "^6.7.1",
    "file-loader": "^6.2.0",
    "html-webpack-plugin": "^5.5.0",
    "mini-css-extract-plugin": "^2.6.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "style-loader": "^3.3.1",
    "webpack": "^5.70.0",
    "webpack-cli": "^4.9.2",
    "webpack-dev-server": "^4.7.4"
  }
}

执行npm run dev查看效果,结果正常

生产环境配置

生产环境的配置梳理

  1. mode为production
  2. 不需要热更新即不需要webpack-dev-server

webpack.prod.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
    entry: './src/index.js',
    output: {
        path: path.join(__dirname, './dist'),
        filename: 'bundle_[hash].js'
    },
    mode: 'production',
    module: {
        rules: [
            {
                test: /\.js$/,
                use: 'babel-loader'
            },
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                ]
            },
            {
                test: /\.(png|jpe?g|webp|svg|gif)$/,
                use: 'file-loader'
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, './src/index.html'),
        }),
        new MiniCssExtractPlugin(),
        new CleanWebpackPlugin(),
    ]
}

修改package.json里的build的命令

{
  "name": "wepack-course",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config webpack.prod.js",  // 直接打包生产文件
    "watch": "webpack --watch",
    "start": "webpack-dev-server --open",
    "dev": "webpack-dev-server --open --config webpack.dev.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.17.8",
    "@babel/preset-env": "^7.16.11",
    "@babel/preset-react": "^7.16.7",
    "babel-loader": "^8.2.4",
    "clean-webpack-plugin": "^4.0.0",
    "css-loader": "^6.7.1",
    "file-loader": "^6.2.0",
    "html-webpack-plugin": "^5.5.0",
    "mini-css-extract-plugin": "^2.6.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "style-loader": "^3.3.1",
    "webpack": "^5.70.0",
    "webpack-cli": "^4.9.2",
    "webpack-dev-server": "^4.7.4"
  }
}

执行npm run build,这里没有热更新了,需要手动打开dist里面的index.html查看网页,结果正常。

这样就区分开了不同环境的配置,根据不同目的执行不同命令,就可以在开发环境和生产环境之间切换,可以删除原来的webpack.config.js

但是这样会有一个问题,就是每次我增加了新的loader或者plugin,比如要在项目中使用typescript,需要增加ts-loader,这样的话webpack.dev.jswebpack.prod.js里面的module都要进行配置,如果依赖多的话,两个文件都要添加,这也挺麻烦的。

webpack-merge可以很好的解决这个问题

webpack-merge

webpack-merge根据字面意思,就是合并两个webpack配置文件

安装webpack-merge

npm i webpack-merge -D

提取不同配置文件的共同配置

新建webpack.common.js

image.png

配置不同环境的共同配置

webpack.common.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
    entry: './src/index.js',
    output: {
        path: path.join(__dirname, './dist'),
        filename: 'bundle_[hash].js'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                use: 'babel-loader'
            },
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                ]
            },
            {
                test: /\.(png|jpe?g|webp|svg|gif)$/,
                use: 'file-loader'
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, './src/index.html'),
        }),
        new MiniCssExtractPlugin(),
        new CleanWebpackPlugin(),
    ]
}

不同环境配置和公共配置合并

webpack.dev.js

const { merge } = require('webpack-merge');
const common = requrie('./webpack.common.js');

module.exports = merge(common, {
    mode: 'development',

    devServer: {
        static: './dist',
    }
});

webpack-merge提供一个merge函数,第一个参数是被合并配置,第二个参数为新的配置,返回新的一个配置。

这里common就是公共基础配置

执行命令npm run dev

正常展示,OK!

webpack.prod.js

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

module.exports = merge(common, {
    mode: 'production'
});

执行命令npm run build

正常展示!

至此,不同环境的配置完美解决,只需要根据需求,分别在不同环境的配置文件进行特殊处理即可!

总结

对于开发与生产环境,webpack有必要切分不同配置文件,通过webpack-merge合并公共配置,以打造舒服的开发环境,同时又保证生产环境正确无误,同时也有利于整个项目的维护。

至此webpack项目打包的基础阶段已结束,根据这个阶段的内容,对于一个小巧且不太考虑性能的项目已经可以搭建起来,功能也已经够用了。

接下来便是对webpack的进阶阶段,打造更加优雅,具备更佳性能的项目。

webpack打包系列-进阶功能

我是aWuYa,如果觉得我的文章对你有小小的帮助,麻烦给我点个赞,创作不易,你的点赞就是我最大的动力,万分感谢!