Grunt中类似Nodemon的任务:执行节点进程并观察

时间:2013-03-05 17:17:17

标签: node.js gruntjs watch spawn

我觉得我错过了什么。

这是我想要实现的目标:

执行我的server.js执行grunt任务并并行运行watch任务。我觉得这正是grunt设计的任务之一,但我无法实现这种配置。

其中,我读过这个: Running Node app through Grunt 但我还是做不到。

这是我的Gruntfile.js:

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    watch: {
      scripts: {
        files: ['*.js'],
        tasks: ['start'],
        options: {
          nospawn: true
        }
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-watch');

  grunt.registerTask('start', function() {
    grunt.util.spawn({
      cmd: 'node',
      args: ['server.js']
    });
    grunt.task.run('watch');
  });

  grunt.registerTask('default', 'start');
};

我的"grunt-contrib-watch": "~0.3.1"版本应高于grunt-contrib-watch@0.3.0,如前所述。

如果你能帮助我实现正确的配置,我将非常感激。但更多的是,我不明白为什么没有正式的grunt-contrib-nodemon-like包和任务,因为我觉得使用grunt是另一个很好的理由(我真的很喜欢它作为工具!)

由于

3 个答案:

答案 0 :(得分:27)

修改:grunt-nodemon

自写这篇文章以来,一个好人开发了这个。


使用grunt.util.spawn解决新进程时遇到了很多麻烦。他们会跑,但他们不会给我任何输出。也许你可以弄清楚我在这些文档中无法做到的事情。 http://gruntjs.com/api/grunt.util#grunt.util.spawn

我看到你遇到的两个问题:

  • 我认为当你使用回调函数来运行你的任务时,grunt.registerTask()必须带三个参数。
  • 我不认为每次文件更改时都可以反复调用node server.js。它将在第一次工作,因为它真正起作用,您必须将服务器作为子进程进行管理,在后续文件更改时终止并重新启动它。

对于registerTask参数尝试这个,只是为了看看你是否可以在当前的实现中使用它。

http://gruntjs.com/api/grunt.task#grunt.task.registertask

这样需要(taskName, description, taskFunction)

grunt.registerTask('start', 'My start task description', function() {
  grunt.util.spawn({
    cmd: 'node',
    args: ['server.js']
  });
  grunt.task.run('watch');
});

这可能至少让您的watch在文件第一次更改时运行node server.js

这就是我要做的事情。

要么按原样使用nodemon $ nodemon server.js

...或

阅读来源并使用grunt-develop

他将服务器作为子进程管理,可能正是您正在寻找的。

...或

获取grunt-shell
npm install grunt-shell --save-dev

并使用它为您运行nodemon:

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    serverFile: 'server.js',
    shell: {
      nodemon: {
        command: 'nodemon <%= serverFile %>',
        options: {
          stdout: true,
          stderr: true
        }
      }
    },
    watch: { /* nothing to do in watch anymore */ }
  });

  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-shell');

  grunt.registerTask('default', 'shell:nodemon');
};

$ grunt shell:nodemon

我衷心希望有所帮助。祝你好运!

答案 1 :(得分:2)

您好我也遇到过这个问题,这是我的解决方案(根据nackjicholson的回答)。这会在grunt-nodemon中使用spawned process。所以我可以:

  • 重新加载nodejs
  • 注意对例如.less files
  • 获取两个任务的输出

    grunt.loadNpmTasks('grunt-nodemon');
    grunt.initConfig({
        nodemon: {
            dev: {
                options: {
                    file: 'server.js',
                    nodeArgs: ['--debug'],
                    env: {
                        PORT: '8282'
                    }
                }
            }
        },
    });
    
    grunt.registerTask('server', function (target) {
        // Running nodejs in a different process and displaying output on the main console
        var nodemon = grunt.util.spawn({
             cmd: 'grunt',
             grunt: true,
             args: 'nodemon'
        });
        nodemon.stdout.pipe(process.stdout);
        nodemon.stderr.pipe(process.stderr);
    
        // here you can run other tasks e.g. 
        // grunt.task.run([ 'watch' ]);
    
    });
    

答案 2 :(得分:1)

使用grunt-concurrent

问题是watch和nodemon之类的任务永远不会终止,所以grunt永远不会到达它们。你需要产生一个新的过程。

您可以使用grunt-concurrent:

轻松完成此操作

https://github.com/sindresorhus/grunt-concurrent

例如:

module.exports = function(grunt) {
  grunt.initConfig({

    ...

    concurrent: {
      dev: {
        tasks: ['nodemon', 'watch'],
        options: {
          logConcurrentOutput: true
        }
      }
    }
  });
};

现在两人将幸福地并肩奔跑。