5.x.x-4.3.1
系から6.0.0-4.3.1
に上げました。
変更点については以下を参照。
トピックはいくつかありますが、大きな変更点としてはGulpタスクの文法を変えたことです。
その際に躓いた点、また検索はしたもののあまり情報がヒットせずもやもやした点をまとめたいと思います。
目次
- 前置き
- 本題
- 関数式の記述が可能か
exports
したタスクをどのようにインポートし、実行するか- フラグによってタスクを増減させたい
- 複数のタスクが1ファイルにある場合、どう
exports
するか
前置き
過去の話になりますが、一応Gulpのバージョンを長らく使われていた3.9.1
から4.x
系に移行したのが、Ususamaでは3.7.0-4.1.3
になります。
このときは今から思えばとりあえず4.x系にアップデートしただけという感じで、
package.json
でのバージョン指定はnext
という表記方法- まだ
gulpfile.js
1つに全てのタスクを記載 - タスクの定義は
gulp.task()
構文のまま
3.11.0-4.1.3
でした。
ただし、このときもまだタスクの定義はgulp.task()
構文のままでした。
本題
しかし、Gulp4.x系は上述のgulp.task()
構文は
This API isn’t the recommended pattern anymore task() ・ gulp.jsということで、推奨されなくなりました。代わりに、関数宣言と
exports
が推奨となりました。独自構文からECMAScriptに寄った形になったのだと思います。
/* 今まで */
gulp.task('TASKNAME', function() {
//処理
});
//アロー関数
gulp.task('TASKNAME', () => {
//処理
});
/* 4.x系 */
function TASKNAME() { //関数宣言した時点では`gulp`コマンドで実行不可能
//処理
});
exports.TASKNAME = TASKNAME;
以下、node.jsのバージョンは10.16.3
、Gulpは4.0.2
の環境で確認しました。
1. 関数式の記述が可能か
ここでまず気になったのは、「関数宣言ではなく関数式は使えるのか?」ということ。//関数式でも可
const TASKNAME = () => {
//処理
});
exports.TASKNAME = TASKNAME;
試してみたところできました。
2. exports
したタスクをどのようにインポートし、実行するか
1.でexports
はできました。次は、これをどうやってインポートするか。
task1.js
//exports
const TASKNAME = () => {
//処理
});
exports.TASKNAME = TASKNAME;
gulpfile.js
const TASK1 = require('./task1'); //`require`でインポート
exports.TASK1 = gulp.series(TASK1); //`gulp TASK1`で実行可能
require
でJSファイルを読み込んで、exports
に渡す、と。受け取り側はrequire
ですが、ECMAScriptの標準的な構文に近い形で行けました。
3. フラグによってタスクを増減させたい
Ususamaでは、YAMLファイルの設定を読み込んでタスクを変化させたいものがいくつかありました。 例えば、「dist/
下にあるHTMLファイルを探索して、人間用のサイトマップを生成する」というのもその一つです。フラグがtrue
ならばサイトマップ生成をタスクに込め、false
ならばサイトマップは生成しない、という具合です。
//タスクを読み込み
const ejs = require('./gulp/tasks/ejs');
const imagemin = require('./gulp/tasks/imagemin');
const js = require('./gulp/tasks/js');
const scss = require('./gulp/tasks/scss');
const sitemap = require('./gulp/plugins/sitemap');
//タスクの配列
let taskArray = [scss, js, imagemin];
//ejsだけ別個に宣言
let taskEjs = [ejs];
if(plugins.sitemap) { //`plugins`オブジェクトの中の`sitemap`をチェック
taskEjs.push(sitemap); //`true`ならばサイトマップ生成のタスクを`taskEjs`に追加
}
//`taskArray`の中身は並列
//ただしサイトマップ生成は`dist/`下のHTMLファイルを見るため、EJSコンパイルが完了してからにしたい
//そのため、`taskEjs`は`series`にする
const taskBuild = gulp.parallel(taskArray, gulp.series(taskEjs));
exports.build = taskBuild;
イメージとしてはこのような形。
gulpfile.js
に関してはこれで良かったのですが、一点元のタスクファイル側で変更が必要でした。
const TASKNAME = () => {
//処理
});
module.exports = TASKNAME; //左辺を`exports.TASKNAME`から`module.exports`に変更
左辺がexports.TASKNAME
だと[Object Object]
になってしまって上手く動かなかったので、module.exports
に変更しました。
この形式ならば、上述のタスク(というより関数)の配列をそのままseries
やparallel
に突っ込んで動かすことができました。
series
やparallel
に突っ込むのがただの「JavaScriptの関数の配列」ならば、配列操作のpush
やunshift
等が使えるだろう、と推測できたので試してみたとこと、思った通り実現できた、という次第です。
4. 複数のタスクが1ファイルにある場合、どうexports
するか
今度は、複数のタスクが1ファイルに宣言されているケースについて。
例えば、JavaScriptでconcat
の後にuglify
する、としています。
//js圧縮&結合&リネーム
const jsConcat = () => {
return gulp.src(['PATH/TO/JSLIBRARY1', 'PATH/TO/JSLIBRARY2'])
.pipe(_.concat('lib.js'))
.pipe(gulp.dest(`${PATH/TO/SRC/JS}/concat/`));
};
const jsBuild = () => {
return gulp.src('PATH/TO/SRC/JS/*.js')
.pipe(_.uglify({output: {comments: 'some'}}))
.pipe(_.rename((path) => {
path.dirname = 'PATH/TO/DIST/JS/'
path.basename += '.min'
path.extname = '.js'
}))
.pipe(gulp.dest('./'));
};
module.exports = gulp.series(jsConcat, jsBuild);
4.x
系で導入されたseries
やparallel
を使えば、タスクを塊にしてexports
はできます。が、それぞれのタスクを単体で実行したい場合はどうするか。
js.js
//js圧縮&結合&リネーム
const js = {
jsConcat: () => {
return gulp.src(['PATH/TO/JSLIBRARY1', 'PATH/TO/JSLIBRARY2'])
.pipe(_.concat('lib.js'))
.pipe(gulp.dest(`${PATH/TO/SRC/JS}/concat/`));
},
jsBuild: () => {
return gulp.src('PATH/TO/SRC/JS/*.js')
.pipe(_.uglify({output: {comments: 'some'}}))
.pipe(_.rename((path) => {
path.dirname = 'PATH/TO/DIST/JS/'
path.basename += '.min'
path.extname = '.js'
}))
.pipe(gulp.dest('./'));
}
};
module.exports = js;
gulpfile.js
const jsTask = require('./js');
const js = gulp.series(jsTask.jsConcat, jsTask.jsBuild);
exports.jsconcat = gulp.series(jsTask.jsConcat); //`gulp jsconcat`でconcatだけ走る
exports.jsbuild = gulp.series(jsTask.jsBuild); //`gulp jsbuild`でjsbuildだけ走る
exports.js = js; //concat→jsbuildの順番で走る
モジュールでexports
できるならば、この書き方でできるはず。実際できました。
以上4点、私のケースでは対処できたサンプルのまとめでした。
参考
全般
- task() ・ gulp.js
- Gulp4の変更点と新しい書き方 – Qiita
- Gulp4がリリースされたのでgulpfile.jsをアップデートした – Qiita
- gulp4に移行するためにタスクを書き換えてみた | 福岡のホームページ制作会社・メディア総研株式会社 マグネッツ事業部