这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战
介绍
相信很多刚入行的小伙伴在开发项目时,不止一次的用了很多本地图片资源,很多都是找线上或电脑软件的去压缩体积的,当然其实在webpack时就可以进行其压缩优化了,本期我们将介绍一种webpack图像压缩插件——image-minimizer-webpack-plugin,它就是用于使用imagemin来压缩所有图像。所以以后不要担心图像的大小了,现在它们是可以自动被优化/压缩的。
安装
# NPM
npm install --save-dev image-minimizer-webpack-plugin
# Yarn
yarn add -D image-minimizer-webpack-plugin
使用
为了演示我们就简单做一个index.html,在其逻辑脚本为app.js中我们放了两张本地的图片,一个是png的,一个svg的。
// app.js
import "./assets/style.css"
const imgs = [require("./assets/01.png"),require("./assets/02.svg")];
imgs.forEach(src=>{
let img = document.createElement("img");
img.src = src;
document.getElementById("app").appendChild(img)
})
然后我们执行yarn build命令去打包,记录一下这两张图片打包后的大小。
接下来,正题就要开始了。
我们做之前要清楚,这个插件可以使用2个工具来优化/生成图像:
- imagemin:默认优化您的图像,因为它稳定且适用于所有类型的图像
- squoosh:在实验模式下使用.jpg, .jpeg, .png, .webp,.avif文件类型工作。
我们本次要使用的是imagemin,所以我们要预先装其插件内容,官方又给出了两种搭配:
-
推荐用于无损优化的 imagemin 插件:
npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo --save-dev
-
推荐用于无损优化的 imagemin 插件:
npm install imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant imagemin-svgo --save-dev
其中imagemin-mozjpeg和imagemin-svgo可以配置为无损和有损模式。
安装完成后,我们执行以下操作:
// webpack.config.js
const TARGET = process.env.npm_lifecycle_event;
const optimization = {
minimizer: []
}
if (TARGET.indexOf("build")!=-1) {
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
const imageMinimizerPlugin = new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify, // 共有imageminMinify和squooshMinify两种模式
options: {
plugins: [
["gifsicle", { interlaced: true }],
["jpegtran", { progressive: true }],
["optipng", { optimizationLevel: 5 }],
["svgo", {
plugins: [
'preset-default',
{
name: "removeViewBox",
active: false,
},
{
name: "addAttributesToSVGElement",
params: {
attributes: [{ xmlns: "http://www.w3.org/2000/svg" }],
},
},
],
},
],
],
},
},
})
optimization.minimizer.push(imageMinimizerPlugin)
}
module.exports = {
// ...
module: {
rules: [
// ...
{
test: /\.(jpe?g|png|gif|svg)$/i,
type: "asset",
},
]
},
optimization
// ...
}
可以发现我们先通过process.env.npm_lifecycle_event拿到当前指令,如果是要执行打包命令的话。我们再去最终压缩才有意义(目前这个简单业务场景是这样的)。而且这个插件要放到optimization的minimizer里面。
值得注意的是上面的代码是svgo9以上的写法。如果svgo 9以下需要使用extendDefaultPlugins,如下:
// svgo 9 以下:
const { extendDefaultPlugins } = require("svgo");
["svgo",{
plugins: extendDefaultPlugins([
// ...
])
}]
现在我们再执行一遍打包,就会发现目录如下:
振奋人心的时刻到了,刚刚还1.5mb的png变成1mb了,而且svg也小了4kb。当然目前是无损压缩,如果想要更小,可以手动改成有损的数值。
吐槽
但是说实话,如果做简单的页面应用其实webpack自动压缩图片是可以的,如果本地图片非常多且非常大其实并不合适让其自动压缩,因为太太耗时了!!!
还有imagemin-jpegtran和imagemin-gifsicle这俩插件,有时候还下载不下来,改hosts配置,科学上网有时候都没用,可有时候一遍就成,方了方了。。
结语
我们今天简单介绍和使用了一下image-minimizer-webpack-plugin这个插件,如果你想自己搭建一套脚手架自动处理一些本地图像可以考虑它。当然今天只是一些皮毛,还用更多的一些配置和使用方法等待你的发掘,比如过滤等,你可以进入其image-minimizer-webpack-plugin仓库里自行发掘。