🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
gulp

gulpは、Node.jsをベースとしたタスク自動化ツールの一つ。ストリームでファイルを処理することが特徴です。CSSプリプロセッサの使用時のコンパイルや、CSS・JavaScriptファイルの圧縮・結合などを自動的に行うことができます。

Q&A

解決済

2回答

6162閲覧

Gulpでエラー発生時にwatchを継続したい

notable

総合スコア415

gulp

gulpは、Node.jsをベースとしたタスク自動化ツールの一つ。ストリームでファイルを処理することが特徴です。CSSプリプロセッサの使用時のコンパイルや、CSS・JavaScriptファイルの圧縮・結合などを自動的に行うことができます。

0グッド

3クリップ

投稿2015/10/07 09:57

編集2015/10/07 09:59

Gulpでbrowserifyやbabelifyなどを使ってReactのソースをビルドしているんですが、
対象のJavaScriptファイルに単純な構文エラー(カッコが足りない、JSXの構文ミスなど)が発生すると
gulp.watchが止まってしまいます。

gulp-plumberを使うと継続できる、とか、
.on('error', function(){})でハンドリングできる、など
いくつか対策を見つけたのですが、watchが止まる状況は変わりませんでした。

Gulpの知識が無いので、記述が良くなくて効果が無いだけなのかもしれないのですが、
Gulp+Browserify+babelify+uglify+Reactな環境でエラー発生後もwatchが継続できるように
gulpfile.jsを記述したいです。

gulpfile.js

JavaScript

1gulp.task('build', function() { 2 return gulp.src('src/js/*.js') 3 .pipe(plumber()) 4 .pipe(through2.obj(function(file, encode, callback){ 5 browserify(file.path) 6 .transform(babelify) 7 .bundle(function(err, res){ 8 file.contents = res; 9 callback(null, file) 10 }) 11 .on('error', console.log('error')) 12 })) 13 .pipe(uglify({preserveComments: 'some'})) 14 .pipe(gulp.dest('./build/js/')); 15});

JSON

