专栏首页coding for love4-2 Development 和 Production 模式的区分打包

4-2 Development 和 Production 模式的区分打包

1. 简介

接上节4-1 Tree Shaking 概念详解末尾,我们可以看到,在 mode 进行切换时,webpack.config.js 的配置也是不一样的。这很好理解,开发环境中我们更多地是考虑开发和调试方便,生产环境我们更多考虑性能。但我们总不会每次切换环境的时候,还要手动去更改配置吧。最简单就是保存两份配置,对应不同的环境。

2. 开发环境配置

// webpack.dev.js
var HtmlWebpackPlugin = require('html-webpack-plugin');
var { CleanWebpackPlugin } = require('clean-webpack-plugin');
var path = require('path');
var webpack = require('webpack');

module.exports = {
    mode: 'development',
    entry: {
        index: "./src/index.js",
    },
    devtool: "cheap-module-eval-source-map",
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "[name].js"
    },
    devServer: {
        contentBase: path.resolve(__dirname, 'dist'),
        open: true,
        port: 3000,
        hot: true // 开启热更新
    },
    module: {
        rules: [
            {
                test: /\.(jpg|jpeg|png|gif)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        name: '[name].[ext]',
                        limit: 2048
                    }
                }
            },
            {
                test: /\.css$/,
                use: [ 'style-loader', 'css-loader' ]
            },
            {
                test: /\.scss$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'postcss-loader',
                    'sass-loader',
                ]
            },
            {
                test: /\.(eot|svg|ttf|woff)$/,
                use: 'file-loader'
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: "./src/index.html"
        }),
        new CleanWebpackPlugin(),
        new webpack.HotModuleReplacementPlugin()
    ]
};
"dev": "webpack-dev-server --config webpack.dev.js"

3. 生产环境配置

// webpack.prod.js
var HtmlWebpackPlugin = require('html-webpack-plugin');
var { CleanWebpackPlugin } = require('clean-webpack-plugin');
var path = require('path');

module.exports = {
    mode: 'production',
    entry: {
        index: "./src/index.js",
    },
    devtool: "cheap-module-source-map",
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "[name].js"
    },
    module: {
        rules: [
            {
                test: /\.(jpg|jpeg|png|gif)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        name: '[name].[ext]',
                        limit: 2048
                    }
                }
            },
            {
                test: /\.css$/,
                use: [ 'style-loader', 'css-loader' ]
            },
            {
                test: /\.scss$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'postcss-loader',
                    'sass-loader',
                ]
            },
            {
                test: /\.(eot|svg|ttf|woff)$/,
                use: 'file-loader'
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: "./src/index.html"
        }),
        new CleanWebpackPlugin()
    ]
};
"build": "webpack --config webpack.prod.js"

4. 公共配置抽取

可以看到开发环境和生产环境配置,存在很多一致的地方,写两套即浪费代码体积,又增加维护成本,我们尝试将其抽取。

// webpack.common.js
var HtmlWebpackPlugin = require('html-webpack-plugin');
var { CleanWebpackPlugin } = require('clean-webpack-plugin');
var path = require('path');

module.exports = {
    entry: {
        index: "./src/index.js",
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "[name].js"
    },
    module: {
        rules: [
            {
                test: /\.(jpg|jpeg|png|gif)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        name: '[name].[ext]',
                        limit: 2048
                    }
                }
            },
            {
                test: /\.css$/,
                use: [ 'style-loader', 'css-loader' ]
            },
            {
                test: /\.scss$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'postcss-loader',
                    'sass-loader',
                ]
            },
            {
                test: /\.(eot|svg|ttf|woff)$/,
                use: 'file-loader'
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: "./src/index.html"
        }),
        new CleanWebpackPlugin()
    ]
};

提取后,dev 和 prod 如下:

// webpack.dev.js
var path = require('path');
var webpack = require('webpack');

module.exports = {
    mode: 'development',
    devtool: "cheap-module-eval-source-map",
    devServer: {
        contentBase: path.resolve(__dirname, 'dist'),
        open: true,
        port: 3000,
        hot: true // 开启热更新
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin()
    ]
};
// webpack.prod.js

