[gulp4] gulpfileのつまずきアレコレ


初めてgulpfileを書きました。
ググると色々紹介記事が出てきましたが、いろんな書き方があり迷走したので、つまずいたこと、この先またつまずきそうなことのメモです。

前置き

  • gulp4使ってます
  • 見出しは、「[関連パッケージ・API]見出し」の形式で書いてます

[gulp-ejs] 拡張子が変わらないままエクスポートされる

▶︎ gulp-renameが別途必要!

gulp4からは、gulp-ejsの引数extに拡張子を渡す方法がなくなったらしいです。
参考にしたサイトがgulp3系を使っていた場合、注意です。

gulpfile
const gulp = require('gulp'); //gulp
const rename = require('gulp-rename'); //名前変更

//NGパターン
function htmlFunc() {
  return gulp
    .src('ejsファイルのパス')
    .pipe(ejs({}, {}, {ext: '.html'})) 
    .pipe(gulp.dest('出力先のパス'));
}

//OKパターン
function htmlFunc() {
  return gulp
    .src('ejsファイルのパス')
    .pipe(ejs())
    .pipe(rename({extname:'.html'})) 
    .pipe(gulp.dest('出力先のパス'));
}

参考サイト:gulp:「gulp-ejs」Ver 4.0.0でファイル出力時の拡張子を変更する方法

[autoprefixer] gridレイアウトにプレフィックスがつかない

▶︎ コードの記載が足りないかも?

gridレイアウトにプレフィックスを自動でつけるには、追加の記載が必要のようです。
flexレイアウト、@support へのプレフィックスは、デフォルトでonになっています。

gulpfile.js
const postcss = require('gulp-postcss'); //autoprefixerを使うのに必要
const autoprefixer = require('autoprefixer'); //prefixをつける

function stylesFunc() {
  return gulp
    .src('scssファイルのパス')
    .pipe(sass().on('error', sass.logError))
    .pipe(postcss([ autoprefixer({
      grid: 'autoplace', //gridレイアウトのプレフィックスを有効にする
    }) ]))
    .pipe(gulp.dest('出力先のパス');
}

参考サイト:npm autoprefixer

[browser-sync] ブラウザが自動更新されない

▶︎ <body>をちゃんとhtmlファイルに書く!

ちゃんとbodyタグを書かないと、自動でブラウザ更新してくれないようです。
「まだ作り途中だから...」と、端折ってはいけないのですね...。

参考サイト:【Gulp】browser-syncのLiveReloadが動かないときの直し方

▶︎ こっちもありかも?リロード用関数を独立させる

全く同じ症状で質問しているstackOverflowのスレッドに、「リロード用の関数は別で作らないとダメみたい」というコメントがついていました。bodyタグあるのに更新されない時は、これを試すのも良さそう。

There was an issue with my watch function and it seems necessary to have reloading done in a separate function.
引用元: Page not reloading/autoinjecting with Gulp 4 and Browsersync

[watch] 監視下のファイルを削除したら、エクスポート先の同ファイルも消したい

▶︎ .on(eventName, eventHandler)の形式で書く

公式ドキュメントのwatchのusageに載ってるこの形式.watch(globs, [options], [task]) で書いてたけども、コールバック内でeventやpathが取れずにかなり迷走しました...。(もしかしたら、私の書き方がどこか違うだけなのかも?)

よーく見たら、同じページにやり方書いてあった!
gulp #chokidar-instance

下の例ではこういうことをしています。

  • 監視下のファイルに変更またはファイル/フォルダ追加があった場合 → 関数A実行(①)
  • 監視下のファイルが削除された場合 → パスの文字列を出力先に置換(②)
gulpfile.js
const gulp = require('gulp'); //gulp
const del = require('del'); //フォルダやファイルを削除

//NGパターン
//①はうまくいくけど②は ``TypeError: Cannot read property 'replace' of undefined``とエラー
gulp.watch('ファイル取得元のパス', {events: ['change', 'add']}, gulp.series(関数A)); //①
gulp.watch('出力先のパス', {events: 'unlink'},(event, path) => {
  return del(path.replace(/src\/views/, '出力先のパス')); //②
});

//OKパターン
gulp.watch('ファイル取得元のパス')
  .on('all', (event, path) => {
    if (event === 'unlink') {
      return del(path.replace(/src\/views/, '出力先のパス'); //②
    }
    return 関数A; //①
});

参考サイト:gulp #chokidar-instance

指定できるイベントの種類は以下の通り。便利!
add / addDir / change / unlink / unlinkDir / ready / error / all

終わりに

公式ドキュメントって大事...!
参考にさせていただいた記事の執筆者さま、ありがとうございました。

「間違いがあるよ!」「こっちの書き方がいいよ!」など、お気付きの点がありましたらご指摘いただけると嬉しいです...!