`.ejs` ファイルだけ `gulp.watch` で `change` イベントが2回発火する現象のメモ

引き続き Gulp ネタです。表題の通り、 .ejs ファイルだけ gulp.watchchange イベントが2回発火する現象に遭遇しました。

例えば、 ./src/ejs/index.ejs を編集すると以下のような実行ログになりました。

File src\ejs\index.ejs was changed.
Stats {
  dev: 3292776302,
  mode: 33206,
  nlink: 1,
  uid: 0,
  gid: 0,
  rdev: 0,
  blksize: 4096,
  ino: 6473924464987415,
  size: 0,
  blocks: 0,
  atimeMs: 1596206608814.928,
  mtimeMs: 1596206608814.928,
  ctimeMs: 1596206608814.928,
  birthtimeMs: 1594219203454.367,
  atime: YYYY-mm-ddThh:ii:ss.xxxZ,
  mtime: YYYY-mm-ddThh:ii:ss.xxxZ,
  ctime: YYYY-mm-ddThh:ii:ss.xxxZ,
  birthtime: YYYY-mm-ddThh:ii:ss.xxxZ
}
[23:43:28] Starting 'commonsEjs'...
[23:43:28] Starting 'indexEjs'...
[23:43:28] Starting 'newsEjs'...
[23:43:28] Finished 'newsEjs' after 47 ms
File src\ejs\index.ejs was changed.
Stats {
  dev: 3292776302,
  mode: 33206,
  nlink: 1,
  uid: 0,
  gid: 0,
  rdev: 0,
  blksize: 4096,
  ino: 6473924464987415,
  size: 2611,
  blocks: 8,
  atimeMs: 1596206608815.935,
  mtimeMs: 1596206608815.935,
  ctimeMs: 1596206608815.935,
  birthtimeMs: 1594219203454.367,
  atime: YYYY-mm-ddThh:ii:ss.xxxZ,
  mtime: YYYY-mm-ddThh:ii:ss.xxxZ,
  ctime: YYYY-mm-ddThh:ii:ss.xxxZ,
  birthtime: YYYY-mm-ddThh:ii:ss.xxxZ
}
[23:43:28] Starting 'commonsEjs'...
[23:43:28] Starting 'indexEjs'...
[23:43:28] Starting 'newsEjs'...
[23:43:29] Finished 'newsEjs' after 46 ms
[23:43:29] Finished 'indexEjs' after 593 ms
[23:43:29] Finished 'indexEjs' after 467 ms
[23:43:29] Finished 'commonsEjs' after 632 ms
[23:43:29] Starting 'sitemapxml'...
[23:43:29] Finished 'sitemapxml' after 51 ms
[23:43:29] Starting 'sitemap'...
[23:43:29] Finished 'commonsEjs' after 930 ms
[23:43:29] Starting 'sitemapxml'...
[23:43:29] Finished 'sitemapxml' after 74 ms
[23:43:29] Starting 'sitemap'...
[23:43:29] Finished 'sitemap' after 124 ms
[23:43:29] Starting '<anonymous>'...
[23:43:29] Finished 'sitemap' after 298 ms
[23:43:29] Starting '<anonymous>'...
[Browsersync] Reloading Browsers...

途中に fs.stats の情報等が流れているのは以下のように一時的に console.log を出力するようにしたためです。

const gulp        = require('gulp');
const watch       = require('gulp-watch');
const browserSync = require('browser-sync');
const ejs         = require('./ejs');

const taskEjs = [ejs];

const browsersync = () => {
    const sEjs = _.gulp.series(taskEjs, browserSync.reload);
    //一時的に console.log で出力
    const sEjsC = (path, stats) => { console.log(`File ${path} was changed.`); console.log(stats); sEjs(); };
    gulp.watch(
        './src/ejs/**/*.ejs'
    )
        .on('add',    sEjs)
        .on('change', sEjsC)
        .on('unlink', sEjs);
};

.js.scss 等では発生しないので少し調査。

気になったのは fs.stats のパラメータのうち、 size が1回目は0バイト、2回目は2611バイトで実容量となっている点。

change と言いつつ、一度削除らしき挙動をしてから上書き保存しているような感じなのでしょうか。

検索してみたところ、古い(2014年) issues ですがまさにそのようなことが書いてある chokidar の issues がありました。

fixed はされているようですが、現象はこれっぽいのですよね…… Windows ですし。

もうちょっと時間のあるときに気が向いたら調べたいと思います。今はひとまず現象とそれらしきもののリンクをメモしておくということで。

参考

この記事を書いた人

アルム=バンド

フロントエンド・バックエンド・サーバエンジニア。LAMPやNodeからWP、Gulpを使ってejs,Scss,JSのコーディングまで一通り。たまにRasPiで遊んだり、趣味で開発したり。