在每个Gulpfile更改时如何重新启动Gulp?

我正在开发一个Gulpfile 。 一旦它改变就可以重新启动吗? 我正在CoffeeScript中开发它。 Gulp可以观看Gulpfile.coffee以便在更改保存时重新启动?

你可以创build一个gulp.watch来执行gulpfile.jstask ,并简单地spawn另一个gulp的child_process 。

 var gulp = require('gulp'), argv = require('yargs').argv, // for args parsing spawn = require('child_process').spawn; gulp.task('log', function() { console.log('CSSs has been changed'); }); gulp.task('watching-task', function() { gulp.watch('*.css', ['log']); }); gulp.task('auto-reload', function() { var p; gulp.watch('gulpfile.js', spawnChildren); spawnChildren(); function spawnChildren(e) { // kill previous spawned process if(p) { p.kill(); } // `spawn` a child `gulp` process linked to the parent `stdio` p = spawn('gulp', [argv.task], {stdio: 'inherit'}); } }); 

我用yargs为了接受“主要任务”运行一次,我们需要重新启动。 所以为了运行这个,你可以调用:

 gulp auto-reload --task watching-task 

要testing,请调用touch gulpfile.jstouch a.css来查看日志。

我创build了gulp.js cli wrapper来重新启动gulp on gulpfile change。

你可以简单地用gulperreplacegulp。

 $ gulper <task-name> 

我为此使用了一个小的shell脚本。 这也适用于Windows。

Ctrl+C停止脚本。

 // gulpfile.js gulp.task('watch', function() { gulp.watch('gulpfile.js', process.exit); }); 

Bash shell脚本:

 # watch.sh while true; do gulp watch; done; 

Windows版本: watch.bat

 @echo off :label cmd /c gulp watch goto label 

我在Caio Cunha的回答中遇到了一堆EADDRINUSE错误。 我的gulpfile打开一个本地的networking服务器连接和LiveReload 。 在旧的进程被杀死之前,新的吞噬过程似乎与旧的过程短暂地共存,所以港口仍在被即将死亡的过程中使用。

这里有一个解决共存问题的类似的解决scheme(主要基于这个 ):

 var gulp = require('gulp'); var spawn = require('child_process').spawn; gulp.task('gulp-reload', function() { spawn('gulp', ['watch'], {stdio: 'inherit'}); process.exit(); }); gulp.task('watch', function() { gulp.watch('gulpfile.js', ['gulp-reload']); }); 

这个效果相当好,但是有一个相当严重的副作用: 最后一个吞咽过程与terminal断开。 所以当gulp watch ,一个孤儿吞咽过程仍在运行。 我一直没有能够解决这个问题,额外的吞咽过程可以手动杀死,或者只是保存一个语法错误gulpfile.js

