使用 Webpack 进行生产环境配置(附 Demo)

栏目: JavaScript · 发布时间: 5年前

内容简介:本文从代码压缩、代码拆分、样式分离等三个方面对生产环境的代码进行了优化。只是最简单的一些配置,如果真正运用到项目中,还需要根据项目添加更多配置。本文讲述的是如何对生产环境下的代码进行压缩,如果还不是太了解 Webpack 的朋友,可以先看一下我的上一篇文章:本文项目代码位置:

本文从代码压缩、代码拆分、样式分离等三个方面对生产环境的代码进行了优化。只是最简单的一些配置,如果真正运用到项目中,还需要根据项目添加更多配置。

前言

本文讲述的是如何对生产环境下的代码进行压缩,如果还不是太了解 Webpack 的朋友,可以先看一下我的上一篇文章: 从零开始搭建一个 Webpack 开发环境配置(附 Demo)

本文项目代码位置: 源码地址

环境搭建

项目结构

首先编写一个项目,初始化 npm,然后 在本地安装 webpack,接着安装 webpack-cli(此 工具 用于在命令行中运行 webpack):

$ mkdir webpack-prod-demo

$ cd webpack-prod-demo

$ npm init -y

$ npm install webpack webpack-cli --save-dev
复制代码

project

webpack-prod-demo
|- package.json
|- /public
  |- index.html
|- /src
  |- index.js
  |- index.css
复制代码

pubic/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Webpack 生产环境配置</title>
</head>
<body>
    
</body>
</html>
复制代码

index.js

import './index.css';

function component() {
    var element = document.createElement('div');

    element.innerHTML = 'Hello World';
  
    return element;
}
  
document.body.appendChild(component());
复制代码

index.css

div {
    color: blue;
    text-align: center;
}
复制代码

package.json

{
  "name": "webpack-prod-demo",
  "version": "1.0.0",
  "description": "",
  "private": true,
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config webpack.config.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
复制代码

配置 webpack.config.js 文件

在根目录下新建 webpack.config.js 文件,并进行基本配置

安装插件

# 安装 babel-loader
$ npm install babel-core babel-loader@7 --save-dev

# 安装 babel presets
$ npm install babel-preset-env babel-preset-stage-0 --save-dev

# 安装 babel plugins 
$ npm install babel-plugin-transform-class-properties babel-plugin-transform-runtime babel-runtime --save-dev

# 安装其余所需 loader
$ npm install css-loader style-loader file-loader csv-loader xml-loader html-loader markdown-loader --save-dev

# 安装 webpack 插件
$ npm install clean-webpack-plugin html-webpack-plugin friendly-errors-webpack-plugin --save-dev
复制代码

配置 webpack.config.js:

webpack.config.js

const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');

module.exports = {
    mode: 'development',
    devtool: 'hidden-source-map',
    entry: './src/index.js',
    output: {
        filename: '[name]-[hash:8].js',
        path: path.resolve(__dirname, 'dist')
    },
    plugins: [
        new HTMLWebpackPlugin({
            // 用于生成的HTML文档的标题
            title: 'Webpack 生产环境配置',
            // webpack 生成模板的路径
            template: './public/index.html'
        }),
        // 用法:new CleanWebpackPlugin(paths [, {options}])
        new CleanWebpackPlugin(['dist']),
        // 在命令行进行友好提示
        new FriendlyErrorsWebpackPlugin()
    ],
    module: {
        rules: [
            {
                test: /\.js/,
                include: path.resolve(__dirname, 'src'),
                loader: 'babel-loader?cacheDirectory'
            },
            // 解析 css
            {
                test: /\.css$/,
                include: path.resolve(__dirname, 'src'),
                use: [
                    'style-loader',
                    // 还可以给 loader 添加一些配置
                    {
                        loader: 'css-loader',
                        options: {
                            // 开启 sourceMop
                            sourceMap: true
                        }
                    }
                ]
            },
            // 解析图片资源
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: [
                    'file-loader'
                ]
            },
            // 解析 字体
            {
                test: /\.(woff|woff2|eot|ttf|otf)$/,
                use: [
                    'file-loader'
                ]
            },
            // 解析数据资源
            {
                test: /\.(csv|tsv)$/,
                use: [
                    'csv-loader'
                ]
            },
            // 解析数据资源
            {
                test: /\.xml$/,
                use: [
                    'xml-loader'
                ]
            },
            // 解析 MakeDown 文件
            {
                test: /\.md$/,
                use: [
                    "html-loader", 
                    "markdown-loader"
                ]
            }
        ]
    }
}
复制代码

