◆
gulp-cache 配合 imagemin 缓存图片压缩结果
图片压缩是构建里最慢的一环,几百张图跑一遍要好几分钟。问题在于 gulp 的任务是无状态的:每次执行都把 src 匹配到的文件全量重新处理一遍,哪怕这次只新增了一张图。
gulp-cache 就是给这类耗时插件加一层结果缓存。它的做法是对每个文件的内容算哈希,把处理结果连同哈希一起存到本地(默认在系统临时目录);下次构建时哈希没变就直接取缓存里的产物,跳过实际处理。所以第一次构建照样慢,从第二次开始只有改动过的文件才会真正走压缩。
用法上它是个包装器——把原来的插件调用套进 cache() 里就行,对被包装的插件无侵入。
gulp-cache
安装
npm i -D gulp-cache
配合 gulp-imagemin 的完整用法。关键就是 .pipe(cache(imagemin([...]))) 这一层嵌套——原本是 .pipe(imagemin([...])),套上 cache() 之后,流里每个文件先查缓存,命中就直接输出缓存结果,不命中才交给 imagemin 处理并把结果存起来。
缓存键基于文件内容而不是修改时间,所以 git checkout 切分支导致 mtime 变化但内容没变时,缓存依然有效。
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,
}); // 设定输出目录
}),
);
注意事项
- 缓存只认文件内容,认不出压缩参数的变化。把
quality从 75 调到 60 后重新构建,缓存照样命中,产出的还是旧参数压出来的图。改完配置要手动清缓存:cache.clearAll(),或者删掉磁盘上的缓存目录。 - 缓存默认存在系统临时目录,CI 环境每次都是干净容器,所以缓存必然不命中。想在 CI 里受益得把缓存目录配到工作区内并纳入 CI 的缓存机制。
- 只对确定性的处理有意义。同样输入每次产出不同结果的插件(比如带时间戳、随机 hash 的),缓存会给出过期或错误的产物。
- 缓存目录会随着图片版本迭代不断变大,长期不清理会占不少磁盘。

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