另一个解决scheme是刷新require.cache

 var gulp = require('gulp'); var __filenameTasks = ['lint', 'css', 'jade']; var watcher = gulp.watch(__filename).once('change', function(){ watcher.end(); // we haven't re-required the file yet // so is the old watcher delete require.cache[__filename]; require(__filename); process.nextTick(function(){ gulp.start(__filenameTasks); }); }); 

我知道这是一个非常古老的问题,但这是对Google的一个重要评论,所以仍然非常相关。

如果您的源gulpfile.js 位于与正在使用的目录不同的目录中 ,则这是更简单的方法。 (这很重要!)它使用gulp模块gulp-newer和gulp-data 。

 var gulp = require('gulp' ) , data = require('gulp-data' ) , newer = require('gulp-newer' ) , child_process = require('child_process') ; gulp.task( 'gulpfile.js' , function() { return gulp.src( 'sources/gulpfile.js' ) // source .pipe( newer( '.' ) ) // check .pipe( gulp.dest( '.' ) ) // write .pipe( data( function(file) { // reboot console.log('gulpfile.js changed! Restarting gulp...') ; var t , args = process.argv ; while ( args.shift().substr(-4) !== 'gulp' ) { t=args; } child_process.spawn( 'gulp' , args , { stdio: 'inherit' } ) ; return process.exit() ; } ) ) ; } ) ; 

它是这样工作的:

  • 技巧1: gulp-newer只执行以下pipe道,如果源文件比当前更新。 这样我们确保没有重启循环。
  • while循环从命令string中删除了之前的所有内容,包括gulp命令,所以我们可以通过任何参数。
  • child_process.spawn产生一个新的gulp进程,pipe道input输出和父错误。
  • 招数2: process.exit杀死当前进程。 但是,该进程将等待直到subprocess结束。

将重启function插入pipe道的方法还有很多。 无论如何,我只是碰巧使用了大量的数据。 随意评论你自己的解决scheme。 🙂

这是@ CaioToOn的重载代码的另一个版本,更符合普通的Gulp任务程序。 它也不依赖于yargs

需要spawn和initilaize过程variables( yargs ):

 var spawn = require('child_process').spawn; var p; 

默认的gulp任务将是spawner:

 gulp.task('default', function() { if(p) { p.kill(); } // Note: The 'watch' is the new name of your normally-default gulp task. Substitute if needed. p = spawn('gulp', ['watch'], {stdio: 'inherit'}); }); 

您的手表任务可能是您的默认吞咽任务。 重命名它来watch并添加一个gulp.watch()来观察你的gulp文件,并对更改运行default任务:

 gulp.task('watch', ['sass'], function () { gulp.watch("scss/*.scss", ['sass']); gulp.watch('gulpfile.js', ['default']); }); 

现在,运行gulp ,它会自动重新加载,如果你改变你的大文件!

试试这个代码(只有win32平台)

 gulp.task('default', ['less', 'scripts', 'watch'], function(){ gulp.watch('./gulpfile.js').once('change' ,function(){ var p; var childProcess = require('child_process'); if(process.platform === 'win32'){ if(p){ childProcess.exec('taskkill /PID' + p.id + ' /T /F', function(){}); p.kill(); }else{ p = childProcess.spawn(process.argv[0],[process.argv[1]],{stdio: 'inherit'}); } } }); }); 

我一直在处理同样的问题,在我的情况下,解决scheme其实很简单。 两件事情。

  1. npm install nodemon -g (如果你愿意,也可以在本地)
  2. 用cmd运行,或者像下面这样创build一个脚本: "dev": "nodemon --watch gulpfile.js --exec gulp"
  3. 刚才inputnpm run dev

–watch指定要注意的文件,–exec表示在下一行执行,gulp是你的默认任务。 只要传入参数,如果你想非默认任务。

希望能帮助到你。

编辑:使它看上去;)现在,而第一部分应该实现你以后,在我的设置,我需要添加更多,使其真正的用户朋友。 我想要的是

  1. 首先打开页面。
  2. 在gulpfile.js中查找更改,如果有的话重新启动gulp
  3. 吞下它,所以要留意文件,重build和热重新加载

如果你只按照我在第一部分所说的做,每次都会打开页面。 要修复它,创build一个将打开页面的吞咽任务。 喜欢这个 :

 gulp.task('open', function(){ return gulp .src(config.buildDest + '/index.html') .pipe(plugins.open({ uri: config.url })); 

然后在我的主要任务中,我有:

 gulp.task('default', ['dev-open']); gulp.task('dev-open', function(done){ plugins.sequence('build', 'connect', 'open', 'watch', done); }); gulp.task('dev', function(done){ plugins.sequence('build', 'connect', 'watch', done); }); 

然后修改你的npm脚本

 "dev": "gulp open & nodemon --watch gulpfile.js --watch webpack.config.js --exec gulp dev" 

会给你正是你想要的。 首先打开页面,然后保持现场重新加载。 顺便说一句livereload我使用的连接,总是使用相同的端口。 希望它适合你,享受!

安装nodemon全局npm i -g nodemon

并添加你的.bashrc(或.bash_profile或.profile)一个别名alias gulp='nodemon --watch gulpfile.js --watch gulpfile.babel.js --quiet --exitcrash --exec gulp'

这将监视文件gulpfile.js和gulpfile.babel.js(请参阅Google )的更改

PS这可以有助于无尽的任务(如手表,…),但不是单一的运行任务。 我的意思是它使用手表,所以即使吞咽任务完成后,它仍然会继续处理。 ;)

Windows的一个很好的解决scheme,它也适用于Visual Studio任务运行器。

 /// <binding ProjectOpened='auto-watchdog' /> const spawn = require('child-proc').spawn, configPaths = ['Gulpconfig.js', 'bundleconfig.js']; gulp.task('watchdog', function () { // TODO: add other watches here gulp.watch(configPaths, function () { process.exit(0); }); }); gulp.task('auto-watchdog', function () { let p = null; gulp.watch(configPaths, spawnChildren); spawnChildren(); function spawnChildren() { const args = ['watchdog', '--color']; // kill previous spawned process if (p) { // You might want to trigger a build as well args.unshift('build'); setTimeout(function () { p.kill(); }, 1000); } // `spawn` a child `gulp` process linked to the parent `stdio` p = spawn('gulp', args, { stdio: 'inherit' }); } }); 

主要变化与其他答案相比:

  • 使用child-proc,因为child_process在Windows上失败。
  • 看门狗在文件更改时退出,因为在Windows中,gulp调用被封装在批处理脚本中。 杀死批处理脚本不会杀死吞咽本身,导致多个手表随着时间的推移。
  • build立在变化上:通常一个大文件的变化也保证重build项目。

这是一个简单的版本,很容易理解,你可以设置为一个默认的任务,所以你只需要input“gulp”:

 gulp.task('watch', function() { const restartingGulpProcessCmd = 'while true; do gulp watch2 --colors; done;'; const restartingGulpProcess = require('child_process').exec(restartingGulpProcessCmd); restartingGulpProcess.stdout.pipe(process.stdout); restartingGulpProcess.stderr.pipe(process.stderr); }); gulp.task('watch2', function() { gulp.watch(['config/**.js', 'webpack.config.js', './gulpfile.js'], () => { console.log('Config file changed. Quitting so gulp can be restarted.'); process.exit(); }); // Add your other watch and build commands here } gulp.task('default', ['watch']); 

安装gulp-restart

npm install gulp-restart

此代码将为您工作。

var gulp = require('gulp'); var restart = require('gulp-restart');

gulp.task('watch', function() { gulp.watch(['gulpfile.js'], restart); })

它会重新启动gulp,在gulpfile.js上进行更改