I have written an application in Node.js (with Express & socket.io) and I would like to use Grunt to compile my client-side stuff with livereload while developing and being connected to Node.js application. How can I do this? (Preferably without running Node.js app in another port and client in another port, because of pathing and cross-domain issues)
I installed also Yeoman and it's using out of the box grunt-contrib-livereload package, but from what I understood it's using Node.js Connect server for serving client-side files, thus being separated from my Node.js application..
Example from Gruntfile.js generated by Yeoman:
var lrSnippet = require('grunt-contrib-livereload/lib/utils').livereloadSnippet;
var mountFolder = function (connect, dir) {
return connect.static(require('path').resolve(dir));
};
// ... cut some parts
grunt.initConfig({
watch: {
livereload: {
files: [
'<%= yeoman.app %>/*/*.html',
'{.tmp,<%= yeoman.app %>}/styles/*.css',
'{.tmp,<%= yeoman.app %>}/scripts/*.js',
'<%= yeoman.app %>/images/*.{png,jpg,jpeg}'
],
tasks: ['livereload']
}
// ..cut some parts
},
connect: {
livereload: {
options: {
port: 9000,
middleware: function (connect) {
return [
lrSnippet,
mountFolder(connect, '.tmp'),
mountFolder(connect, 'app')
];
}
}
}
}
// ..cut some parts
});
grunt.registerTask('server', [
'clean:server',
'coffee:dist',
'compass:server',
'livereload-start',
'connect:livereload',
'open',
'watch'
]);
Not sure if you have solved this question yet, but I have done this by adding my express application as a middleware attached to the 'connect.livereload.options.middleware' option.
However, automatic reloading of server side code doesn't work. For that you could implement a reload friendly server using a simple 'node ./server.js', create a connect middleware that acts as a transparent proxy to your development server, and invoke that within your Gruntfile.js before your standard connect/livereload server starts.
connect: {
options: {
port: 9000,
// change this to '0.0.0.0' to access the server from outside
hostname: 'localhost'
},
livereload: {
options: {
middleware: function (connect) {
return [
lrSnippet,
mountFolder(connect, '.tmp'),
mountFolder(connect, 'app'),
require('./server') // your server packaged as a nodejs module
];
}
}
}
}
server.js:
var app = express();
...
// Export your server object.
module.exports = app;
My answer is using Gulp
that I am more familiar with, instead of Grunt, but I imagine the same approach would work with Grunt
as well.
See my repository (and an older one) and my other answer.
Neither any browser extension nor adding any script to your files is needed.
The solution is based on the gulp-livereload
and connect-livereload
packages working together. First, you start your live reload listener, and pipe into it any file changes (change *
to any more specific node-glob
to listen to only specific files):
var gulpLivereload = require('gulp-livereload');
gulpLivereload.listen();
gulp.watch('*', function(file) {
gulp.src(file.path)
.pipe(gulpLivereload());
});
Second, you configure your server to use the listener as middleware via connect-livereload
:
var connect = require('connect');
var connectLivereload = require('connect-livereload');
connect()
.use(connectLivereload())
.use(connect.static(__dirname))
.listen(8080);
See the packages for more information on how they work internally.
In the Gruntfile, remove connect:livereload
and open
from server
task.
Add following script in the HTML file
<!-- livereload script -->
<script type="text/javascript">
document.write('<script src="http://'
+ (location.host || 'localhost').split(':')[0]
+ ':35729/livereload.js?snipver=1" type="text/javascript"><\/script>')
</script>