メタ言語の続きです。前回は外部のJSONファイルをTypeScriptで型付で読み込みました。今回はgulp-imageminなどをのパッケージを使って画像の圧縮設定もしてみます。それではいきましょう!
【目次】
- 前回のおさらい
- srcフォルダの中にも画像用のimgフォルダを作る
- 画像を圧縮する方法を調べる。
- gulp-imageminをインストール
- gulpfile.jsでパッケージをインポート
- 画像圧縮設定
- watch設定
- defaultのタスクにimageminを追加
- 動作確認
- 最後に
※参考:前回記事
【TypeScript】外部のJSONファイルを型付で読み込む - クモのようにコツコツと
※参考:【メタ言語】HTMLテンプレートエンジン、AltCSS、AltJSのまとめ
qiita.com
前回のおさらい
「unsei.ts」を「json」フォルダに移動し「unsei.json」にリネイム
このunsee.jsonをTypeScriptで型を付けて読み込んでwebpackでバンドルした。
詳細は前回記事を参照
※参考:【TypeScript】外部のJSONファイルを型付で読み込む - クモのようにコツコツと
srcフォルダの中にも画像用のimgフォルダを作る
これまでメタ言語のコンパイルを主軸にしていたため、画像は手付かずだった。
コンパイル前のメタ言語ファイルを入れている「src」フォルダには画像ファイルは含めていなかった。
画像ファイルはコンパイル後の「dest」フォルダの中の「img」フォルダに直接アップしていた。
しかしできれば「dest」フォルダの中は触りたくない。自動的に作られるコンパイル結果のみをおきたい。
とはいえ単にsrcフォルダの中にimgフォルダを作ってそれをdestフォルダにコピーするだけなのも芸がないな。。
画像を圧縮する方法を調べる。
そういえば、画像って圧縮するとさらにスリムになってページで読み込み速度が上がるんだよな(Webデザイナー時代はフォトショの保存設定でサイズを下げたりしてたが)。
下記の記事の実例のように画像をgulpで圧縮すると見た目はほどんど変わらずにサイズが下がっている!
※参考:【デザイナー向け】gulpでかんたん画像圧縮 - Qiita
webpackでも画像圧縮できる(jsファイルにバンドルせずにフォルダ構成を保持もできる!)
※参考:webpackで画像を圧縮する方法 | HPcode
また、gulpやwebpackを使わなくてもpackage.jsonのnpm scriptsに設定を書くだけでも画像圧縮できる!
※参考:npm scriptsで画像圧縮を自動化した際の課題と検討事項 - LCL Engineers' Blog
いろいろな方法を調べたが共通するのはimageminというパッケージを使っていることだ。どうやら画像圧縮の定番らしい。
今回は「gulp-imagemin」を使って画像圧縮したい。下記の記事の方法がわかりやすかったのでこちらを参考に進める。
※参考:Gulpでいろんなフォーマットの画像を一括で圧縮する | オウンドメディア | 大阪市天王寺区SOHOホームページ制作 | デザインサプライ-DesignSupply.-
gulp-imageminをインストール
まず画像圧縮に必要な3つのパッケージをインストールする。
$ npm install --save-dev gulp-imagemin $ npm install --save-dev imagemin-pngquant $ npm install --save-dev imagemin-mozjpeg
- gulp-imagemin:SVG(svgoプラグイン)とGIF(gifsicleプラグイン)の圧縮
- imagemin-pngquant:PNG圧縮
- imagemin-mozjpeg:JPG圧縮
SVGはsvgo、GIFはgifsicleというプラグインを使う。gulp-imagemin本体に含まれている。
PNGはimagemin-pngquant、JPGはimagemin-mozjpegはというプラグインを使う。これは本体と別でインストールする。
package.jsonを確認
"devDependencies": { "browser-sync": "^2.26.13", "gulp": "^4.0.2", "gulp-ejs": "^5.1.0", "gulp-imagemin": "^7.1.0", // 追記 "gulp-plumber": "^1.2.1", "gulp-rename": "^2.0.0", "gulp-replace": "^1.0.0", "gulp-sass": "^4.1.0", "gulp-typescript": "^6.0.0-alpha.1", "imagemin-mozjpeg": "^9.0.0", // 追記 "imagemin-pngquant": "^9.0.1", // 追記 "ts-loader": "^8.0.11", "webpack": "^5.4.0", "webpack-stream": "^6.1.1" },
3つのパッケージが追記されている!
gulpfile.jsでパッケージをインポート
gulpの設定ファイルgulpfile.jsでパッケージをインポートする。
const imagemin = require('gulp-imagemin'); const mozjpeg = require('imagemin-mozjpeg'); const pngquant = require('imagemin-pngquant');
- 変数
imagemin
でgulp-imagemin
をインポート - 変数
mozjpeg
で'imagemin-mozjpeg
をインポート - 変数
pngquant
でimagemin-pngquant
をインポート
画像圧縮設定
imagemin
という名前のgulp.tusk()
で画像圧縮の設定をする
// 画像圧縮 gulp.task('imagemin', (done) => { gulp.src('./src/img/**/*.{jpg,jpeg,png,gif,svg}') .pipe(imagemin( [ pngquant({ quality: '65-80', speed: 1 }), mozjpeg({ quality: 80 }), imagemin.svgo(), imagemin.gifsicle() ] )) .pipe(gulp.dest('./dest/img')); done(); });
gulp.task()
を実行(第一引数はimagemin
、第二引数は無名関数でその引数はdone
gulp.src()
を実行(引数はパスで「/src/img」フォルダのファイル、拡張子はjpg,jpeg,png,gif,svg
のいずれか- 一つ目の
pipe()
の引数でimagemin()
を実行(引数は配列でオプション設定 - オプション設定
pngquant
は品質65-80でスピード1、mozjpeg
の品質は80、imagemin
のsvgo
、gifsicle
も実行 - 二つ目の
pipe()
の引数でgulp.dest()
を実行。引数は保存先のパス「/dest/img」 - 最後に
done()
を実行
watch設定
watch-files
のgulp.task()
に画像フォルダの監視設定を追加する
// 監視ファイル gulp.task('watch-files', (done) => { gulp.watch(["./src/ejs/**/*.ejs", "./src/json/**/*.json"], gulp.task('ejs')); gulp.watch("./dest/*.html", gulp.task('browser-reload')); gulp.watch("./src/scss/**/*.scss", gulp.task('sass')); gulp.watch("./dest/css/*.css", gulp.task('browser-reload')); gulp.watch(["./src/ts/**/*.ts", "./src/json/**/*.json"], gulp.task('webpack')); gulp.watch("./dest/js/*.js", gulp.task('browser-reload')); gulp.watch("./src/img/**/*", gulp.task('imagemin')); // 追加 gulp.watch("./dest/img/*", gulp.task('browser-reload')); // 追加 done(); });
gulp.watch()
で「/src/img」フォルダを監視して、変更があったらimagemin
を実行gulp.watch()
で「/dest/img」フォルダを監視して、変更があったらbrowser-reload
を実行
これで画像フォルダに変更があったら画像圧縮が実行されてブラウザがリロードする。
defaultのタスクにimagemin
を追加
default
のgulp.task()
に画像圧縮のタスクを追加する
// タスク実行 gulp.task('default', gulp.series(gulp.parallel( 'watch-files', 'browser-sync', 'ejs', 'sass', 'webpack', 'imagemin' ), (done) => { done(); }));
gulp.parallel()
の引数の中にimagemin
を追加する
これでgulp起動時にもimagemin
を実行する。
動作確認
gulpを実行
$ npx gulp
localhostの3000でブラウザが立ち上がる。
destの/imgフォルダにも画像ファイルが入っている。
試しにファイル名を変えてみよう。destフォルダの方の画像はいったん削除して
ヘッダーの背景画像もリンク切れになる。
srcフォルダの画像のファイル名の拡張子を「.jpeg」から「.jpg」に変更
destフォルダにも「.jpg」の画像が保存される。
「_header.scss」の背景画像のパスも「.jpg」に変更
/* header */ .header { @include pageSize(); padding: 80px 10px; background-image: url(../img/header_bg.jpg); // 拡張子変更 background-size: cover; text-align: center; &__title { margin: 0; color: $text-color_w; text-shadow: 0 0 20px #000; } }
「style.css」の背景画像も「.jpg」でコンパイルされている。
.header { width: 100%; max-width: 1000px; padding: 0 20px; margin: 0 auto; padding: 80px 10px; background-image: url(../img/header_bg.jpg); background-size: cover; text-align: center; }
背景画像が再び表示された!
圧縮前:srcフォルダの画像(28KB)
圧縮後:destフォルダの画像(20KB)
わずかだがサイズが下がっている。圧縮が行われていることがわかった!
今回の修正内容(GitHub)
※参考:画像圧縮設定を追加 · ryo-i/frontendMetaLanguage@9f4bb86 · GitHub
プレビュー画面(GitHub Pages)
※参考:メタ言語同時コンパイル(EJS、Sass(SCSS)、TypeScript)
最後に
ということでメタ画像コンパイル時に同時に画像の圧縮も実行できました。また、これによってコンパイル後のdestフォルダは手付かずで画像ファイルについてもsrcフォルダ内の作業で完結することができるようになりました。
このメタ言語開発環境、あんなこと、こんなこと他にもいろいろなことをやりたくなってきます。
- gulpの修正時にNodeサーバを閉じなくていいいように監視したい(gulp-nodemon)
- DBと接続するAPI設定を作りたい(Express)
- Node環境の方もTypeScriptで型を付けて書きたい(gulpfile、Express共に)
ただ、やり始めるとキリがないし、何よりそろそろ具体的なアプリや作品を作りたいです。
当初やりたかったことは大方実現できたので、現時点でいったん最小構成のメタ言語セットを作って、そこに機能を足し算する形で進めていこうかな、とも考えています。
それではまた!
※参考:【メタ言語】HTMLテンプレートエンジン、AltCSS、AltJSのまとめ
qiita.com