HAM MEDIA MEMO

静的サイトジェネレータ「metalsmith」を gulp で使う

Node.js の child_process を利用する

gulp との組み合わせをどうしようかと、最初とても悩みました。

プラグインで gulpsmith というのもあるらしいのですが、なんだかパッとみて使いにくそう。

GitHub : pjeby/gulpsmith

ということで、Node.js の コマンドを実行してくれる child_process.spawn 機能を使って、そこで gulp と metalsmith を組み合わせようと思います。

Child Process Node.js Manual & Documentation

metalsmith の設定自体は、以前のエントリー同様に、 metalsmith.json で指定しておくとして、ここではあくまで毎回のコンパイル用のコマンドを動作させるようにするためのもの。

livereload も有効になるようにしてみます。

gulpfile.js

var gulp = require('gulp');
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var cp = require('child_process');

gulp.task('metalsmith', function () {
  cp.spawn('node', ['node_modules/.bin/metalsmith'])
    .on('close', reload);
});

gulp.task('server', function () {
  browserSync({
    notify: false,
    server: {
      baseDir: "html"
    }
  });

  gulp.watch('_source/**/*.html', ['metalsmith']);
});

これも以前書いたのですが、『gulp の BrowserSync で watch を利用した際のちょっとした記述ミスで、大量のタブが開く問題発生』 この時は reload[] 付きで指定したら問題が起きたのですが、今回は作成したタスクを叩くこともあって、 [] がないと怒られます。

上記のように gulpfile.js を用意して $ gulp server をたたけば、 _source 配下の HTML を保存するたびに html フォルダに書き出ししてくれるようになります。(設定は先日の metalsmith のエントリーを参考に)

BrowserSync の reload のタイミング

reload をさせるタイミングが違うと、どうも書き出し前の状態で reload が走ってしまうために、表示がうまくいかない時がある。

例えば下記のように watch で reload も指定してしまうと、表示は書き出し前のが表示されてしまう。

gulp.watch('_source/**/*.html', ['metalsmith', reload]);

そのため、metalsmith のタスクの際に、 close のイベントに合わせて reload が動くようにしてみています。

確実に書き出し後のが表示されているのか、大きいファイルや大量のファイルがある状態では未確認ですが、ファイル数が少ない時などでは上記のような設定で問題なく、保存後かつ書き出し後の状態でリロードしてくれました。