1 "devDependencies": { 2 "babelify": "^6.3.0", 3 "browser-sync": "^2.9.6", 4 "browserify": "^11.2.0", 5 "del": "^2.0.2", 6 "gulp": "^3.9.0", 7 "gulp-plumber": "^1.0.1", 8 "gulp-uglify": "^1.4.1", 9 "gulp-watchify": "^0.5.0", 10 "react": "^0.13.3", 11 "run-sequence": "^1.1.4", 12 "through2": "^2.0.0", 13 "vinyl-buffer": "^1.0.0", 14 "vinyl-source-stream": "^1.1.0", 15 "vinyl-transform": "^1.0.0" 16 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

修正すべき箇所は2点です。

  • 発生した例外errを適切にcallbackに渡してください。
  • errorイベントを追加する場所を、bundle後から、uglify直前にしてください。

以下のようなgulpfile.babel.jsで、監視が継続することをできます。

gulpfile.babel.js

javascript

1import gulp from 'gulp' 2import plumber from 'gulp-plumber' 3import through2 from 'through2' 4import browserify from 'browserify' 5import babelify from 'babelify' 6import uglify from 'gulp-uglify' 7 8gulp.task('default',['build','watch']) 9gulp.task('watch',()=>{ 10 return gulp.watch('src/js/*.js',['build']) 11}) 12gulp.task('build',()=>{ 13 return gulp 14 .src('src/js/*.js') 15 .pipe(plumber()) 16 .pipe(through2.obj(function(file,encode,callback){ 17 browserify(file.path) 18 .transform(babelify) 19 .bundle(function(err,res){ 20 if(err){ 21 return callback(err) 22 } 23 file.contents = res 24 callback(null,file) 25 }) 26 })) 27 .on('error',function(error){ 28 console.log(error.message) 29 this.emit('end') 30 }) 31 .pipe(uglify({preserveComments:'some'})) 32 .pipe(gulp.dest('./build/js/')) 33})

src/js/index.js

jsx

1import React from 'react' 2export default class Component extends React.Component{ 3 render(){ 4 // return <div>ok</div> 5 return <div>{syntax error!}</div> 6 } 7}

bash

1gulp 2# [10:33:46] Requiring external module babel-core/register 3# [10:33:46] Using gulpfile ~/Downloads/hoge/gulpfile.babel.js 4# [10:33:46] Starting 'build'... 5# [10:33:46] Starting 'watch'... 6# [10:33:46] Finished 'watch' after 11 ms 7# /Users/59naga/Downloads/hoge/src/js/index.js: Unexpected token (5:24) while parsing file: /Users/59naga/Downloads/hoge/src/js/index.js 8# [10:33:46] Finished 'build' after 98 ms 9# [10:33:46] Starting 'default'... 10# [10:33:46] Finished 'default' after 15 μs

参考

For reference, it was the this.emit('end'); that is now needed: - Watch stops on errors (Figure out better error handling) · Issue #259 · gulpjs/gulp

投稿2015/10/27 01:44

編集2015/10/27 08:30
horse_n_deer

総合スコア454

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

notable

2015/10/28 06:32

解決できました! ありがとうございます!!
guest

0

gulp.watchが止まってしまいます。

これは、gulpコマンドそのものが停止してしまうのでしょうか?
それともgulpコマンドは実行されたままjavascriptファイルを変更してもタスクが実行されなくなる現象でしょうか?

後者の場合、一度、run-sequencebrowser-syncが原因で
JSHintでエラー/ワーニングがあるとjavascriptファイルを変更しても一切タスクが実行されなくなる (watchされなくなる?)」という現象に出遭ったことがあります。
これは、browserSync.reload(){stream: true, once: true}というオプションを与えることで解決しました。

gulpそのものは止まらないが、jshintなどでエラーがあるとjsファイルのwatchが認識されなくなったパターン

javascript

1var gulp = require("gulp"), 2 /* 中略 */ 3 browserSync = require('browser-sync'), 4 reload = browserSync.reload; 5 6// watch で実行されるjavascriptのタスク 7gulp.task('js', function(cb) { 8 runSequence('jshint', 'js.build', reload); 9 // ↑ reloadを指定すると、最後に cb を追加するとエラーになってしまう。 10}); 11 12// watch 13gulp.task('default', function() { 14 gulp.watch([devDir + '/js/**/*.js'], ['js']); 15});

browserSync.reload(){stream: true, once: true}というオプションを与えることで解決したパターン

javascript

1var gulp = require("gulp"), 2 /* 中略 */ 3 browserSync = require('browser-sync'); 4 5// reloadを別タスク化 6gulp.task('reload', function() { 7 return gulp.src('/') 8 .pipe( browserSync.reload({stream: true, once: true}) ); 9}); 10 11// watch で実行されるjavascriptのタスク 12gulp.task('js', function(cb) { 13 runSequence('jshint', 'js.build', 'reload', cb); 14}); 15 16// watch 17gulp.task('default', function() { 18 gulp.watch([devDir + '/js/**/*.js'], ['js']); 19});

問題が、gulpコマンドそのものが停止してしまうであると的はずれな回答となりますが、
gulpは実行されたままwatchされなくなっている場合は、この辺りが原因のこともあるかもしれません。

参考: Gulp JSHintでError Warningsが無い時だけ次のタスクを実行してリロードさせたい

投稿2015/10/07 12:10

KiKiKi_KiKi

総合スコア596

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

notable

2015/10/08 00:15

ありがとうございます。 現象としては次のようなエラーが表示されてGulpそのものが止まります。 gulp/node_modules/vinyl-fs/node_modules/vinyl/index.js:143 throw new Error('File.contents can only be a Buffer, a Stream, or null.' run-sequenceやbrowser-syncを使わない状態でも同じでした…
KiKiKi_KiKi

2015/10/08 07:42

notable さん なるほど、そもそもgulpが止まってしまう問題でしたか... では、このケースは的はずれでしたね。。。 エラーで検索したら下記のような感じのものもあったので何かしらヒントになるかもしれません。 File.contents can only be a Buffer, a Stream, or null. #1 https://github.com/hurrymaplelad/metalsmith-feed/issues/1 引き続き、僕も調べてみたいと思います!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問