◆
gulp-imagemin 图片压缩安装与使用
图片往往是页面里体积最大的一块,压缩带来的收益比压 JS/CSS 更直接。gulp-imagemin 把这件事接进 gulp 的流式管道:读取源图 → 压缩 → 写到输出目录,一条 task 覆盖整个目录。
它本身只是个 gulp 包装层,实际干活的是按格式分的几个压缩器插件,得按需组合。压缩方式分有损和无损两类:jpg 走有损(调 quality 换体积),png 走无损优化(重排色板、去冗余块),svg 是删掉编辑器留下的元数据。质量参数不能一味压低,jpg 的 quality 一般 75 上下是体积和观感的平衡点。
gulp-imagemin
安装
npm install gulp-imagemin --save-dev
使用
标准的 gulp 三段式:src 读文件(注释里也给出了传数组和用 ! 排除的写法)→ pipe 处理 → dest 写出。
imagemin([...]) 里按格式各配一个压缩器:gifsicle 的 interlaced 开隔行扫描,让 gif 加载时从模糊到清晰而不是从上往下刷;mozjpeg 的 quality: 75 是有损压缩质量,progressive: true 生成渐进式 jpg;optipng 的 optimizationLevel: 5(范围 0-7)是无损压缩强度,越高越慢;svgo 保留 viewBox(删掉的话 svg 就没法响应式缩放了)、并保留 id(cleanupIDs: false,避免 id 被重命名后 CSS 或 JS 里的引用失效)。
外面包的那层 cache(...) 来自 gulp-cache,作用是跳过已压缩过的图片,没有它每次构建都要把所有图重压一遍。
const gulp = require('gulp');
const {
getProjectPath,
getNpmArgs,
runCmd,
} = require('mio-common-js/cjsUtils/utils');
const imagemin = require('gulp-imagemin');
const cache = require('gulp-cache');
gulp.task(
'build',
gulp.series(async done => {
gulp
.src(getProjectPath('../../resource/img/**')) // 源文件 可以传数组 gulp.src(['src/js/*.js', '!src/js/**/{test1,test2}.js'])
.pipe(
cache(
imagemin([
imagemin.gifsicle({
// 隔行扫描gif进行渲染
interlaced: true,
}),
imagemin.mozjpeg({
// 压缩质量
quality: 75,
// 无损压缩jpg图片
progressive: true,
}),
imagemin.optipng({
optimizationLevel: 5,
}),
imagemin.svgo({
plugins: [
// 不要移除svg的viewbox属性
{ removeViewBox: true },
{ cleanupIDs: false },
],
}),
]),
),
)
.pipe(gulp.dest(getProjectPath('../../../mio-blog/images')), {
// overwrite: true,
// append: true,
}); // 设定输出目录
}),
);
注意事项
gulp-imagemin从 v7 开始改成了纯 ESM 包,require引不进来,只能用import或者动态import()。gulpfile 还是 CommonJS 的项目要么锁在 v6,要么把配置文件改成.mjs。- 同样从 v7 起,各个压缩器不再挂在
imagemin对象上(imagemin.mozjpeg这种写法失效),要单独安装imagemin-mozjpeg等包再分别引入。上面这段是 v6 及之前的写法。 svgo的插件配置格式在 svgo v2 之后变了,改成{ name: 'removeViewBox', active: false }这种形式。这里的{ removeViewBox: true }是旧格式,而且按旧格式的语义true是「启用移除」——和注释说的「不要移除」正好相反,实际会把viewBox删掉。要保留应该写false。- task 里的 async 函数没有 return 那个 stream,也没调
done(),gulp 判断不出任务何时结束,可能在压缩完成前就退出。规范写法是return gulp.src(...)。

还没有留言,来发表第一条吧~