gulpで画像を圧縮する
タグ:
結論
動作確認環境
Node.js v16.13.0
"devDependencies": {
"del": "^6.0.0",
"gulp": "^4.0.2",
"gulp-imagemin": "^7.1.0",
"gulp-notify": "^4.0.0",
"gulp-plumber": "^1.2.1",
"imagemin-mozjpeg": "^9.0.0",
"imagemin-pngquant": "^9.0.2"
}
使い方
- プロジェクトのディレクトリに移動し、
npm i
コマンドでパッケージをインストールする npx gulp imagemin
コマンドでsrc/img/
以下の画像を圧縮してdist/assets/img/
以下に吐き出すnpx gulp watch
コマンドでwatch
モードを起動できる。watch
モード下ではsrc/img/
以下の変更を検知して自動で画像圧縮タスクが走る
解説
gulpfile.jsは以下のように記述しています。
const gulp = require("gulp");
const plumber = require("gulp-plumber");
const notify = require("gulp-notify");
const imagemin = require("gulp-imagemin");
const imageminMozjpeg = require("imagemin-mozjpeg");
const pngquant = require("imagemin-pngquant");
const del = require("del");
const imageMinify = () => {
return gulp
.src("src/img/**/*", { since: gulp.lastRun(imageMinify) })
.pipe(plumber({ errorHandler: notify.onError("<%= error.message %>") }))
.pipe(
imagemin([
imagemin.gifsicle({ optimizationLevel: 3 }),
pngquant({ quality: [0.65, 0.8], speed: 1 }),
imageminMozjpeg({
quality: 65,
}),
imagemin.svgo({
plugins: [
{
removeViewBox: false,
},
],
}),
]),
)
.pipe(gulp.dest("dist/assets/img/"));
};
const cleanImage = () => {
return del("dist/assets/img/");
};
const watch = (done) => {
gulp.watch("src/img/**/*", imageMinify);
done();
};
exports.watch = watch;
exports.imagemin = gulp.series(cleanImage, imageMinify);
画像圧縮タスクはimageMinify
という名前の関数で定義しています。
const imageMinify = () => {
...
};
画像圧縮のためのパッケージとしてimageminを使用しています。gulp用のパッケージgulp-imagemin
があるので、今回はこちらを使用します。また、JPEGのコンバーターをしてMozJPEGを、PNGのコンバーターとしてpngquantを使用しています。共にimageminのプラグインimagemin-mozjpeg
およびimagemin-pngquant
が提供されているので、それらを使用します。
gulp
はgulpの本体、gulp-plumber
はエラーが起きたときにgulpタスクを停止させないようにするパッケージ、gulp-notify
はエラーを通知するためのパッケージです。
del
はディレクトリ・ファイルを削除するためのパッケージです(後述)。
const gulp = require("gulp");
const plumber = require("gulp-plumber");
const notify = require("gulp-notify");
const imagemin = require("gulp-imagemin");
const imageminMozjpeg = require("imagemin-mozjpeg");
const pngquant = require("imagemin-pngquant");
const del = require("del");
...
src/img/**/*
ディレクトリのファイルをソースとして処理を行います。
optimizationLevel
やquality
といった項目を変更することで、圧縮のクオリティを調整できます。実際に圧縮してみて、加減してみるといいでしょう。
最後にdist/assets/img/
へ画像を吐き出しています。
...
const imageMinify = () => {
return gulp
// `{ since: gulp.lastRun(imageMinify) }`を設定することで、
// 前回実行時からの差分のファイルのみを対象としてタスクを実行することができる。
.src("src/img/**/*", { since: gulp.lastRun(imageMinify) })
.pipe(plumber({ errorHandler: notify.onError("<%= error.message %>") }))
.pipe(
imagemin([
// GIF用の設定
imagemin.gifsicle({ optimizationLevel: 3 }),
// PNG用の設定
pngquant({ quality: [0.65, 0.8], speed: 1 }),
// JPEG用の設定
imageminMozjpeg({
quality: 65,
}),
// SVG用の設定
imagemin.svgo({
plugins: [
{
removeViewBox: false,
},
],
}),
])
)
.pipe(gulp.dest("dist/assets/img/"));
};
...
定義したimageMinify関数をimagemin
という名前でエクスポートしておきます。これによりnpx gulp imagemin
コマンドで画像圧縮タスクが走るようになりました。
...
exports.imagemin = imageMinify;
...
これで画像を圧縮できるようになりました。しかし、このままでは画像を追加する度に上記のコマンドを叩く必要があります。それでは面倒なので、src/img/
ディレクトリに画像を追加、または画像を変更したら自動で画像圧縮のタスクが走るようにしてみます。
watch
を使ってsrc/img/
ディレクトリのファイルを監視対象とし、ファイルの追加・変更でimageMinify
が実行されるようにします。
こちらもwatch
という名前でエクスポートしておきます。これによりnpx gulp watch
コマンドでwatch
モードを起動できます。普段の制作ではwatch
モードを起動しておいた方が便利でしょう。
...
const watch = (done) => {
gulp.watch("src/img/**/*", imageMinify);
done();
};
exports.watch = watch;
...
最後に、もう1つやっておくことがあります。
現在の状態では、src/img/
の画像を削除しても、dist/assets/img/
の中の圧縮後のファイルは削除されません。もっと便利な方法があるかもしれませんが、ここではnpx gulp imagemin
で画像を圧縮する前に、dist/assets/img/
ディレクトリを削除するという大雑把な方法を取ります。
新しくcleanImage
という関数を定義します。この関数ではdel
を使用してdist/assets/img/
を削除する処理を行います。続いて、imagemin
の定義を更新します。gulp.series()
を使用し、cleanImage
→imageMinify
の順で処理を実行するようにします。
npx gulp imagemin
コマンドで一旦圧縮済みの画像を全て削除したあと改めてimageMinify
を実行するようになりました。節目ごとにnpx gulp imagemin
を実行することで、src
とdist
でファイルの一貫性を保つことができます。
...
const imageMinify = () => {
...
};
const cleanImage = () => {
return del("dist/assets/img/");
};
const watch = (done) => {
gulp.watch("src/img/**/*", imageMinify);
done();
};
exports.watch = watch;
exports.imagemin = gulp.series(cleanImage, imageMinify);
これで画像圧縮タスクの完成です。ディレクトリのパス等はお使いの環境に合わせて変更してください。