文章目录
系列文章目录
第一章 webpack5介绍及基本使用(一)
第二章 webpack5介绍及基本使用(二)
前言
新春愉快!前面的文章介绍了webpack5的entry、output、mode、loader配置、plugins配置还有环境变量配置,这一章主要是优化项目,一方面为了项目性能对产出代码进行优化,另一方面也为了开发体验和效率,会介绍更多的 plugins
配置以及 optimization
配置。
完善配置
1. 压缩生产代码
首先是压缩 webpack 打包文件,压缩资源使浏览器下载资源时间减少,主要采用
gzip
算法进行压缩,不过随着Brotli
压缩越来越受欢迎,更多 Web 服务器使用 Brotli 做为默认压缩设置。Brotli 是 Google 在 2013年底推出的一款开源通用数据压缩器,并在 Github 开源,Brotli 专为 web数据设计,对于 web网络流数据的压缩效率更高,现在已经被大多数知名浏览器和 Web 服务器采用。
1.1 依赖服务器配置
开启gzip与Brotli需要服务器支持,比如配置nginx代理开启压缩,每次浏览器请求资源时,nginx服务器对文件进行压缩后返回给浏览器,压缩文件会需要时间和占用服务器cpu资源,更好的方式是前端在打包的时候直接生成已压缩的资源,服务器接收到请求,可以直接把对应压缩好的文件返回给浏览器。
1.2 工作原理
- 浏览器请求url,并在请求头中设置属性accept-encoding:gzip。表明浏览器支持gzip,这个参数是浏览器自动会携带的请求头信息。
- 服务器收到浏览器发送的请求之后,服务器会返回压缩后的文件,并在响应头中包含content-encoding: gzip;如果没有压缩文件,服务器会返回未压缩的请求文件。
- 浏览器接收到到服务器的响应,根据content-encoding: gzip 响应头使用gzip策略去解压压缩后的资源,通过content-type内容类型决定怎么编码读取该文件内容。
npm i compression-webpack-plugin -D
// webpack.pro.js
const { merge } = require('webpack-merge');
const baseConfig = require('./webpack.base');
const CompressionPlugin = require('compression-webpack-plugin');
const zlib = require('zlib');
module.exports = merge(baseConfig, {
mode: 'production', //production——默认代码压缩
plugins: [
// 针对gzip压缩的打包配置
new CompressionPlugin({
filename: '[path][base].gz', // 文件命名
algorithm: 'gzip', // 压缩格式,默认是gzip
test: /\.js$|\.css$|\.html$/, // 只生成css,js,html压缩文件
threshold: 10240, // 只有大小大于该值的资源会被处理。默认值是 10k,文件太小可能会反向压缩
minRatio: 0.8, // 压缩率,默认值是 0.8
}),
// 针对Brotli压缩的打包配置,如果服务器没有开启Brotli压缩,那就没必要配置
new CompressionPlugin({
filename: '[path][base].br',
algorithm: 'brotliCompress',
test: /\.(js|css|html|svg)$/,
compressionOptions: {
params: {
[zlib.constants.BROTLI_PARAM_QUALITY]: 11,
},
},
threshold: 10240, // 只有大小大于该值的资源会被处理。默认值是 10k
minRatio: 0.8,
}),
],
// ...
});
2. 打包进度展示以及美化
2.1 使用 webpack.ProgressPlugin(已内置)
// webpack.pro.js
const { merge } = require('webpack-merge');
const baseConfig = require('./webpack.base');
const webpack = require('webpack');
module.exports = merge(baseConfig, {
mode: 'production', //production——默认代码压缩
plugins: [
// 配置项按需开启,这里我保持简洁全关了
new webpack.ProgressPlugin({
entries: false, // 默认true,显示正在进行的条目计数消息。
modules: false, // 默认true,显示正在进行的模块计数消息。
dependencies: false, // 默认true,显示正在进行的依赖项计数消息。
// activeModules: false, // 默认false,显示活动模块计数和一个活动模块正在进行消息。
// modulesCount: 5000, // 默认5000,开始时的最小模块数。PS:modules启用属性时生效。
// profile: false, // 默认false,告诉ProgressPlugin为进度步骤收集配置文件数据。
// dependenciesCount: 10000, // 默认10000,开始时的最小依赖项计数。PS:dependencies启用属性时生效。
}),
// ...
],
// ...
});
2.2 使用 webpackbar
npm i webpackbar@5 -D
webpackbar 的5.0.2版本兼容Node14,使用webpackbar最新版本需要使用较新的Node版本。
// webpack.pro.js
const { merge } = require('webpack-merge');
const baseConfig = require('./webpack.base');
const WebpackBar = require('webpackbar');
module.exports = merge(baseConfig, {
mode: 'production', //production——默认代码压缩
plugins: [
new WebpackBar(),
// ...
],
// ...
});
3. 分析打包文件的大小
npm i webpack-bundle-analyzer -D
分析打包文件结果不能对平时打包造成影响,所以单独创建 analyzer
脚本命令用于特定的分析场景。
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --config ./build/webpack.dev.js",
"build": "cross-env NODE_ENV=production webpack --config ./build/webpack.pro.js",
"pre": "cross-env NODE_ENV=pre webpack --config ./build/webpack.pro.js",
"pre-dev": "cross-env NODE_ENV=pre webpack-dev-server --config ./build/webpack.dev.js",
"analyzer": "cross-env NODE_ENV=production webpack --config ./build/webpack.analyzer.js"
},
在build目录下新建 webpack.analyzer.js 文件,针对生产配置进行合并
const prodConfig = require('./webpack.pro.js'); // 引入打包配置
const { merge } = require('webpack-merge'); // 引入合并webpack配置方法
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); // 打包结果分析插件
module.exports = merge(prodConfig, {
plugins: [
new BundleAnalyzerPlugin(), // 配置分析打包结果插件
],
});
4. 分析打包用时
原本在webpack4版本采用的speed-measure-webpack-plugin在webpack5上存在兼容问题,而插件开发者长时间没有进行更新维护了,所以我采用了 time-analytics-webpack-plugin
插件进行分析。
npm i time-analytics-webpack-plugin -D
// webpack.analyzer.js
const prodConfig = require('./webpack.pro.js'); // 引入打包配置
const { merge } = require('webpack-merge'); // 引入合并webpack配置方法
const { TimeAnalyticsPlugin } = require('time-analytics-webpack-plugin'); // webpack打包速度分析插件
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); // 打包结果分析插件
module.exports = TimeAnalyticsPlugin.wrap(
merge(prodConfig, {
plugins: [
new BundleAnalyzerPlugin(), // 配置分析打包结果插件
],
})
);
5. 设置Cache改善构建速度
// webpack.base.js
module.exports = {
// ...
cache: {
// 默认是memory,将缓存类型设置为文件系统,持久缓存会将缓存存储到磁盘
type: 'filesystem',
buildDependencies: {
// 更改配置文件时,重新缓存
config: [__filename],
},
},
}
6. 设置Stats 对象(控制台信息显示)
stats 选项让你更精确地控制 bundle 信息该怎么显示。
// webpack.base.js
module.exports = {
// ...
stats: {
//配置项按需开启,这里我让控制台尽量保持简洁所以把打包信息全关了
assets: false, //是否展示资源信息
chunks: false,
colors: true,
modules: false, //构建模块的信息
entrypoints: false, //展示入口文件与对应的文件 bundles
},
}
7. fix:修改html文件后没触发热更新
需要在webpack入口文件(index.js文件)里引入.html文件。
import './index.html';
8. 优化(Optimization)
webpack5是开箱即用的,默认的 Optimization 配置对于大部分用户来说非常友好。
当采用第三方库的时候,可能就需要使用 splitChunks
进行拆分包,将满足拆分规则的内容抽出来单独打包,比如当第三包代码没变化时,对应chunkhash值也不会变化,从而可以有效利用浏览器缓存,也可以减少重复打包耗时。
// webpack.pro.js
module.exports = {
// ...
optimization: {
// ...
splitChunks: {
// 分隔代码
cacheGroups: {
// 提取node_modules代码
vendors: {
test: /node_modules/,
name: 'vendors',
minChunks: 1, // 只要使用一次就提取出来
chunks: 'initial', // 只提取初始化就能获取到的模块,不管异步的
minSize: 0, // 提取代码体积大于0就提取出来
priority: 1, // 提取优先级为1,默认组的优先级为负
},
// 提取页面公共代码
commons: {
name: 'commons',
minChunks: 2, // 只要使用两次就提取出来
chunks: 'initial', // 只提取初始化就能获取到的模块,不管异步的
minSize: 0, // 提取代码体积大于0就提取出来
},
},
},
}
}
总结
关于webpack5的配置就到此为止了,已经成功将开发环境、预发环境、生产环境配置完成,另外还做了打包资源的分析,有助于开发者对项目进行针对性的优化,开发环境配置了开发服务器保持所有资源文件的热更新,另外也做了一些常见优化构建速度和构建结果的配置。当然这篇文章只是简单的配置介绍,如果想运用好webpack还需要深入学习webpack的构建原理以及loader和plugin的实现机制。希望这系列文章能帮助大家更好地理解运用webpack5打包前端项目。
欢迎各位看官【点赞】、【收藏】,多多支持!也欢迎您【评论】留下宝贵意见,共同探讨一起学习~