javascript 如何在每次 Gulpfile 更改时重新启动 Gulp?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22886682/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can Gulp be restarted upon each Gulpfile change?
提问by coool
I am developing a Gulpfile
. Can it be made to restart as soon as it changes? I am developing it in CoffeeScript. Can Gulp
watch Gulpfile.coffee
in order to restart when changes are saved?
我正在开发一个Gulpfile
. 能不能一改就重启?我正在用 CoffeeScript 开发它。保存更改后可以Gulp
观看Gulpfile.coffee
以重新启动吗?
采纳答案by Caio Cunha
You can create a task
that will gulp.watch
for gulpfile.js
and simply spawn
another gulp child_process.
您可以创建一个task
这种意愿gulp.watch
的gulpfile.js
,只是spawn
另一个一饮而尽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'});
}
});
I used yargs
in order to accept the 'main task' to run once we need to restart. So in order to run this, you would call:
我用来yargs
接受'主要任务'一旦我们需要重新启动就运行。因此,为了运行它,您可以调用:
gulp auto-reload --task watching-task
And to test, call either touch gulpfile.js
or touch a.css
to see the logs.
要进行测试,请致电touch gulpfile.js
或touch a.css
查看日志。
回答by anatoo
回答by Simon Epskamp
I use a small shell script for this purpose. This works on Windows as well.
为此,我使用了一个小的 shell 脚本。这也适用于 Windows。
Press Ctrl+C
to stop the script.
按Ctrl+C
停止脚本。
// gulpfile.js
gulp.task('watch', function() {
gulp.watch('gulpfile.js', process.exit);
});
Bash shell script:
Bash shell 脚本:
# watch.sh
while true; do
gulp watch;
done;
Windows version: watch.bat
视窗版本: watch.bat
@echo off
:label
cmd /c gulp watch
goto label
回答by joemaller
I was getting a bunch of EADDRINUSE
errors with the solution in Caio Cunha's answer. My gulpfile opens a local webserver with connectand LiveReload. It appears the new gulp process briefly coexists with the old one before the older process is killed, so the ports are still in use by the soon-to-die process.
我EADDRINUSE
在 Caio Cunha 的回答中遇到了一堆解决方案错误。我的 gulpfile 使用connect和LiveReload打开本地网络服务器。在旧进程被杀死之前,新的 gulp 进程似乎与旧进程短暂共存,因此端口仍在被即将死亡的进程使用。
Here's a similar solution which gets around the coexistence problem, (based largely on 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']);
});
That works fairly well, but has one rather serious side-effect: The last gulp process is disconnected from the terminal.So when gulp watch
exits, an orphaned gulp process is still running. I haven't been able to work around that problem, the extra gulp process can be killed manually, or just save a syntax error to gulpfile.js.
这很有效,但有一个相当严重的副作用:最后一个 gulp 进程与终端断开连接。所以当gulp watch
退出时,一个孤立的 gulp 进程仍在运行。我一直无法解决这个问题,额外的 gulp 进程可以手动终止,或者只是将语法错误保存到gulpfile.js。
回答by bid
I know this is a very old question, but it's a top comment on Google, so still very relevant.
我知道这是一个非常古老的问题,但它是 Google 上的最高评论,因此仍然非常相关。
Here is an easier way, if your source gulpfile.js is in a different directorythan the one in use. (That's important!) It uses the gulp modules gulp-newerand gulp-data.
这是一种更简单的方法,如果您的源 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() ;
} ) )
;
} ) ;
It works like this:
它是这样工作的:
- Trick 1: gulp-neweronly executes the following pipes, if the source file is newer than the current one. This way we make sure, there's no reboot-loop.
- The while loopremoves everything before and including the gulp command from the command string, so we can pass through any arguments.
- child_process.spawnspawns a new gulp process, piping input output and error to the parent.
- Trick 2: process.exitkills the current process. However, the process will wait to die until the child process is finished.
- 技巧 1:gulp-newer仅执行以下管道,如果源文件比当前文件新。这样我们可以确保没有重启循环。
- 该while循环中移除了之前的一切,并包括命令字符串吞气的命令,所以我们可以通过任何参数。
- child_process.spawn产生一个新的gulp进程,将输入输出和错误传送到父进程。
- 技巧 2:process.exit杀死当前进程。但是,进程会一直等待,直到子进程完成。
There are many other ways of inserting the restart function into the pipes. I just happen to use gulp-data in every of my gulpfiles anyway. Feel free to comment your own solution. :)
还有许多其他方法可以将重新启动功能插入管道。无论如何,我碰巧在我的每个 gulpfiles 中都使用了 gulp-data。请随意评论您自己的解决方案。:)
回答by stringparser
Another solution for this is to refresh the require.cache
.
另一个解决方案是刷新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);
});
});
回答by ddunderfelt
Here's another version of @CaioToOn's reload code that is more in line with normal Gulp task procedure. It also does not depend on yargs
.
这是@CaioToOn 重新加载代码的另一个版本,它更符合正常的 Gulp 任务过程。它也不依赖于yargs
.
Require spawn and initilaize the process variable (yargs
is not needed):
需要 spawn 和 initilaize 过程变量(yargs
不需要):
var spawn = require('child_process').spawn;
var p;
The default gulp task will be the spawner:
默认的 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'});
});
Your watch task was probably your default gulp task. Rename it to watch
and add a gulp.watch()
for watching your gulpfile and run the default
task on changes:
你的 watch 任务可能是你默认的 gulp 任务。将其重命名为watch
并添加一个gulp.watch()
以查看您的 gulpfile 并default
在更改时运行任务:
gulp.task('watch', ['sass'], function () {
gulp.watch("scss/*.scss", ['sass']);
gulp.watch('gulpfile.js', ['default']);
});
Now, just run gulp
and it will automatically reload if you change your gulpfile!
现在,只要运行gulp
,如果您更改 gulpfile,它会自动重新加载!
回答by AhbapAldirmaz
try this code (only win32 platform)
试试这个代码(仅限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'});
}
}
});
});
回答by Peter Kottas
I've been dealing with the same problem and the solution in my case was actually very simple. Two things.
我一直在处理同样的问题,我的情况下的解决方案实际上非常简单。两件事情。
npm install nodemon -g
(or locally if you prefer)run with cmd or create a script in packages like this:
"dev": "nodemon --watch gulpfile.js --exec gulp"
The just type
npm run dev
npm install nodemon -g
(或者如果您愿意,可以在本地)使用 cmd 运行或在这样的包中创建一个脚本:
"dev": "nodemon --watch gulpfile.js --exec gulp"
刚刚的类型
npm run dev
--watch
specifies the file to keep an eye on. --exec
says execute next in line and gulp
is your default task. Just pass in argument if you want non default task.
--watch
指定要关注的文件。--exec
说执行下一个gulp
是你的默认任务。如果您想要非默认任务,只需传入参数。
Hope it helps.
希望能帮助到你。
EDIT : Making it fancy ;) Now while the first part should achieve what you were after, in my setup I've needed to add a bit more to make it really user friend. What I wanted was
编辑:让它变得漂亮;) 现在虽然第一部分应该实现你所追求的,但在我的设置中,我需要添加更多内容以使其真正成为用户友好。我想要的是
- First open the page.
- Look for changes in gulpfile.js and restart gulp if there are any
- Gulp it up so keep an eye on files, rebuild and hot reload
- 首先打开页面。
- 在 gulpfile.js 中查找更改并重新启动 gulp(如果有)
- 吞下它,以便密切关注文件,重建和热重载
If you only do what I've said in the first part, it will open the page every time. To fix it, create a gulp task that will open the page. Like this :
如果你只按照我在第一部分说的做,它每次都会打开页面。要修复它,请创建一个将打开页面的 gulp 任务。像这样 :
gulp.task('open', function(){
return gulp
.src(config.buildDest + '/index.html')
.pipe(plugins.open({
uri: config.url
}));
Then in my main tasks I have :
然后在我的主要任务中,我有:
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);
});
Then modifying your npm scripts to
然后将您的 npm 脚本修改为
"dev": "gulp open & nodemon --watch gulpfile.js --watch webpack.config.js --exec gulp dev"
Will give you exactly what you want. First open the page and then just keep live reloading. Btw for livereload I use the one that comes with connect which always uses the same port. Hope it works for you, enjoy!
会给你你想要的。首先打开页面,然后继续实时重新加载。顺便说一句,对于 livereload,我使用了 connect 附带的那个,它总是使用相同的端口。希望它对你有用,享受!
回答by Davit Yavryan
Install nodemon globally: npm i -g nodemon
全局安装 nodemon: npm i -g nodemon
And add in your .bashrc (or .bash_profile or .profile) an alias:
并在您的 .bashrc(或 .bash_profile 或 .profile)中添加一个别名:
alias gulp='nodemon --watch gulpfile.js --watch gulpfile.babel.js --quiet --exitcrash --exec gulp'
This will watch for file gulpfile.js and gulpfile.babel.js changes. (see Google)
这将监视文件 gulpfile.js 和 gulpfile.babel.js 的变化。(见谷歌)
P.S.This can be helpful for endless tasks (like watch
) but not for single run tasks. I mean it uses watch so it will continue process even after gulp task is done. ;)
PS这对无休止的任务(如watch
)很有帮助,但对单次运行的任务没有帮助。我的意思是它使用 watch 所以它会在 gulp 任务完成后继续处理。;)