Grunt:`contrib-watch`在编译服务器端`.coffee`文件后重新启动`grunt-nodemon`之后的firererere事件

时间:2013-10-18 18:49:26

标签: gruntjs grunt-contrib-watch grunt-concurrent

我一直遇到Grunt.js和一些插件的问题,特别是:grunt-contrib-watchgrunt-nodemongrunt-contrib-coffee。我一直试图解决这个问题两天,但我不认为我对Grunt的了解足以解决它。

我遇到的问题只是我想要我的服务器端.coffee文件进行编译,然后让nodemon重新启动服务器,然后只有livereload工作。现在,Livereload按照预期的方式处理除服务器端coffee文件之外的所有内容。 contrib-watch检测到更改,运行coffee并触发livereload事件,但随后nodemon重新启动。

有没有办法在页面重新加载之前让nodemon重新启动,这样我在屏幕上看到的内容与我服务器端代码中的内容是最新的?

我已经看到了在一个单独的终端选项卡中运行nodemon的选项,但是我在Windows上并且更希望保持一个终端为此运行,这就是我的全部原因m使用grunt-concurrent

这是我的Grunt文件,它处于阶段的早期阶段(因为我试图弄清楚这一切)。如果您希望我将其编译为JavaScript,那么只需留下评论并请求,我将很乐意。

module.exports = (grunt) ->

  # configuration
  grunt.initConfig
    pkg: grunt.file.readJSON 'package.json'

    # watch task
    watch:
      css:
        files: ['src/assets/styles/**/*.styl']
        tasks: ['stylus']
        options:
          livereload: true
      coffee:
        files: ['src/**/*.coffee']
        tasks: ['coffee']
      js:
        files: ['**/*.js']
        options:
          livereload: true
      jade:
        files: ['views/**/*.jade']
        options:
          livereload: true

    # compile coffeescript to javascript
    coffee:
      compile:
        options:
          sourceMap: true
        files: [
          expand: true
          cwd: 'src/'
          src: ['**/*.coffee']
          dest: ''
          ext: '.js'
        ]

    # compile stylus to css
    stylus:
      compile:
        files: [
          expand: true
          cwd: 'src/assets/styles/'
          src: ['**/*.styl']
          dest: 'assets/styles/'
          ext: '.css'
        ]

    # run server
    nodemon:
      dev:
        options:
          file: 'server.js'
          watchedExtensions: ['js', 'json']
          ignoredFiles: [
            'assets/**',
            'node_modules/**',
            '**/.js.map'
          ]

    # run tasks concurrently for fast builds
    concurrent:
      first:
        tasks: ['coffee', 'stylus']
        options:
          logConcurrentOutput: true
      second:
        tasks: ['nodemon', 'watch']
        options:
          logConcurrentOutput: true

  # load dependencies
  require('load-grunt-tasks') grunt

  # register tasks
  grunt.registerTask 'default', [
    'concurrent:first',
    'concurrent:second'
  ]

4 个答案:

答案 0 :(得分:3)

我自己没有用过这个,但我刚才发现它:grunt-rerun。与监视任务结合使用,您可以暂停一个长时间运行的任务,如快速(但也可能与nodemon一起使用),运行一些任务,然后再次启动任务。示例配置如下所示:

grunt.initConfig({
  watch: {
      dev: {
        files: ['server/*.js'],

        //Note the :go flag used for sending the reload message to the rerun server
        tasks: ['clean','rerun:dev:express:go']
      },
    },
    express: {
        dev: {
            options: {
                port: 3000,
                bases: ['/public'],
                keepalive: true,
                server: path.resolve('./server/app.js')
            }
        }
    },
    // Configuration to be run (and then tested).
    rerun: {
      dev: {
        options: {
          tasks: ['express']
        },
      },
    }
})

https://npmjs.org/package/grunt-rerun

我不太确定实时重装的事情。我的猜测是因为它关闭了这个过程,通过生成一个新的,它会重新加载页面,但我没有亲自使用这个,所以我不确定。

第二种方法是肯定的,使用支持多个标签的命令提示符,例如Console。我是Mac用户,因此我使用具有多个窗格的iTerm 2;对于watchtestem,一个php服务器和一个用于其他所有内容的shell,大多数时候我每个项目都有四个打开。你可能会发现这更快,更轻松。

只是关于Coffeescript的快速说明,很多JavaScript开发人员都没有使用它,所以为了让更广泛的受众了解您的源代码,在之前将咖啡编译成js 可能是一个好习惯。 >你发表你的问题。

答案 1 :(得分:2)

我使用watch来观察服务器文件和一个简单的'2SecDelay'任务,它让nodemon有时间重启服务器。

所以,我得到了一个补丁,但它很难看:

grunt.registerTask '2SecDelay', 'just taking some time', ->
  done = @async()
  setTimeout((() -> done()), 2000)

...

nodemon:
  server:
    ... run server and watch server related files ...
watch:
  server: 
    files: ... same files as the nodemon watches ...
    tasks: ['2SecDelay']
concurrent:
  server:
    ['nodemon', 'watch']

```

答案 2 :(得分:1)

为什么要重新加载咖啡/手写笔/玉器文件?

只需重新加载已编译的更改!我猜你有一个公共文件夹,其中包含.coffee / .styl / .jade文件的编译输出

这是我的Gruntfile示例:

module.exports = (grunt) ->
  grunt.config.init
    ...

    watch:
      css:
        files: ['src/assets/styles/**/*.styl']
        tasks: ['stylus']
      coffee:
        files: ['src/**/*.coffee']
        tasks: ['coffee']
      jade:
        files: ['views/**/*.jade']
      livereload:
        files: ['public/**/*.*']
        options:
          livereload: true
    ...

这样,您还将触发非js / css文件更改的实时重载,如图像,字体等。而且你总是确定会触发livereload

答案 3 :(得分:0)

我在服务器启动时向tiny-lr添加了以下http请求。

var server = app.listen(process.env.PORT || 3000, function() {
  debug('Koa server listening on port ' + server.address().port);

  require('http').get({host: 'localhost', port: 35729, path: '/changed?files=app.js'},      
     function (response){
        console.log('Restart');
  });
});

我有运行nodemon的Webstorm,所以这似乎是在nodemon和我正在使用的livereload服务器实现之间进行通信的一种简单方法。

我尝试从Gulp任务运行nodemon并在那里进行http调用以保持我的代码干净但是nodemon似乎没有在服务器启动后触发的事件 - 重启之前触发

应用程序自己的侦听事件似乎是触发刷新的最佳位置,因为您知道此时服务器已准备好开始处理请求。

这些不是问题中指定的技术,但原则应该同样适用。