有时候,Webpack打包后文件体积往往会过大,我们可以通过代码压缩的方式来减少Webpack打包后文件的体积。对代码进行压缩不仅可以有效提升网页加载的速度,还具有混淆源码的作用。就算别人下载了网页的代码,由于代码是压缩过的,也就增加了代码分析和改造的难度。
下面,我们逐一介绍如何在 Webpack中压缩代码:
压缩 HTML
在Webpack中,我们都会使用 html-webpack-plugin 插件来自动生成 HTML文件。当我们使用该插件时不配置任何选项,会生成如下未压缩的HTML文件:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Webpack App</title>
</head>
<body>
<script type="text/javascript" src="main.bundle.js"></script></body>
</html>
html-webpack-plugin
html-webpack-plugin 提供的 minify 属性可以帮助我们对生成的 HTML 进行压缩,配置如下:
const htmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
plugins: [
new htmlWebpackPlugin({
template: "./src/index.html", // 读取的模板文件
filename: "index.html", // 生成的文件
minify: {
// 压缩HTML文件
removeComments: true, // 移除HTML中的注释
collapseWhitespace: true, // 删除空白符与换行符
minifyCSS: true, // 压缩内联css
},
}),
],
};
压缩后的HTML文件如下:
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Webpack App</title></head><body><script type="text/javascript" src="main.bundle.js"></script></body></html>
压缩CSS
CSS代码也是造成文件体积过大的原因之一,因此,我们也需要对 CSS代码进行压缩。cssnano 是目前比较成熟的 CSS压缩工具。它是基于 PostCSS 的,它会在保持 CSS 代码语义不变的情况下,将多余的空白符及注释删除,对CSS选择器进行压缩,并清理没用的CSS 代码。以确保最终生成的文件对生产环境来说体积是最小的。
/* normalize selectors */
h1::before, h1:before {
/* reduce shorthand even further */
margin: 10px 20px 10px 20px;
/* reduce color values */
color: #ff0000;
/* remove duplicated properties */
font-weight: 400;
font-weight: 400;
/* reduce position values */
background-position: bottom right;
/* normalize wrapping quotes */
quotes: '«' "»";
/* reduce gradient parameters */
background: linear-gradient(to bottom, #ffe500 0%, #ffe500 50%, #121 50%, #121 100%);
/* replace initial values */
min-width: initial;
}
/* correct invalid placement */
@charset "utf-8";
上面是一段未压缩过的CSS代码,使用 cssnano 进行压缩后的代码如下:
@charset "utf-8";h1:before{margin:10px 20px;color:red;font-weight:400;background-position:100% 100%;quotes:"«" "»";background:linear-gradient(180deg,#ffe500,#ffe500 50%,#121 0,#121);min-width:0}
optimize-css-assets-webpack-plugin
把 cssnano 接入到Webpack 中十分简单,在Webpack4 中我们使用 optimize-css-assets-webpack-plugin 插件,并在其实例对象中配置 cssProcessor ,将其压缩引擎指定为 cssnano 。配置代码如下:
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const htmlWebpackPlugin = require("html-webpack-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
module.exports = {
module: {
rules: [
{
test: /\.less$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: "../",
},
},
"css-loader",
"postcss-loader",
"less-loader",
],
},
],
},
plugins: [
new htmlWebpackPlugin({
template: "./src/index.html",
filename: "index.html",
minify: {
// 压缩HTML文件
removeComments: true, // 移除HTML中的注释
collapseWhitespace: true, // 删除空白符与换行符
minifyCSS: true, // 压缩内联css
},
}),
new MiniCssExtractPlugin({
filename: "css/[name]-[contenthash:6].css", // 给输出的 CSS 文件加上 Hash 值
}),
new OptimizeCSSAssetsPlugin({
cssProcessor: require("cssnano"), // 这里制定了引擎,不指定默认也是 cssnano
}),
],
};
在 Webpack 中使用 cssnano 的另一种方式是开启 css-loader 的 minimize 选项。相关Webpack配置如下:
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const htmlWebpackPlugin = require("html-webpack-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
module.exports = {
module: {
rules: [
{
test: /\.less$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: "../",
},
},
{
loader: 'css-loader',
options: {
minimize: true || {/* CSSNano Options */}
}
},
"postcss-loader",
"less-loader",
],
},
],
},
plugins: [
new htmlWebpackPlugin({
template: "./src/index.html", // HTML 模板文件所在的路径
filename: "index.html", // 输出的 HTML文件名称
minify: {
// 压缩HTML文件
removeComments: true, // 移除HTML中的注释
collapseWhitespace: true, // 删除空白符与换行符
minifyCSS: true, // 压缩内联css
},
}),
new MiniCssExtractPlugin({
filename: "css/[name]-[contenthash:6].css", // 给输出的 CSS 文件加上 Hash 值
}),
new OptimizeCSSAssetsPlugin({
cssProcessor: require("cssnano"), // 这里制定了引擎,不指定默认也是 cssnano
}),
],
};
压缩 JavaScript
terser-webpack-plugin
业界中比较成熟的 JavaScript 代码压缩工具是 UglifyJS,它会分析 JavaScript 代码语法树,理解代码含义,能做到去掉无效代码、去掉日志输出代码、缩短变量名等优化。但该工具在 ES6 代码压缩上做的不够好,于是有了 uglify-es,但 uglify-es 已经不再维护了。因此我们推荐使用 terser-webpack-plugin,它是从 uglify-es 拉出来的一个分支,是 Webpack 官方维护的插件。
安装方法如下:
npm install terser-webpack-plugin --save-dev
Webpack 相关配置如下:
const TerserPlugin = require("terser-webpack-plugin");
module.exports = {
entry: {
"add-number": "./src/index.js",
"add-number.min": "./src/index.js",
},
output: {
filename: "[name].js", // 指定打包出来的文件名称
library: "addNumber", // 指定打包出来的库的名称
libraryTarget: "umd", // 指定打包出来的规范
libraryExport: "default", //必要
},
mode: "none",
optimization: {
minimize: true,
minimizer: [
// 使用 terser-webpack-plugin 压缩 JavaScript
new TerserPlugin({
test: /\.min\.js$/, // 指定只有 min.js 的文件才压缩
}),
],
},
};
以上就是Webpack中代码压缩常用的几种方式。
