我正在开发Gulpfile
。一旦它改变就可以重新启动吗?我正在用CoffeeScript开发它。可以Gulp
观看Gulpfile.coffee
以便在保存更改时重新启动吗?
答案 0 :(得分:59)
您可以为task
和spawn
another gulp child_process gulp.watch
创建一个gulpfile.js
。
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
要进行测试,请致电touch gulpfile.js
或touch a.css
查看日志。
答案 1 :(得分:37)
答案 2 :(得分:11)
我为此目的使用了一个小的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
答案 3 :(得分:9)
我在Caio Cunha的回答中得到了一堆EADDRINUSE
错误。我的gulpfile打开了一个包含connect和LiveReload的本地网络服务器。看起来新的gulp进程在旧进程被杀之前与旧的进程短暂共存,因此即将到来的进程仍在使用端口。
这是解决共存问题的类似解决方案(主要基于this):
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']);
});
效果相当好,但有一个相当严重的副作用:最后一个gulp进程与终端断开连接。因此当gulp watch
退出时,孤立的gulp进程仍在运行。我无法解决这个问题,可以手动杀死额外的gulp进程,或者只是将语法错误保存到 gulpfile.js 。
答案 4 :(得分:3)
另一个解决方案是刷新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);
});
});
答案 5 :(得分:2)
我知道这是一个非常古老的问题,但这是对谷歌的最高评论,因此仍然非常相关。
如果您的源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() ;
} ) )
;
} ) ;
它的工作原理如下:
还有许多其他方法可以将重启功能插入管道。 无论如何,我恰巧在我的每个gulpfiles中使用gulp-data。随意评论您自己的解决方案。 :)
答案 6 :(得分:1)
这是@CaioToOn的另一个版本的重新加载代码,它更符合正常的Gulp任务程序。它也不依赖于yargs
。
需要生成并初始化流程变量(不需要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'});
});
您的监视任务可能是您的默认gulp任务。将其重命名为watch
并添加gulp.watch()
以观察您的gulpfile并对更改运行default
任务:
gulp.task('watch', ['sass'], function () {
gulp.watch("scss/*.scss", ['sass']);
gulp.watch('gulpfile.js', ['default']);
});
现在,只需运行gulp
,如果更改了gulp文件,它将自动重新加载!
答案 7 :(得分:1)
尝试此代码(仅限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'});
}
}
});
});
答案 8 :(得分:1)
我一直在处理同样的问题,而我的案例中的解决方案实际上非常简单。两件事。
npm install nodemon -g
(如果您愿意,可在本地使用)使用cmd运行或在包中创建脚本:
"dev": "nodemon --watch gulpfile.js --exec gulp"
只是输入npm run dev
--watch
指定要关注的文件。 --exec
表示执行下一行,gulp
是您的默认任务。如果你想要非默认任务,只需传入参数。
希望它有所帮助。
编辑:让它看起来很棒;) 现在,虽然第一部分应该实现你所追求的目标,但在我的设置中,我需要添加更多内容才能使其真正成为用户朋友。我想要的是
如果您只做我在第一部分中所说的内容,它每次都会打开页面。要修复它,请创建一个打开页面的gulp任务。像这样:
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"
会准确地给你你想要的东西。首先打开页面然后只是保持实时重新加载。 btw for livereload我使用的是随附的连接,它总是使用相同的端口。希望它适合你,享受!
答案 9 :(得分:1)
全局安装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)
P.S。这对于无休止的任务(如watch
)有帮助,但对单次运行任务则无效。我的意思是它使用手表,所以即使在gulp任务完成后它也会继续处理。 ;)
答案 10 :(得分:1)
Windows的一个很好的解决方案,它也适用于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' });
}
});
与其他答案相比的主要变化:
答案 11 :(得分:0)
这是一个易于理解的简短版本,您可以将其设置为默认任务,因此您只需输入“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']);
答案 12 :(得分:0)
安装gulp-restart
<强> npm install gulp-restart
强>
此代码适合您。
var gulp = require('gulp');
var restart = require('gulp-restart');
gulp.task('watch', function() {
gulp.watch(['gulpfile.js'], restart);
})
它会重新启动你在gulpfile.js上进行更改的gulp
答案 13 :(得分:0)
我花了一整天试图在 Windows / Gulp 4.0.2 上完成这项工作,我(终于)成功了...
我在此页面和其他页面上使用了一些来自人们的解决方案。都在评论里...
“allTasks”中任何函数的任何更改都会对 gulpfile.js(或其他监视文件)的保存生效...
还有一些无用的评论和console.logs,请随意删除它们...;)
const { gulp, watch, src, dest, series, parallel } = require("gulp");
const spawn = require('child_process').spawn;
// This function contains all that is necessary: start server, watch files...
const allTasks = function (callback) {
console.log('==========');
console.log('========== STARTING THE GULP DEFAULT TASK...');
console.log('========== USE CTRL+C TO STOP THE TASK');
console.log('==========');
startServer();
// other functions (watchers) here
// *** Thanks to Sebazzz ***
// Stop all on gulpfile.js change
watch('gulpfile.js', function (callback) {
callback(); // avoid "task didn't complete" error
process.exit();
});
callback(); // avoid "task didn't complete" error
}
// Restart allTasks
// ********************************************
// CALL GULPDEFAULT WITH THE GULP DEFAULT TASK:
// export.default = gulpDefault
// ********************************************
const gulpDefault = function (callback) {
let p = null;
watch('gulpfile.js', spawnChildren);
// *** Thanks to Sphinxxx: ***
// New behavior in gulp v4: The watcher function (spawnChildren()) is passed a callback argument
// which must be called after spawnChildren() is done, or else the auto-reload task
// never goes back to watching for further changes (i.e.the reload only works once).
spawnChildren(callback);
function spawnChildren(callback) {
/*
// This didn't do anything for me, with or without the delay,
// so I left it there, but commented it out, together with the console.logs...
// kill previous spawned process
if (p) {
// You might want to trigger a build as well
//args.unshift('build');
setTimeout(function () {
console.log('========== p.pid before kill: ' + p.pid); // a random number
console.log('========== p before kill: ' + p); // [object Object]
p.kill();
console.log('========== p.pid after kill: ' + p.pid); // the same random number
console.log('========== p after kill: ' + p); // still [object Object]
}, 1000);
}
*/
// `spawn` a child `gulp` process linked to the parent `stdio`
// ['watch'] is the task that calls the main function (allTasks):
// exports.watch = allTasks;
p = spawn('gulp', ['watch'], { stdio: 'inherit', shell: true });
// *** Thanks to people from: ***
// https://stackoverflow.com/questions/27688804/how-do-i-debug-error-spawn-enoent-on-node-js
// Prevent Error: spawn ENOENT
// by passing "shell: true" to the spawn options
callback(); // callback called - thanks to Sphinxxx
}
}
exports.default = gulpDefault;
exports.watch = allTasks;