在项目根目录下创建 .babelrc 文件

.babelrc

{
    "presets": ["env", "stage-0"],
    "plugins": [
        "transform-runtime",
        "transform-class-properties"
    ]
}
复制代码

基本配置完成后运行项目

在命令行运行指令:

$ npm run build
复制代码

此时在浏览器打开 dist 文件夹下的 html 文件,页面上正常显示 蓝色居中的 Hello World

查看此时 dist 文件大小:

使用 Webpack 进行生产环境配置(附 Demo)

设置 mode 为 production

webpack.config.js

...
module.exports = {
    mode: 'production'
    ...
}
复制代码

设置为生产环境后运行项目

在命令行运行指令:

$ npm run build
复制代码

此时在浏览器打开 dist 文件夹下的 html 文件,页面上还是能够正常显示 蓝色居中的 Hello World

查看此时 dist 文件大小:

使用 Webpack 进行生产环境配置(附 Demo)

本文的重点:优化打包

安装需要用到的插件:

# 安装压缩 js、 css 代码的插件
$ npm install uglifyjs-webpack-plugin optimize-css-assets-webpack-plugin --save-dev

# 安装提取 css 的插件
$ npm install mini-css-extract-plugin --save-dev
复制代码

uglifyjs-webpack-plugin 和 optimize-css-assets-webpack-plugin 的使用

webpack.config.js

...;
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");

module.exports = {
    ...,
    optimization: {
        // 打包压缩js/css文件
        minimizer: [
            new UglifyJsPlugin({
                uglifyOptions: {
                    compress: {
                        // 在UglifyJs删除没有用到的代码时不输出警告
                        warnings: false,
                        // 删除所有的 `console` 语句,可以兼容ie浏览器
                        drop_console: true,
                        // 内嵌定义了但是只用到一次的变量
                        collapse_vars: true,
                        // 提取出出现多次但是没有定义成变量去引用的静态值
                        reduce_vars: true,
                    },
                    output: {
                        // 最紧凑的输出
                        beautify: false,
                        // 删除所有的注释
                        comments: false,
                    }
                }
            }),
            new OptimizeCSSAssetsPlugin({
                cssProcessorOptions: {
                    safe: true
                }
            })
        ]
    }
}
复制代码

uglifyjs-webpack-plugin 更多配置请参考: 插件文档

optimize-css-assets-webpack-plugin 更多配置请参考: 插件文档

mini-css-extract-plugin 的使用

注意:MiniCssExtractPlugin.loader 和 style-loader 一起使用可能出现问题。所以下面我将 style-loader 去掉了。

webpack.config.js

...;
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    ...
    plugins: [
        ...,
        // 打包后提取出css文件
        new MiniCssExtractPlugin({
            filename: '[name].[contenthash:8].css',
            chunkFilename: '[name].[contenthash:8].chunk.css'
        })
    ],
    module: [
        rules: [
            ...,
            // 解析 css
            {
                test: /\.css$/,
                include: path.resolve(__dirname, 'src'),
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader
                    },
                    // 还可以给 loader 添加一些配置
                    {
                        loader: 'css-loader',
                        options: {
                            // 开启 sourceMop
                            sourceMap: true
                        }
                    }
                ]
            },
            ...
        ]
    ]
}
复制代码

mini-css-extract-plugin 更多配置请参考: 插件文档

chunk 拆分

webpack.config.js

...;

module.exports = {
    ...,
    optimization: {
        // 打包压缩js/css文件
        minimizer: [
            ...
        ],
        splitChunks: {
            chunks: 'all'
        }
    }
}
复制代码

splitChunks 更多配置请参考:官方文档。

进行配置优化后运行项目

在命令行运行指令:

$ npm run build
复制代码

此时在浏览器打开 dist 文件夹下的 html 文件,页面上仍能正常显示 蓝色居中的 Hello World

查看此时 dist 文件大小:

使用 Webpack 进行生产环境配置(附 Demo)

webpack.config.js 文件最终代码

其余文件基本未进行修改。在此将 webpack.config.js 代码贴出来

webpack.config.js

const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');


