88
98

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Gulp4の変更点と新しい書き方

Last updated at Posted at 2019-07-18

gulpjs公式ブログでもアナウンスされたように、2018年12月にGulp4が正式にリリースされました。Gulp4未満は数ヶ月後から非推奨になるようです。

「Gulp4」で検索すると、それぞれが違う書き方をしていました。この記事ではgulp.jsの公式ドキュメントを参考に、Gulp3からGulp4に移行するための情報をまとめています。

  • gulp.task()が非推奨になり、関数宣言とexportsが推奨になった
  • run-sequenceを使った直列・並列処理を、公式APIのseries()parallel()で実行できるようになった
  • gulp.watch()の第二引数が配列から関数名になった
  • 公式APIにsourcemapsオプションが追加された
  • 公式APIのgulp.lastRun()で差分ビルドができるようになった

gulp.task()が非推奨になり、関数宣言とexportsが推奨になった

Creating Tasksにあるように、関数宣言(function タスク名(){})でプライベートタスクを作成、exportsでパブリックタスクにする書き方へ変わりました。

// 非推奨
gulp.task('task', function() {
  ...
});
gulp.task('task', () => {
  ...
});
// 推奨
function task() { // この時点では`gulp`コマンドで実行不可能
  ...
}
exports.task = task; // `gulp task`で実行可能

Async Completionにあるように、returnを返さない処理の場合はコールバック関数で完了を知らせる必要があります。

基本的なタスクはreturn gulpから始めれば大丈夫です。

// OK
function task() {
  return
    gulp
      .src('')
      .pipe()
      .pipe(
        gulp.dest()
      )
  );
}

browser-syncではreturnを使っていないので、done()というコールバック関数を実行するようにしました(公式ではcb()となっています)。

// OK
function serve(done) {
  browserSync({
    server: {
      baseDir: '',
    },
    ghostMode: false,
    open: 'external',
    notify: false,
  });
  done();
}

run-sequenceを使った直列・並列処理を、公式APIのseries()parallel()で実行できるようになった

直列・並列処理はrun-sequenceをインストールしていましたが、直列をseries()で、並列をparallel()で実行できるようになりました。

// run-sequenceを使った場合
const runSequence = require('run-sequence');
gulp.task('default', function() {
  runSequence(
    ['pug', 'sass', 'js'],
    'server'
    );
});
// `series()`と`parallel()`を使った場合
exports.default = gulp.series(
  gulp.parallel(pug, sass, js),
  server,
);

gulp.watch()の第二引数が配列から関数名になった

Gulp3では、gulp.watch()の第二引数に配列でタスク名を渡していましたが、Gulp4ではタスクの関数を渡すようになりました。

// Gulp3
gulp.watch([''], ['task']);
// Gulp4
gulp.watch('', task);

gulp.seriesfunction()を渡すこともできます。

gulp.watch('', gulp.series(task));
gulp.watch('', gulp.parallel(task));
gulp.watch('', function(done) {
  done();
});

公式APIにsourcemapsオプションが追加された

sourcemapsはgulp-sourcemapsをインストールしていましたが、gulp.src()gulp.dest()optionssourcemapsが追加されました。

// Gulp3
const sourcemaps = require('gulp-sourcemaps');
gulp.task('task', function() {
  gulp.src('')
    .pipe(sourcemaps.init())
    .pipe(sourcemaps.write())
    .pipe(gulp.dest(''));
});
// Gulp4
function task() {
  return gulp
    .src('', {
      sourcemaps: true, // init
    })
    .pipe(dest('',{
      sourcemaps: true, // write
    }));
}

gulp.dest()sourcemaps: trueにするとインラインで、パスを渡すと別ファイルで出力されます。たとえばdestsourcemaps: '.'にすると同階層に出力されます。

公式APIのgulp.lastRun()で差分ビルドができるようになった

差分ビルドにはgulp-changedなどをインストールしていましたが、gulp.src()sinceオプションにgulp.lastRun()を渡して実行できるようになりました。

// gulp-changedの場合
const changed = require('gulp-changed');
gulp.task('image', function() {
  return gulp
    .src(src.img)
    .pipe(changed(dest.img)) // `gulp.dest()`のパスを渡す
    .pipe(imagemin())
    .pipe(gulp.dest(dest.img));
);
// `gulp.lastRun()`の場合
function image() {
  return gulp
    .src(src.img, {
      since: lastRun(image) // タスク名を渡す
    })
    .pipe(imagemin())
    .pipe(dest(dest.img));
}

試したときは若干不安定に感じたので、まだ導入はしていません。

名前の衝突に気をつける

書き方が変わって名前の衝突が起こりやすくなっています。

実際にあったのが、browser-syncでの名前の衝突。

// NG
const browserSync = require('browser-sync');
function browserSync(done) { // const browserSyncと衝突している
  browserSync({
    server: {
      baseDir: '',
    },
    ghostMode: false,
    open: 'external',
    notify: false,
  });
  done();
}

browserSyncが衝突していてエラーになりました。

function browserSync(done) {
^

SyntaxError: Identifier 'browserSync' has already been declared

ここではserveというタスク名にすることで回避しました。

// OK
const browserSync = require('browser-sync');
function serve(done) {
  browserSync({
    server: {
      baseDir: '',
    },
    ghostMode: false,
    open: 'external',
    notify: false,
  });
  done();
}

公式ドキュメントで以下のように名前付きインポートをしている箇所があります。

const { src, dest, lastRun, watch } = require('gulp');

const gulp = require('gulp');だとgulp.src()のようにしますが、名前付きインポートを使うとsrc()のようにできます。

ただ、srcdestはパスを変数化するときに使ったり、watchはタスク名に使っていることも多いです。名前付きインポートは使わない方がベターなのかなと思いました。

Gulp4に移行したgulpfile.jsは以下のリンクを参考にしてください。

88
98
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
88
98

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?