LoginSignup
6
4

More than 5 years have passed since last update.

run-sequenceでgulp-eslintを実行した時にエラーでもタスクを続行する方法

Last updated at Posted at 2016-10-11

Gulpでタスクの直列/並列処理をする場合にお世話になるrun-sequence

Browserifyタスクを実行する直前にESLintを実行したいな〜、と思ってタスクを書いたんですが、上手く動きませんでした。
ESLint実行時にLintに引っかかってしまった場合、エラーが出てその場でrun-sequenceのタスクが終了してしまいます(本来は正しいのかも知れないけど)。

うまく動かない書き方

pathは各種ファイルのパスをまとめて書いているJSです。

esLint.js
import gulp from 'gulp';
import path from '../path';
import plumber from 'gulp-plumber';
import esLint from 'gulp-eslint';

gulp.task('esLint', () => {
  return gulp
    .src([
      path.source.javascripts + '**/*.{js,jsx,vue}',
      '!' + path.source.javascripts + 'lib/**/*'
    ])
    .pipe(plumber())
    .pipe(esLint({
      useEslintrc: true
    }))
    .pipe(esLint.format())
    .pipe(esLint.failAfterError());
});
default.js
import gulp from 'gulp';
import runSequence from 'run-sequence';

gulp.task('default', () => {
  runSequence('esLint', 'browserify', 'watch');
});

エラーが出てもタスクを続行できるgulp-plumberを使ってるのに、なんでか止まっちゃう。

参考になった記事

gulp-sass, gulp-plumberを使うときの注意 - Qiita

まさにこれで、解決しました。ありがとうございます。

うまく動く書き方

esLint.js
import gulp from 'gulp';
import path from '../path';
import plumber from 'gulp-plumber';
import esLint from 'gulp-eslint';

gulp.task('esLint', () => {
  return gulp
    .src([
      path.source.javascripts + '**/*.{js,jsx,vue}',
      '!' + path.source.javascripts + 'lib/**/*'
    ])
    .pipe(plumber({
      errorHandler(err) {
        console.log(err.message);
        this.emit('end');
      }
    }))
    .pipe(esLint({
      useEslintrc: true
    }))
    .pipe(esLint.format())
    .pipe(esLint.failAfterError());
});

default.jsは上と同じ。
これで、esLintでエラーが出ても、run-sequenceが最後まで動くようになりました。

余談: this.emit()thisについて

ここのthis.emit()thisなんですが、その外側のerrorHandler関数の書き方がちょっと変わっている。
plumber関数の引数にオブジェクトが入っており、そこでerrorHandler関数を定義しています。
ES2015の関数の書き方だと、パッと見、以下のようになりそうな気がしませんか。

plumber({
  errorHandler: (err) => {
    this.emit('end');
  }
});

でも、これだとthisundefinedになってしまうんですよね。正解は以下です。

plumber({
  errorHandler(err) {
    this.emit('end');
  }
});

こう書くことで、thisがちゃんとこのオブジェクト(pipeに入っているTransformオブジェクト)を指すようになります。

まとめ

無事にESLintできるようになって良かったです。
とはいえ、エラーが出てもそのままタスクを続行できるのは、開発時はいいけど、本番用にファイルをビルドするときはダメですよね。
なので、その場合は環境変数などで条件分岐して、デフォルト通りエラーが出たらタスクを途中で終了するようにすればいいと思います。

Browserify/WatchifyでJSをコンパイルする時に、関数の中でESLintを動かしていたんですが、タスクを切り出したことで、汎用性が高くなったので良かったです。

6
4
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
6
4