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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 23:57:43  来源:igfitidea点击:

How can Gulp be restarted upon each Gulpfile change?

javascriptnode.jsworkflowgulpgulp-watch

提问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 Gulpwatch Gulpfile.coffeein order to restart when changes are saved?

我正在开发一个Gulpfile. 能不能一改就重启?我正在用 CoffeeScript 开发它。保存更改后可以Gulp观看Gulpfile.coffee以重新启动吗?

采纳答案by Caio Cunha

You can create a taskthat will gulp.watchfor gulpfile.jsand simply spawnanother gulp child_process.

您可以创建一个task这种意愿gulp.watchgulpfile.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 yargsin 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.jsor touch a.cssto see the logs.

要进行测试,请致电touch gulpfile.jstouch a.css查看日志。

回答by anatoo

I created gulperthat is gulp.js cli wrapper to restart gulp on gulpfile change.

我创建条美洲即gulp.js CLI包装重新启动吞掉上gulpfile变化。

You can simply replace gulp with gulper.

你可以简单地用 gulper 替换 gulp。

$ gulper <task-name>

回答by Simon Epskamp

I use a small shell script for this purpose. This works on Windows as well.

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

Press Ctrl+Cto 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 EADDRINUSEerrors 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 使用connectLiveReload打开本地网络服务器。在旧进程被杀死之前,新的 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 watchexits, 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-newergulp-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 (yargsis 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 watchand add a gulp.watch()for watching your gulpfile and run the defaulttask 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 gulpand 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.

我一直在处理同样的问题,我的情况下的解决方案实际上非常简单。两件事情。

  1. npm install nodemon -g(or locally if you prefer)
  2. run with cmd or create a script in packages like this:

    "dev": "nodemon --watch gulpfile.js --exec gulp"
    
  3. The just type npm run dev

  1. npm install nodemon -g(或者如果您愿意,可以在本地)
  2. 使用 cmd 运行或在这样的包中创建一个脚本:

    "dev": "nodemon --watch gulpfile.js --exec gulp"
    
  3. 刚刚的类型 npm run dev

--watchspecifies the file to keep an eye on. --execsays execute next in line and gulpis 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

编辑:让它变得漂亮;) 现在虽然第一部分应该实现你所追求的,但在我的设置中,我需要添加更多内容以使其真正成为用户友好。我想要的是

  1. First open the page.
  2. Look for changes in gulpfile.js and restart gulp if there are any
  3. Gulp it up so keep an eye on files, rebuild and hot reload
  1. 首先打开页面。
  2. 在 gulpfile.js 中查找更改并重新启动 gulp(如果有)
  3. 吞下它,以便密切关注文件,重建和热重载

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 任务完成后继续处理。;)