webpack学习(十四):生产环境搭建

demo地址: https://github.com/Lkkkkkkg/webpack-demo
继上一次配置完react的热替换: https://blog.csdn.net/qq593249106/article/details/84947301

当前 webpack.config.js

目前使用的 webpack 配置文件包含了生产模式和开发模式,
webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
var devMode = true; //设为开发模式
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');


module.exports = {
    mode: 'development',
    entry: { //入口文件
        index: "./src/components/index/index.js",
        otherA: "./src/components/otherA/otherA.js",
        otherB: "./src/components/otherB/otherB.js",
    },
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'js/[name].js', //根据入口文件分为不同出口文件
    },
    devtool: 'inline-source-map', // 不同选项适用于不同环境
    devServer: {
        contentBase: './dist', //将dist目录下的文件(index.html)作为可访问文件, 如果不写这个参数则默认与webpack.cofig.js的同级目录
        port: 8080, //端口号设为8080, 默认也是8080
    },
    module: {
        rules: [ //配置加载器, 用来处理源文件, 可以把es6, jsx等转换成js, sass, less等转换成css
            {
                exclude: /node_modules|packages/, //路径
                test: /\.js$/, //配置要处理的文件格式,一般使用正则表达式匹配
                use: 'babel-loader', //使用的加载器名称
            },
            {
                test: /\.(sa|sc|c)ss$/,
                use: [
                    devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
                    'css-loader',
                    'sass-loader',
                ],
            },
        ]
    },
    plugins: [ //webpack 通过 plugins 实现各种功能, 比如 html-webpack-plugin 使用模版生成 html 文件
        new CleanWebpackPlugin(['dist']), //设置清除的目录
        new HtmlWebpackPlugin({
            template: "./src/components/index/index.html", //设置生成的HTML文件的名称, 支持指定子目录,如:assets/admin.html
            chunks: ['index', 'commons'], //指定入口文件
            filename: "index.html" //指定模板文件的位置
        }),
        new HtmlWebpackPlugin({
            template: "./src/components/otherA/otherA.html",
            chunks: ['otherA', 'commons'],
            filename: "otherA.html"
        }),
        new HtmlWebpackPlugin({
            template: "./src/components/otherB/otherB.html",
            chunks: ['otherB', 'commons'],
            filename: "otherB.html"
        }),
        new MiniCssExtractPlugin({
            filename: 'css/[name].css', //类似出口文件
            chunkFilename: 'css/[id].css'
        }),
        new OptimizeCssAssetsPlugin({
            assetNameRegExp: /\.css$/g, //一个正则表达式,指示应优化\最小化的资产的名称。提供的正则表达式针对配置中ExtractTextPlugin实例导出的文件的文件名运行,而不是源CSS文件的文件名。默认为/\.css$/g
            cssProcessor: require('cssnano'), //用于优化\最小化CSS的CSS处理器,默认为cssnano。这应该是一个跟随cssnano.process接口的函数(接收CSS和选项参数并返回一个Promise)。
            cssProcessorOptions: { safe: true, discardComments: { removeAll: true } }, //传递给cssProcessor的选项,默认为{}
            canPrint: true //一个布尔值,指示插件是否可以将消息打印到控制台,默认为true
        })
    ],
    optimization: {
        splitChunks: {
            cacheGroups: {
                //打包公共模块
                commons: {
                    chunks: 'initial', //initial表示提取入口文件的公共部分
                    minChunks: 2, //表示提取公共部分最少的文件数
                    minSize: 0, //表示提取公共部分最小的大小
                    name: 'commons' //提取出来的文件命名
                }
            }
        }
    }
};

配置

开发环境(development)和生产环境(production)的构建目标差异很大, 在开发环境中,我们需要具有强大的、具有实时重新加载(live reloading)或热模块替换(hot module replacement)能力的 source map 和 localhost server, 而在生产环境中, 我们的目标则转向于关注更小的 bundle, 更轻量的 source map, 以及更优化的资源, 以改善加载时间。由于要遵循逻辑分离, 我们通常建议为每个环境编写彼此独立的 webpack 配置

使用 webpack-merge

将生产模式和开发模式的公共部分写在 webpack.comon.js, 生产模式单独写在 webpack.prod.js, 开发模式单独写在 webpack.dev.js, 然后通过 webpack-merge 这个工具将它们连接起来

安装

npm install webpack-merge --save-dev 

分离代码

webpack.common.js

