ericclemmons / grunt-express-server

Grunt task for running an Express Server that works great with LiveReload + Watch/Regarde

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

livereload does not seem to work with watch

konsumer opened this issue · comments

I am using yeoman. I want to replace grunt-contrib-connect with this module, so I can run my express server. I probably just missed something, but I can't seem to get it to work like grunt-contrib-connect does with a static dir. The relevant parts of my grunt config look like this:

watch: {
  bower: {
    files: ['bower.json'],
    tasks: ['bowerInstall']
  },
  js: {
    files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
    tasks: ['newer:jshint:all'],
    options: {
      livereload: true
    }
  },
  jsTest: {
    files: ['test/spec/{,*/}*.js'],
    tasks: ['newer:jshint:test', 'karma']
  },
  styles: {
    files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
    tasks: ['newer:copy:styles', 'autoprefixer']
  },
  gruntfile: {
    files: ['Gruntfile.js']
  },
  livereload: {
    options: {
      spawn: false
    },
    files:  [
      'server.js',
      'modules/*.js',
      'models/*.js',
      'package.json',
      '<%= yeoman.app %>/{,*/}*.html',
      '.tmp/styles/{,*/}*.css',
      '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
    ],
    tasks:  [ 'express:livereload' ]
  },
  less: {
      files: ['<%= yeoman.app %>/styles/{,*/}*.less'],
      tasks: ['less:dist']
  }
},
express: {
  options: {
    script: 'server.js'
  },
  livereload: {
    options: {
    }
  },
  test: {
    options: {
    }
  },
  dist: {
    options: {
    }
  }
}

My task looks like this:

grunt.registerTask('serve', function (target) {
  if (target === 'dist') {
    return grunt.task.run(['build', 'express:dist:keepalive']);
  }

  grunt.task.run([
    'clean:server',
    'bowerInstall',
    'useminPrepare',
    'concurrent:server',
    'autoprefixer',
    'express:livereload',
    'watch'
  ]);
});

I made a minimal example, and it doesn't reload, either:


module.exports = function (grunt) {
    grunt.initConfig({
      express: {
        dev: {
          options: {
            script: 'server.js'
          }
        }
      },
      watch: {
        express: {
          files:  [ 'app/**/*.js' ],
          tasks:  [ 'express:dev' ],
          options: {
            spawn: false // for grunt-contrib-watch v0.5.0+, "nospawn: true" for lower versions. Without this option specified express won't be reloaded
          }
        }
      }
    });

    grunt.loadNpmTasks('grunt-express-server');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.registerTask('default', [ 'express:dev', 'watch' ]);
};

It starts & stops the server, but no live-reload in chrome.

hhhhwhat!?!?! I'll test this out & get this crap fixed. @ericclemmons probably screwed up :)

Hehe. no biggie. I been meaning to try out gulp, but may be good for yeomanites. Is there some client-side magic js that needs to be injected or something?

I think you simply forgot to specify livereload: true for watch

module.exports = function (grunt) {
    grunt.initConfig({
      express: {
        dev: {
          options: {
            script: 'server.js'
          }
        }
      },
      watch: {
        express: {
          files:  [ 'app/**/*.js' ],
          tasks:  [ 'express:dev' ],
          options: {
            spawn: false,
            livereload: true
          }
        }
      }
    });

    grunt.loadNpmTasks('grunt-express-server');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.registerTask('default', [ 'express:dev', 'watch' ]);
};

I have a similar issue. Livereload refreshes the browser before express has a chance to start.

module.exports = (grunt) ->
  grunt.initConfig
    pkg: grunt.file.readJSON('package.json')
    express:
      options:
        cmd: 'coffee'

      dev:
        options:
          script: 'app/server.coffee'

    watch:
      express:
        files:  [ 'app/**/*.coffee' ]
        tasks:  [ 'express:dev' ]
        options:
          spawn: false
          livereload: true

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

  grunt.registerTask('default', ['express:dev', 'watch'])

@thgil take a look at #50 .. it is a problem of coffeescript: When using coffee, the server is not restartable.

I took a look at your issue on spawning a coffee child process doesn't work as expected and repeated your test of

test.coffee:

spawn = require('child_process').spawn
child = spawn("coffee",["subtest.coffee"])
child.stdout.on 'data', (data) ->
  console.log('stdout: ' + data)
console.log(child.pid)

subtest.coffee:

console.log(process.pid)

and got matching pid everytime

89136
stdout: 89136
89192
stdout: 89192

Should this allow the server to be restartable, if the coffee process can be killed?

hmm .. then it should work. Could you provide more information, to make it reproducible?
Version of node, grunt-express-server, grunt-contrib-watch?
Which system?

Package.json

{
  "name": "application-name",
  "version": "0.0.1",
  "private": true,
  "engines" : {
    "node" : "~0.10.21"
   },
  "dependencies": {
    "express": "3.4.7"
  },
  "devDependencies": {
    "grunt": "~0.4.2",
    "grunt-express-server": "~0.4.13",
    "grunt-contrib-watch": "~0.6.1"
  }
}

Gruntfile.js

module.exports = function (grunt) {
    grunt.initConfig({
      express: {
        dev: {
          options: {
            script: 'app.js'
          }
        }
      },
      watch: {
        express: {
          files:  [ 'app.js' ],
          tasks:  [ 'express:dev' ],
          options: {
            spawn: false,
            livereload: true,
          }
        }
      }
    });

    grunt.loadNpmTasks('grunt-express-server');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.registerTask('default', [ 'express:dev', 'watch' ]);
};

app.js

var express = require('express');
var app = express();

app.get('/', function(req, res){
  res.send('hello world123');
});

app.listen(3000);
console.log('\n  listening on port 3000\n');

This doesn't reload properly. It seems livereload refreshes the page before the server can start. Although even adding a delay doesn't help so something else might be going wrong.

debounceDelay: 2000

Ok. I could reproduce and workaround .. but I'm not understanding why.

doesn't work

watch: {
  express: {
    files:  [ 'app.js' ],
    tasks:  [ 'express:dev' ],
    options: {
      spawn: false,
      livereload: true
    }
  }
}

works

watch: {
  options: {
    livereload: true
  },
  express: {
    files:  [ 'app.js' ],
    tasks:  [ 'express:dev' ],
    options: {
      spawn: false
    }
  }
}

could also be a problem of grunt-contrib-watch

Weird.. the workaround doesn't work for me. Same issue.

yeah .. doesn't work for me anymore, too.
I think there is a race condition for starting the server / livereload

ok .. I found the bug in here
the finished function is triggered regardless of the server state
I will make a pr

Awesome, thanks for the help!

Livereload refreshes the browser before express has a chance to start.
I have the same issue.
what should I do, my configuration is the same.

This should be resolved via v0.4.14& #53, thanks to @paulpflug. Let me know if there are still issues!