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
,设为true
contentBase
(默认当前工作目录)下文件变更都会触发刷新,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/polyfill
7.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