webpack的默认行为会在一个模块发生变化的时候把所有模块都重新打包
开启HMR功能后,只重新打包变化的模块,其它模块使用缓存
样式文件天然支持这个功能(devserver 的hot配置默认为true)
js的支持:(vue-loader和react-loader都默认支持了这样的功能,不需要我们单独实现)
if(module.hot) {
module.hot.accept('./xx.js') // 被引入的模块发生变化时,就会启用热模块更新
}
webpack的默认行为是当一个类型的检查是否使用某一个loader进行处理时,即使匹配到了也会在接下来的所有规则中进行再次匹配(走完所有的rules规则匹配)
使用oneOf解决上面的问题
rules: [
{
oneOf:[
...rules
]
}
]
两个配置只能同时是用一个,可以设置包含(include)或者设置排除(exclude)
一般对js处理(babel和eslint比较耗时),因为代码量比较大
// loader 的配置
{
test: /\.js$/,
exclude: /(node_modules)/, // 使用这种
include: path.join(__dirname, 'src'), // 或者使用这种
use: [...]
}
// 插件的配置
new ESLintPlugin({
context: path.join(__dirname, 'src'), // 配置eslint检测范围
exclude: 'node_modules' // 这是一个默认值
}),
前面提到js文件的编译需要进行babel和eslint的处理,比较耗时,所有这里说的缓存也只针对这两个过程
bebel-loader 配置
{
loader: 'babel-loader?',
options: {
cacheDirectory: true, // 开启babel缓存
cacheCompression: false // 关闭缓存文件压缩(耗时无意义,线上用不到)
}
}
eslint 配置
new ESLintPlugin({
context: path.join(__dirname, 'src'), // 配置eslint检测范围
exclude: 'node_modules', // 这是一个默认值
cache: true, // 开启缓存
cacheLocation: path.resolve(__dirname, './node_modules/.cache/eslint') // 设置缓存目录
}),
注意: 把注意写在前面,每个进程打开大概需要 600ms 的时间,建议在文件量很大的情况下使用
一样是针对最耗时的任务 js 处理 babel 和 eslint 检查使用
安装依赖(用于babel编译开启多进程)
npm install thread-loader -D
获取 cpu 核心数量
const os = require('os')
const threads = os.cpus().length
增加多进程配置添加到 babel-loader 前面
{
test: /\.js$/,
exclude: /(node_modules)/, // 设置哪些目录不需要扫描
use: [
{
loader: 'thread-loader', // 开启多线程处理 babel
options: {
works: threads // 设置线程数量
}
},
{
loader: 'babel-loader?cacheDirectory', //开启缓存,可以设置缓存目录
}
]
}
引入 webpack5 内置压缩 js 代码的插件
const TerserWebpackPlugin = require('terser-webpack-plugin')
js代码压缩开启多进程
plugins: [
new TerserWebpackPlugin({
parallel: threads // js 代码压缩开启多进程,threads:cpu 核心数量
})
]
// 或者放入optimization中,和之前的 css 压缩一样
optimization: {
minimizer: [
new CssMinimizerPlugin(),
new TerserWebpackPlugin({
parallel: threads // js 代码压缩开启多进程,threads:cpu 核心数量
})
]
}
eslint 开启多进程
new ESLintPlugin({
context: path.join(__dirname, 'src'), // 配置eslint检测范围
exclude: 'node_modules', // 这是一个默认值
cache: true, // 开启缓存
cacheLocation: path.resolve(__dirname, './node_modules/.cache/eslint') // 设置缓存目录
+ threads, // +++ eslint 开启多进程
}),
依赖安装1
npm install image-minimizer-webpack-plugin -D
无损压缩依赖
npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo --save-dev
有损压缩依赖
npm install imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant imagemin-svgo --save-dev
配置
// webpack.config.js
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
const { extendDefaultPlugins } = require("svgo");
plugins: [
new ImageMinimizerPlugin({
minimizerOptions: {
// Lossless optimization with custom option
// Feel free to experiment with options for better result for you
plugins: [
["gifsicle", { interlaced: true }],
["jpegtran", { progressive: true }],
["optipng", { optimizationLevel: 5 }],
// Svgo configuration here https://github.com/svg/svgo#configuration
[
"svgo",
{
plugins: extendDefaultPlugins([
{
name: "removeViewBox",
active: false,
},
{
name: "addAttributesToSVGElement",
params: {
attributes: [{ xmlns: "http://www.w3.org/2000/svg" }],
},
},
]),
},
],
],
},
}),
],
这种方式的依赖安装问题比较大
也可以使用第二种方式完成图片压缩:
安装依赖
npm install @squoosh/lib --save-dev
有损压缩:
// 引入依赖
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
// 使用插件(放入plugins)
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.squooshMinify,
options: {
// Your options for `squoosh`
},
},
}),
// 再说一次还可以在 optimization 中使用
optimization: {
minimizer: [
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.squooshMinify,
options: {
// Your options for `squoosh`
},
},
}),
],
},
无损压缩
optimization: {
minimizer: [
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.squooshMinify,
options: {
encodeOptions: {
mozjpeg: {
// That setting might be close to lossless, but it’s not guaranteed
// https://github.com/GoogleChromeLabs/squoosh/issues/85
quality: 100,
},
webp: {
lossless: 1,
},
avif: {
// https://github.com/GoogleChromeLabs/squoosh/blob/dev/codecs/avif/enc/README.md
cqLevel: 0,
},
},
},
},
}),
],
},