Setting up Grunt to serve Livereload over SSL - node.js

I followed this tutorial:
http://www.gilluminate.com/2014/06/10/livereload-ssl-https-grunt-watch/
My Gruntfile.js looks like this:
module.exports = function(grunt) {
grunt.initConfig({
jshint: {
files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
options: {
globals: {
jQuery: true
}
}
},
watch: {
css: {
files: '**/*.sass',
tasks: ['sass'],
options: {
livereload: {
port: 9000,
key: grunt.file.read('ssl/livereload.key'),
cert: grunt.file.read('ssl/livereload.crt')
// you can pass in any other options you'd like to the https server, as listed here: http://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener
}
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['jshint']);
};
I added
<script src="//localhost:9000/livereload.js"></script>
at the end of my index.html file.
My goal is to run livereload over httpS: port 9000.
Maybe am I missing some part, like "run Grunt to make it load to the grunt file"?
The error I get is:
GET https://localhost:9000/livereload.js net::ERR_CONNECTION_REFUSED

Grunt-contrib-watch uses tiny-lr#^0.2.1 which doesn't support SSL, someone needs to make a pull request to upgrade tiny-lr.

Related

Use grunt with browser-refresh

I'm currently using browser-refresh to restart my node server every time I make a change to my server file. I want to take this further and have my browser refresh/reload every time I make a change to an HTML file. I'm using handlebars for the client, so I have .hbs files in my views directory. I thought browser-refresh was supposed to be able to refresh the browser as well, but it's not working for me.
For grunt, I have the following tasks installed:
grunt.loadNpmTasks('grunt-express-server');
grunt.loadNpmTasks('grunt-express');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-exec');
grunt.loadNpmTasks('grunt-open');
grunt.loadNpmTasks('grunt-express-runner');
I don't think I need all of these, but I want to find something that works. I'm able to restart my server with grunt-exec, but I already have an alias for browser-refresh, so I don't really need that.
I should also note that in my app.js server file, I'm using app.use('/', routes); where var routes = require('./routes/index');. So, when my app loads (using node app.js), it goes directly to http://localhost:3000/users/login.
Thanks in advance.
Using the grunt-contrib-watch and setting the Live reload option to true, will enable live reloads and grunt auto rebuild.
For example, in your gruntfile.js:
watch: {
css: {
files: '**/*.sass',
tasks: ['sass'],
options: {
livereload: true,
},
},
},
For the rebuild of your site, (using the grunt-contrib-watch plugin), simply type
grunt watch
To auto rebuild your website on changes, have a look at an example usage of the grunt watch command below:
gruntfile.js
module.exports = function (grunt) {
grunt.initConfig({
exec: {
server: 'node server'
},
// Other JS tasks here
// ...
watch: {
css: {
files: ['scss/**/*.scss'],
tasks: ['sass'],
options: {
spawn: false
}
},
javascript: {
files: ['js/*.js'],
tasks: ['uglify']
},
options: {
livereload: true,
},
},
});
grunt.registerTask('server', ['exec:server']);
// Minify JS and create CSS files
grunt.registerTask('build', ['uglify', 'sass']);
// Do what you expect the default task to do
grunt.registerTask('default', ['build', 'exec:server']);
};
More info here: https://github.com/gruntjs/grunt-contrib-watch/blob/master/docs/watch-examples.md#enabling-live-reload-in-your-html

Gruntjs with grunt-nodemon, watch and jshint

I'm trying to run GruntJS with those 3 plugins so it can watch for changes and first: lint the file and then reload express server.
My problem with the config below is that if jshint lint the file, nodemon doesn't run and vice versa.
// Gruntfile.js
// our wrapper function (required by grunt and its plugins)
// all configuration goes inside this function
module.exports = function(grunt) {
// ===========================================================================
// CONFIGURE GRUNT ===========================================================
// ===========================================================================
grunt.initConfig({
// get the configuration info from package.json ----------------------------
// this way we can use things like name and version (pkg.name)
pkg: grunt.file.readJSON('package.json'),
// all of our configuration will go here
// configure jshint to validate js files -----------------------------------
jshint: {
options: {
reporter: require('jshint-stylish') // use jshint-stylish to make our errors look and read good
},
// when this task is run, lint the Gruntfile and all js files in src
build: ['Grunfile.js', 'routes/*.js']
},
watch: {
// for scripts, run jshint and uglify
scripts: {
files: 'routes/*.js',
tasks: ['jshint']
}
},
concurrent: {
dev: {
tasks: ['jshint', 'nodemon', 'watch'],
options: {
logConcurrentOutput: true
}
}
}, // concurrent
nodemon: {
dev: {
script: './server.js'
}
} // nodemon
});
// ===========================================================================
// LOAD GRUNT PLUGINS ========================================================
// ===========================================================================
// we can only load these if they are in our package.json
// make sure you have run npm install so our app can find these
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-nodemon');
grunt.registerTask('default', '', function() {
var taskList = [
'jshint',
'nodemon',
'watch'
];
grunt.task.run(taskList);
});
};
EDIT (clarification):
The first time that I ran grunt, jshint lint the files, then nodemon start and jshint doesn't lint anymore.
Output:
grunt
Running "default" task
Running "jshint:build" (jshint) task
✔︎ No problems
Running "nodemon:dev" (nodemon) task
[nodemon] v1.2.1
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node ./server.js`
Express server listening on port 3000
Was a really silly mistake.
I wasn't loading grunt-concurrent, just installed grunt-concurrent and addeded it to Kelz's function and now its working :).
Thank you all.
Final code:
// Gruntfile.js
// our wrapper function (required by grunt and its plugins)
// all configuration goes inside this function
module.exports = function(grunt) {
// ===========================================================================
// CONFIGURE GRUNT ===========================================================
// ===========================================================================
grunt.initConfig({
// get the configuration info from package.json ----------------------------
// this way we can use things like name and version (pkg.name)
pkg: grunt.file.readJSON('package.json'),
// all of our configuration will go here
// configure jshint to validate js files -----------------------------------
jshint: {
options: {
reporter: require('jshint-stylish') // use jshint-stylish to make our errors look and read good
},
// when this task is run, lint the Gruntfile and all js files in src
build: ['Grunfile.js', 'routes/*.js']
},
watch: {
// for scripts, run jshint and uglify
scripts: {
files: 'routes/*.js',
tasks: ['jshint']
}
}, // watch
nodemon: {
dev: {
script: './server.js'
}
}, // nodemon
concurrent: {
dev: {
tasks: ['jshint', 'nodemon', 'watch'],
options: {
logConcurrentOutput: true
}
}
} // concurrent
});
// ===========================================================================
// LOAD GRUNT PLUGINS ========================================================
// ===========================================================================
// we can only load these if they are in our package.json
// make sure you have run npm install so our app can find these
grunt.loadNpmTasks('grunt-concurrent');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-nodemon');
grunt.registerTask('default', '', function() {
var taskList = [
'concurrent',
'jshint',
'nodemon',
'watch'
];
grunt.task.run(taskList);
});
};
Try running it as a function task:
grunt.registerTask('default', '', function() {
var taskList = [
'jshint',
'nodemon',
'watch'
];
grunt.task.run(taskList);
});
EDIT: Another method I've used to achieve the goal of auto rerunning tasks including express, using grunt-express-server, applied to your setup:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON("package.json"),
watch: {
express: {
files: ['routes/*.js'],
tasks: ['jshint', 'express:dev'],
options: {
spawn: false
}
}
},
express: {
dev: {
options: {
script: 'app.js',
}
}
},
jshint: {
options: {
node: true
},
all: {
src: ['routes/*.js']
}
}
});
grunt.loadNpmTasks('grunt-express-server');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.registerTask('default', '', function() {
var taskList = [
'jshint',
'express:dev',
'watch'
];
grunt.task.run(taskList);
});
};

How to setup Gruntfile.js to watch for SASS (compass) and JS

I'm new to using gruntjs and nodejs. I wanted to know how can I setup the gruntfile so that it watches both the sass files and the js files compiles using watch.
This is what I have so far:
module.exports = function ( grunt ) {
"use strict";
require("matchdep").filterDev("grunt-*").forEach(grunt.loadNpmTasks);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
compass: {
dist: {
options: {
config: 'config.rb',
watch: true
}
}
}
});
grunt.registerTask('default', []);
};
Any help will be much appreciated. Thank you!
Try grunt-contrib-watch with grunt-contrib-sass. They're both Grunt plugins specifically for this kind of thing:
sass: {
dist: {
options: {
style: 'compressed'
},
files: {
'css/build/global.css': 'scss/screen.scss'
}
}
},
watch: {
css: {
files: ['scss/*.scss'],
tasks: ['sass'],
options: {
spawn: false
}
}
},
The watch plugin configuration above will watch for changes in any .scss files, and will run the sass tasked (also defined above). You can even hook into livereload this way. You can also have multiple watches (the above only defines a css watch); creating a second watch to minify JS would be easy with grunt-contrib-uglify
I have an example you can look at that also concatenates JavaScript and does some minification with grunt-contrib-uglify. Here is the example.

What am I doing wrong with Gruntjs targets?

I followed the instructions on the grunt.option page to create different configurations for different environments/targets such as development, staging, and production in my Gruntfile. However, upon doing so I found that my tasks silently fail.
I've reduced the problem to a very simple example. The following Gruntfile fails to build the file:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
less: {
dev: {
options: {
compress: true
},
build: {
src: ['src/css/test.less'],
dest: 'build/css/test.css'
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.registerTask('default', ['less:dev']);
};
The output in my terminal is the following:
$ grunt
Running "less:dev" (less) task
Done, without errors.
If, however, I use the following Gruntfile, the build output is as expected:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
less: {
options: {
compress: true
},
build: {
src: ['src/css/test.less'],
dest: 'build/css/test.css'
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.registerTask('default', ['less']);
};
The terminal output for this Gruntfile reflects the built file:
$ grunt
Running "less:build" (less) task
File build/css/test.css created.
Done, without errors.
What am I doing wrong in the first Gruntfile? What is it that I am missing about this task:target convention?
Your first Gruntfile - If you want per-target options, you need to specify the files object. So your code would be something like this:
less: {
dev: {
files: {
"build/css/test.css": "src/css/test.less"
}
},
production: {
options: {
compress: true
},
files: {
"build/css/test.css": "src/css/test.less"
}
},
}
Basically in your first Gruntfile build is an unknown object. Your target is named dev and grunt-contrib-less doesn't have an option called build so Grunt doesn't know where to write the files. Your second Gruntfile works because you set the options as a global. Use the above code if you want per-target options.

Running node app from grunt with watch

So, I have the grunt file below. I'm wanting to add a task that will start my node app and watch for changes in a directory and restart. I have been using supervisor, node-dev (which are great) but I want to run one command and start my whole app. There has got to be a simple way to do this, but I'm just missing it. It is written in coffeescript as well (not sure if that changes things)...
module.exports = function(grunt) {
grunt.initConfig({
/*exec: {
startApi: {
command: "npm run-script start-api"
}
},*/
//static server
server: {
port: 3333,
base: './public',
keepalive: true
},
// Coffee to JS compilation
coffee: {
compile: {
files: {
'./public/js/*.js': './src/client/app/**/*.coffee'
},
options: {
//basePath: 'app/scripts'
}
}
},
mochaTest: {
all: ['test/**/*.*']
},
watch: {
coffee: {
files: './src/client/app/**/*.coffee',
tasks: 'coffee'
},
mochaTest: {
files: 'test/**/*.*',
tasks: 'mochaTest'
}
}
});
grunt.loadNpmTasks('grunt-contrib-coffee');
grunt.loadNpmTasks('grunt-mocha-test');
//grunt.loadNpmTasks('grunt-exec');
grunt.registerTask( 'default', 'server coffee mochaTest watch' );
};
As you can see in the comments, I tries grunt-exec, but the node command stops the execution of the other tasks.
You can set grunt to run default task and the watch task when you start your node app:
in app.js
var cp = require('child_process');
var grunt = cp.spawn('grunt', ['--force', 'default', 'watch'])
grunt.stdout.on('data', function(data) {
// relay output to console
console.log("%s", data)
});
Then just run node app as normal!
Credit

Resources