module.exports = {
    mode: 'production',
    devtool: 'hidden-source-map',
    entry: './src/index.js',
    output: {
        filename: '[name]-[hash:8].js',
        path: path.resolve(__dirname, 'dist')
    },
    plugins: [
        new HTMLWebpackPlugin({
            // 用于生成的HTML文档的标题
            title: 'Webpack 开发环境配置',
            // webpack 生成模板的路径
            template: './public/index.html'
        }),
        // 用法:new CleanWebpackPlugin(paths [, {options}])
        new CleanWebpackPlugin(['dist']),
        // 在命令行进行友好提示
        new FriendlyErrorsWebpackPlugin(),
        // 打包后提取出css文件
        new MiniCssExtractPlugin({
            filename: '[name].[contenthash:8].css',
            chunkFilename: '[name].[contenthash:8].chunk.css'
        })
    ],
    module: {
        rules: [
            {
                test: /\.js/,
                include: path.resolve(__dirname, 'src'),
                loader: 'babel-loader?cacheDirectory'
            },
            // 解析 css
            {
                test: /\.css$/,
                include: path.resolve(__dirname, 'src'),
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader
                    },
                    // 还可以给 loader 添加一些配置
                    {
                        loader: 'css-loader',
                        options: {
                            // 开启 sourceMop
                            sourceMap: true
                        }
                    }
                ]
            },
            // 解析图片资源
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: [
                    'file-loader'
                ]
            },
            // 解析 字体
            {
                test: /\.(woff|woff2|eot|ttf|otf)$/,
                use: [
                    'file-loader'
                ]
            },
            // 解析数据资源
            {
                test: /\.(csv|tsv)$/,
                use: [
                    'csv-loader'
                ]
            },
            // 解析数据资源
            {
                test: /\.xml$/,
                use: [
                    'xml-loader'
                ]
            },
            // 解析 MakeDown 文件
            {
                test: /\.md$/,
                use: [
                    "html-loader", 
                    "markdown-loader"
                ]
            }
        ]
    },
    optimization: {
        // 打包压缩js/css文件
        minimizer: [
            new UglifyJsPlugin({
                uglifyOptions: {
                    compress: {
                        // 在UglifyJs删除没有用到的代码时不输出警告
                        warnings: false,
                        // 删除所有的 `console` 语句,可以兼容ie浏览器
                        drop_console: true,
                        // 内嵌定义了但是只用到一次的变量
                        collapse_vars: true,
                        // 提取出出现多次但是没有定义成变量去引用的静态值
                        reduce_vars: true,
                    },
                    output: {
                        // 最紧凑的输出
                        beautify: false,
                        // 删除所有的注释
                        comments: false,
                    }
                }
            }),
            new OptimizeCSSAssetsPlugin({
                cssProcessorOptions: {
                    safe: true
                }
            })
        ],
        splitChunks: {
            chunks: 'all'
        }
    }
}
复制代码

对比

通过三次打包的对比,可以看到:

  • 第一次普通配置打包后,包大小为 48.1 K
  • 第二次设置为生产环境后打包,包大小为 39.0 K
  • 第三次进行优化配置后打包,包大小为 1.46 K

目前这个项目一个 js 文件,代码量很少,但是还是可以看到优化的效果的。如果项目更大的话,优化的效果也会更明显。当然,需要的配置可能更多了。

项目源码

源码地址

总结

本文只是对于生产环境下代码打包的简单优化,在项目实战的过程中,可能会需要更多的配置。其实无论看多少教程,其实里面的配置都不一定能够满足自身的要求。在开发的过程中,还是需要自己根据需求进行配置。

其实 Webpack 的学习并不难,根据官网的说明和指南,其实基本都会使用。难的是各种 loader、plugin 自身的配置。这些都需要去到 loader 和 plugin 的网站上深入研究才可以。所以想要更好的进行 webpack 配置,还是需要多多留意最新技术的出现,多搜集有用的插件和配置。积少成多,慢慢的就能配置出更好的项目脚手架(目前这也是我的目标)。


以上所述就是小编给大家介绍的《使用 Webpack 进行生产环境配置(附 Demo)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

SEO实战密码

SEO实战密码

昝辉 / 电子工业出版社 / 2012-5-1 / 89.00元

SEO实战密码:60天网站流量提高20倍(第2版),ISBN:9787121167676,作者:昝辉Zac 著一起来看看 《SEO实战密码》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

在线进制转换器
在线进制转换器

各进制数互转换器