🐶

Pugでimgタグにwidth, height属性を自動で付加する方法

2021/09/15に公開

普段HTMLはPugで書いています。
<img>タグにwidth, height属性を付けるとレイアウトシフトを防げます[1]が、Pugで全部の<img>タグに付けるのは大変なので、自動化をしています。

Pugをコンパイルするためのgulp-pugに加え、
https://github.com/gulp-community/gulp-pug
gulp-dataでNode.jsからPugファイル内にデータを渡せるようにします。
https://github.com/colynb/gulp-data
関数を渡すこともできるので、image-sizeを使って画像ファイルのサイズを取得する関数を定義して渡します。
https://github.com/image-size/image-size

以下のようなGulpタスクを定義し、

gulpfile.js
const path = require('path');
const { src, dest } = require('gulp');
const gulpPug = require('gulp-pug');
const gulpData = require('gulp-data');
const imageSize = require('image-size');

const sourcePath = path.resolve(__dirname, 'src');

exports.default = function () {
  return src(path.resolve(sourcePath, '**/*.pug'))
    .pipe(
      gulpData((file) => {
        // file: 処理中のPugファイルに関する情報
        // file.dirname: 処理中のPugファイルのあるディレクトリパス
        return {
          // imageSizeという名前の関数をPug内で使えるようにする
          imageSize: (src) => {
            // imgタグのsrc属性のパスを基にファイルパスを生成する
            const filePath = src.startsWith('/')
              ? path.resolve(sourcePath, src.slice(1)) // /から始まるルート相対パスの場合
              : path.resolve(file.dirname, src); // 相対パスの場合
            // ファイルパスに該当する画像のサイズをimage-sizeで取得する
            return imageSize(filePath);
          },
        };
      })
    )
    .pipe(gulpPug())
    .pipe(dest(path.resolve(__dirname, 'public')));
};

以下のようなPug mixinを定義して、通常の<img>タグに指定するsrc属性の値だけを引数に指定すると、

mixin img(src, alt = '')
  - const { width, height } = imageSize(src); // gulp-dataで定義したimageSize関数
  img(src=src, alt=alt, width=width, height=height)

//- 相対パス
+img('./images/150x150.png')
//- /から始まるルート相対パス
+img('/images/300x200.png')


以下のようにwidth, height属性の値が画像ファイルのサイズと同じ数値で出力されます。

<img src="./images/150x150.png" alt="" width="150" height="150"/>
<img src="/images/300x200.png" alt="" width="300" height="200"/>

実際に動作する環境のリポジトリ

これで、いちいち画像サイズを調べて手動で入力しなくても、Pugコンパイル時に全部の<img>タグにwidth, height属性を自動で付加することができます。


gulp-dataはEJSでも使えるらしいので、EJSでも同様にできるかもしれません。


参考:レイアウトシフトについて

https://parashuto.com/rriver/development/img-size-attributes-are-back
https://www.mizdra.net/entry/2020/05/31/192613

脚注
  1. 参考:レイアウトシフトについて参照 ↩︎

Discussion