module.exports = {
    mode: 'production',
    devtool: "cheap-module-source-map"
};

5. 合并配置

上面提取公共配置以后,dev 和 prod 的配置只剩很小一部分了,那么如何将公共配置与单独的环境配置合并到一起呢?需要使用 webpack-merge 库。

npm i webpack-merge -D
// webpack.dev.js
var path = require('path');
var webpack = require('webpack');
var merge = require('webpack-merge');
var commonConfig = require('./webpack.common');

var devConfig = {
    mode: 'development',
    devtool: "cheap-module-eval-source-map",
    devServer: {
        contentBase: path.resolve(__dirname, 'dist'),
        open: true,
        port: 3000,
        hot: true // 开启热更新
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin()
    ]
};

module.exports = merge(commonConfig, devConfig);
// webpack.prod.js
var merge = require('webpack-merge');
var commonConfig = require('./webpack.common');

var prodConfig = {
    mode: 'production',
    devtool: "cheap-module-source-map"
};

module.exports = merge(commonConfig, prodConfig);

6. mode 选择

webpack 可以使用 mode 告知 webpack 使用相应模式的内置优化。可以理解为一系列配置的合集就是 mode。

image.png

7. 移动配置文件

现在的配置文件很分散,我们将他们挪到同一个目录 build 下:

image.png

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

运行打包命令 npm run dev

image.png

发现,build 目录下多了一个 dist。我们修改源码后,重新打包,发现 build/dist 的页面更新,但是 dist 下没有更新。这说明,代码输出的地址发生了改变,并且清除旧的打包代码插件的作用地址也发生了改变。这两个分别对应 output 和 CleanWebpackPlugin。 我们先改一下 output,如下:

    output: {
        path: path.resolve(__dirname, '../dist'),
        filename: "[name].js"
    },

删掉两个 dist,打包后如下:

image.png

说明输出地址已经正确了。我们在 dist 加一个文件 temp.js,重新打包,如下:

image.png

temp.js 消失了,说明 CleanWebpackPlugin 已经正确生效。这一点和视屏讲述不一样,因为 CleanWebpackPlugin 已经升级,会将作用目标定为 output.path,不需要再像旧版一样传入 root 来指定根目录。详见 https://github.com/johnagan/clean-webpack-plugin/issues/106

参考

https://www.webpackjs.com/concepts/mode/ https://www.npmjs.com/package/clean-webpack-plugin

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 4-12 环境变量的使用

    其实我么之前已经将webpack.config.js 按环境进行去了区分配置,那么在公共配置文件中我们能否知道当前所处的环境,并据此做逻辑区分呢?

    love丁酥酥
  • 3-1 Loader是什么

    前面说过,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler),我们也看到了webpack对js文件的打包...

    love丁酥酥
  • 5-12 webpack 性能优化(3)

    及时删除无用的模块,不要引入无用的文件,使用 treeshaking 尽量减少包体。也可以利用 splitchunks 将包文件切割,有效率利用缓存。

    love丁酥酥
  • webpack 入门教程

    本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归...

    老马
  • webpack处理url资源的配置

    Dream城堡
  • webpack4实用配置指南-上手篇

    算起来已经有3到4个项目的webpack构建打包经历。然而每次搭建起来还是有新手既视感,比较捉急。工具用法的东西,好记性不如烂笔头,有必要系统梳理下webpac...

    elson
  • 转 入门Webpack,看这篇就够了

    2017年8月13日更新,本文依旧最新的webpack3.5.3将代码部分完全重写,所有代码都在Mac上正常运行过。希望依旧对你学习webpack有帮助。 ...

    jojo
  • vue+webpack搭建单文件应用和多文件应用webpack.config.js的写法区别

    这几天,都遇到过有人问过相似的问题,就是用vue和webpack搭建目录的时候,怎么把单页面应用的配置改成多文件应用,或者是怎么把多文件应用的配置改成单文件应用...

    守候i
  • 详解Webpack的loader和plugin编写

    loader是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中。

    Dunizb

扫码关注云+社区

领取腾讯云代金券