Webpack5热替换,压缩JS、CSS、图片,基础优化新方法
本文基于最新Webpack5配置HMR热替换、JS、CSS、图片压缩,基础优化并生成Source Map
热替换 · HMR · Hot Module Replace
JS 和 CSS 热替换
只需将hot设为true,不需要引入热替换插件,在入口.js,添加module.hot.accept()即可
// 配置:webpack.config.js
devServer: {
hot: true
}
// 入口:index.js
if (module.hot) {
module.hot.accept(); // bundle.js 支持HMR
}
import './style.css'; // CSS作为模块引入 支持HMR
注意:如果css模块命名包含[contenthash]或[chunkhash],HMR会失效
建议只在生产环境配置hash,开发环境HMR本身已经解决缓存问题
new MiniCssExtractPlugin({
filename: 'style.[contenthash].css' // 开发环境:style.css即可
}),
HTML 热更新
开启热替换后,.html默认不再自动刷新,您可以:
- 在
hot下新增参数watchContentBase,设为truecontentBase(默认当前工作目录)下文件变更都会触发刷新,JS和CSS的热替换失效
- 通过
raw-loader将.html作为资源引入入口.js.html成为模块可以热更新,JS和CSS热替换有效,可能需要在html手动引用它们
HtmlWebpackPlugin多用来将html作为模版,自动引用打包好的JS和CSS不用插件,用nodejs的chokidar配合before参数,.html内容变化时通知server更新即可
npm i chokidar -D
devServer: {
hot: true,
before(_, server) {
const chokidar = require('chokidar');
const files = [
resolve('src-es6/index-tpl.html') // 与 HtmlWebpackPlugin 的 template 对应
];
chokidar.watch(files).on('all', () => {
server.sockWrite(server.sockets, 'content-changed');
})
}
}
综上,我们实现了JS和CSS热替换(不刷新更新),HTML热更新(自动刷新页面)
JavaScript压缩
TerserPlugin
Webpack5自带,不用安装。暂时忘记UglifyjsPlugin ParallelUglifyPlugin和环境变量吧
optimization: {
minimize: true, // 可省略,默认最优配置:生产环境,压缩 true。开发环境,不压缩 false
minimizer: [
new TerserPlugin({
parallel: true, // 可省略,默认开启并行
terserOptions: {
toplevel: true, // 最高级别,删除无用代码
ie8: true,
safari10: true,
}
})
}
cache不再单独配置。遵循webpack的cache设置(与optimization同级)
cache: true // 可省略,默认最优配置:生产环境,不缓存 false。开发环境,缓存到内存,memory
sourceMap不再单独配置。遵循webpack的devtool配置(与cache同级)
devtool: env.NODE_ENV === 'production' ? 'source-map' : 'inline-source-map' // 官方推荐生产环境和开发环境的配置
Babel
开启缓存babel-loader?cacheDirectory仍是提高Babel性能有效方式
cache-loader类似,thread-loader代替HappyPack,为其后loader开启单独worker pool
两者只用npm i cache-loader -D npm i thread-loader -D放到需要作用的loader前面即可
module: {
rules: [{
test: /\.js$/,
include: resolve('src-es6/js'), // test、include、exclude 缩小查找范围
use: [
'cache-loader', // 缓存其后loader结果
'thread-loader', // 其后loader开启独立worker池
{
loader: 'babel-loader?cacheDirectory', // 开启babel-loader缓存
options: {
presets: '@babel/preset-env',
plugins: [
['@babel/plugin-transform-runtime',
{ 'corejs': 3 }]
]
}
}
]
}]
}
preset-env-2015等以年代latest结尾的预设已成为过去。只是为了es5+转es5,可直接
npm i @babel/preset-env -D
默认除语法外,Babel对ES6的新增接口如includes不会转成老接口
为了兼容,需要在老浏览器上引入polyfill,即纯JS实现新增接口
@babel/polyfill7.4.0起废弃,不用配置useBuiltIns,用@babel/plugin-transform-runtim
npm i @babel/plugin-transform-runtime -D
指定corejs版本
2仅支持全局变量,如Promise等3还支持实例属性,包括includes等 安装即可
npm i @babel/runtime-corejs3 -D
作用域提升 · Scope Hoisting
多ES6模块放闭包,减冗余并加速。ModuleConcatenationPlugin曾是首选,Webpack4+默认支持
optimization: {
concatenateModules: true // 可省略,默认最优配置,生产环境作用域提升开启 true,开发环境禁用 false
}
其它
HardSourceWebpackPlugin DllPlugin和DLLReferencePlugin,随着Webpack4+自身编译加快
曾经收益可观的优化方式,在一些项目中已经不那么必要,但他们的贡献有目共睹,至今仍被使用
CSS压缩
MiniCssExtractPlugin
Webpack4+以后,抽离CSS到独立文件,通过MiniCssExtractPlugin实现
npm i mini-css-extract-plugin -D
// 入口:index.js
import './style.css';
// 配置:webpack.config.js
module: {
rules: [
{
test: /\.css$/,
include: resolve('src-es6/css'), // test、include、exclude 缩小查找范围
use: [
MiniCssExtractPlugin.loader, // 放在css-loader前
{ loader: 'css-loader',
options: { sourceMap: true } } // 影响所有依赖css-loader的插件生成sourceMap
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'style.css', // 指定文件名 生产环境可写成 style.[contenthash].css 避免缓存问题
}),
]
CssMinimizerPlugin
MiniCssExtractPlugin推荐CssMinimizerPlugin压缩CSS,自带cssnano。暂时忘记PurgeCSS吧
npm i css-minimizer-webpack-plugin -D
配置:webpack.config.js
optimization: {
minimizer: [
new CssMinimizerPlugin({
parallel: true, // 可省略,默认开启并行
sourceMap: true, // 可省略,默认遵循webpack的devtool配置
minimizerOptions: {
preset: 'advanced', // 需额外安装
},
})
]
}
sourceMap可单独配置。不配置时遵循webpack的devtool配置(与optimization同级)
插件自带的preset默认是default。cssnano共支持3种预设优化方案

移除未使用CSSdiscardUnused在优化方案advance中,安装cssnano-preset-advanced即可
npm i cssnano-preset-advanced -D
图片压缩
CSS内联图片
url-loader小于指定尺寸图片转base64
module: {
rules: [{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10, // 小于10KB图片,转base64编码
}
}]}
图片模块
import/require到.js或.html中require(图片路径)的图
file-loader+image-webpack-loader
rules: [{
test: /\.png$/i, // 以png为例
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
pngquant: {
quality: [0.65, 0.90] // 设置png的品质区间
},
}
},
],
}]
图片目录
如果图片是直接引入到.html,或者通过.js加载,上面方法无效,实际项目中
- 图片多在同一目录
CopyPlugin在编译时,从源目录src复制到发布目录dist
npm i imagemin-webpack-plugin -D
注意 插件默认安装gifsicle,如果你的网络环境一直失败,请用cnpm安装
使用cnpm后,删node_modules目录,再cnpm i将之前用npm装的重装一遍,避免其它问题
plugins: [
new CopyPlugin({
patterns: [{
from: resolve('src-es6/images'),
to: resolve('dist/images'),
}]
}),
new ImageminPlugin({ // 在CopyPlugin之后。如果是merge多配置文件,CopyPlugin放common被合并的配置里
test: /\.(png|jpe?g)$/i,
pngquant: {
quality: '70-75' // 设置png的品质区间
},
plugins: [ // 可以引入其它图片压缩插件
ImageminMozjpeg({
quality: 70, // 设置jpeg/jpg的品质
progressive: true // 渐进式:true:由模糊到清晰加载 false:从上到下加载
})
]
}),
]
自带jpegtran不能调品质,在《ImageminPlugin支持图片压缩插件列表》选插件
安装ImageminMozjpeg即可
npm i imagemin-mozjpeg -D
转载自:https://juejin.cn/post/6910913987613818894