Gulp のプラグインを自分で作ってみます。 gulp
のレポジトリにドキュメントがあるのでそれを読むのがいいですが、メモとして書き残しておきます。
用意
プラグインの中で使う gulp-util
と through2
をインストールしておきます。 gulp
は動作確認用です。
$ npm install -g gulp
$ npm install -D gulp-util through2
何もしないプラグイン
簡単な例として「何もしない」をするプラグインを書きます。
// a.js
const through = require('through2');
module.exports = () => through.obj((file, encoding, callback) => {
callback(null, file);
});
これがプラグインの本体です。
Gulp は vinyl という仮想ファイルを扱うライブラリと、 Node.js の stream を利用してファイルを扱っています。
例では through2
の obj
という関数でオブジェクトを扱う stream を作っています。 file
には vinyl のファイルオブジェクトがわたってきます。普通はこれを何かしら変換するのですが、とりあえず何もしていません。次のプラグインにファイルを渡すため callback
にそのまま file
をわたします。 callback
の第一引数はエラーがあったときにはエラーオブジェクトをわたします。
これを使う gulpfile.js
が以下です。
// gulpfile.js
const gulp = require('gulp');
const a = require('./a');
gulp.task('default', () =>
gulp.src(['*.txt'])
.pipe(a())
.pipe(gulp.dest('out')));
a
を require
して pipe
を使ってつなげています。
a
はなにもしないので、実行すると .txt
ファイルが out
にそのままコピーされます。
$ echo X > x.txt
$ gulp
$ ls out
x.txt
テキストを JavaScript に変換する
これだけでは意味が無いので、もっと益のあるプラグインを書いてみます。
.txt
なファイルを Node.js から require
で読み込める .js
ファイルに変換するプラグインです。
// a.js
const gutil = require('gulp-util');
const through = require('through2');
module.exports = () => through.obj((file, encoding, callback) => {
if (file.isNull()) {
callback(null, file);
return;
}
if (file.isStream()) {
callback(new gutil.PluginError('a', 'Streams not supported'));
return;
}
if (file.isBuffer()) {
const text = file.contents.toString('utf8');
const script = `module.exports = ${JSON.stringify(text)};\n`;
callback(null, new gutil.File({
base: file.base,
cwd: file.cwd,
path: gutil.replaceExtension(file.path, '.js'),
contents: new Buffer(script, 'utf8')
}));
return;
}
});
file.isNull()
はファイルの中身がないときに true
になります。 gulp.src
に { read: false }
というオプションをわたした時に目にします。ファイル名だけわかればいい場合はこれを使います。
file.isStream()
は何かしらのプラグインがファイルの中身を stream にして次にわたしたとき true
になります。今回はサポートしないで例外を callback
の第一引数にわたします。 gulp-util
の PluginError
は Gulp プラグインが投げるエラーです。第一引数にプラグインの名前を、第二引数にメッセージをわたします。
file.isBuffer()
はファイルの中身が Buffer
としてわたってきた場合 true
になります。今回はこれを変換して次に渡すことにします。
file.contents
に Buffer
が入っているので toString('utf8')
で文字列にします。 これを JSON.stringify
を利用しつつ module.exports = ...
の Node.js で使えるモジュールの形にしています。
gulp-util
の File
はそのまま vinyl
の File
です。新しいファイルを作って callback
にわたします。 base
cwd
はそのまま、 path
は gulp-util
の replaceExtension
を使って買う調子を .js
に変換しています。 contents
にはファイルの中身をわたします。この場合変換後の JavaScript を Buffer
にして使っています。
これでテキストを Node.js から使えるモジュールに変換するプラグインができました。先ほどと同じ gulpfile.js
を使ってコマンドを実行すると期待した変更をします。
$ gulp
$ ls out
x.js
$ cat out/x.js
module.exports = "X\n"
さいごに
through2
を使って簡単なプラグインを作りました。Gulp は stream や vinyl というしくみに乗っかっているので npm モジュールも活用しやすいです。
広く便利なものができればテストなんかも書いて npm
に公開するのもいいと思います。プロジェクト固有のプラグインも相対パスで require
するだけなので気軽に作ることができます。