const path = require('path'); //公共模块
const CleanWebpackPlugin = require('clean-webpack-plugin'); //公共插件
const HtmlWebpackPlugin = require('html-webpack-plugin'); //公共插件


module.exports = {
    entry: { //公共entry
        index: "./src/components/index/index.js",
        otherA: "./src/components/otherA/otherA.js",
        otherB: "./src/components/otherB/otherB.js",
    },
    output: { //公共output
        path: path.join(__dirname, 'dist'), 
        filename: 'js/[name].js', //根据入口文件分为不同出口文件
    },
    module: {
        rules: [ //公共配置加载器
            {
                exclude: /node_modules|packages/, 
                test: /\.js$/, 
                use: 'babel-loader', 
            }
        ]
    },
    plugins: [
        new CleanWebpackPlugin(['dist']), 
        new HtmlWebpackPlugin({
            template: "./src/components/index/index.html", 
            chunks: ['index', 'commons'], 
            filename: "index.html" 
        }),
        new HtmlWebpackPlugin({
            template: "./src/components/otherA/otherA.html",
            chunks: ['otherA', 'commons'],
            filename: "otherA.html"
        }),
        new HtmlWebpackPlugin({
            template: "./src/components/otherB/otherB.html",
            chunks: ['otherB', 'commons'],
            filename: "otherB.html"
        })
    ]

};

webpac.dev.js

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

module.exports = merge(common, {
    mode: 'development', //开发模式会将 process.env.NODE_ENV 的值设为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin。
    module: {
        rules: [
            {
                test: /\.(sa|sc|c)ss$/,
                use: [
                    'style-loader', //开发模式不使用插件
                    'css-loader',
                    'sass-loader',
                ],
            }
        ]
    },
    devtool: 'inline-source-map', //开发模式启用代码跟踪
    devServer: { //开发模式启用服务器
        contentBase: './dist',
        port: 8080,
    }
});

webpack.prod.js

const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); //生产模式使用分离代码插件
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); //生产模式使用压缩代码插件

module.exports = merge(common, {
    mode: "production", //生产模式会将 process.env.NODE_ENV 的值设为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 TerserPlugin.
    module: {
        rules: [
            {
                test: /\.(sa|sc|c)ss$/,
                use: [
                    MiniCssExtractPlugin.loader, //生产模式使用分离代码插件
                    'css-loader',
                    'sass-loader',
                ],
            }
        ]
    },
    devtool: 'source-map', //生产模式启用代码跟踪
    plugins: [
        new MiniCssExtractPlugin({ //生产模式使用分离代码插件
            filename: 'css/[name].css'
        }),
        new OptimizeCssAssetsPlugin({ //生产模式使用压缩代码插件
            assetNameRegExp: /\.css$/g,
            cssProcessor: require('cssnano'),
            cssProcessorOptions: { safe: true, discardComments: { removeAll: true } },
            canPrint: true
        })
    ],
    optimization: {
        splitChunks: {
            cacheGroups: {
                //生产打包公共模块
                commons: {
                    chunks: 'initial', //initial表示提取入口文件的公共部分
                    minChunks: 2, //表示提取公共部分最少的文件数
                    minSize: 0, //表示提取公共部分最小的大小
                    name: 'commons' //提取出来的文件命名
                }
            }
        }
    }
});

修改NPM脚本配置

package.json

{
  "name": "demo05",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --colors --config webpack.prod.js", //生产模式关联 webpack.prod.js 加上--progress显示构建百分比
    "dev": "webpack-dev-server --open --hot --progress --config webpack.dev.js" //开发模式关联 webpack.dev.js 加上--progress显示构建百分比
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1",
    "clean-webpack-plugin": "^1.0.0",
    "css-loader": "^2.0.0",
    "html-webpack-plugin": "^3.2.0",
    "mini-css-extract-plugin": "^0.5.0",
    "node-sass": "^4.11.0",
    "optimize-css-assets-webpack-plugin": "^5.0.1",
    "react": "^16.6.3",
    "react-dom": "^16.6.3",
    "react-hot-loader": "^4.3.12",
    "sass-loader": "^7.1.0",
    "style-loader": "^0.23.1",
    "webpack": "^4.27.1",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.10",
    "webpack-merge": "^4.1.5"
  },
  "dependencies": {
    "lodash": "^4.17.11"
  }
}

运行和打包

终端分别输入 npm run build 和 npm run dev, 都能正常打包和运行

你可能感兴趣的:(webpack,webpack)