Tom Holsters Tom Holsters - 5 months ago 8
Node.js Question

Grunt: Livereload doesn't work

I keep running into this problem everytime I try to use the live reload option of grunt watch.
No matter which port I use, I keep getting the "Fatal error: Port xxxx is already in use by another process."
I listed all ports in use, and choosing a random number that doesn't appear in the list doesn't help: it substitues xxxx with whatever port was last used in the gruntfile.

My gruntfile itself:

module.exports = function (grunt) {

pkg: grunt.file.readJSON('package.json'),

watch: {

options: {
livereload: true

js: {
files: ['.dev/**/*.js'],
tasks: ['concat', 'uglify', 'watch'],
scss: {
files: ['./dev/scss/*.scss'],
tasks: ['sass', 'concat', 'watch'],
options: {
reload: true,
livereload: false,

html: {
files: ['./dev/**/*.html', 'watch'],
tasks: ['copy', 'watch'],
grunt: {
files: ['Gruntfile.js'],
tasks: ['watch'],

concat: {
js: {
src: ['dev/js/script1.js', 'dev/js/script2.js'],
dest: 'dev/js/script.js',
css: {
src: ['./dev/css/nav.css', './dev/css/anim.css', './dev/css/style.css'],
dest: './dist/css/style.css',

uglify: {
build: {
src: 'dev/js/script.js',
dest: 'dist/js/script.min.js'

sass: { // Task
dev: { // Target
files: { // Dictionary of files
'./dev/css/style.css': './dev/scss/style.scss', // 'destination': 'source'
tasks: ['copy'],

copy: {
main: {
expand: true,
cwd: './dev/html',
src: '*.html',
dest: './dist/html/'

// Load the plugin that provides the "uglify" task.

// Default task(s).
grunt.registerTask('default', ['concat', 'uglify', 'sass', 'copy', 'watch']);


I'm still new to npm, grunt etc, and have had this issue using Yeoman as well.
Is there some application that might automatically listen to every port (I'm using Webstorm)?
However, when I close it down and use sublime and a terminal, it keeps on saying every random port is already in use


Looks like you're recursively calling watch..

Take this portion of your gruntfile for example:

watch: { // hey grunt, you now know of a task called 'watch'
    html: {
        files: ['./dev/**/*.html', 'watch'], // here are the files to watch
        tasks: ['copy', 'watch'], // and oh, hey, when you run watch, make 
                                  // sure to run watch again, recursively, forever

I think you can see where this is going. Your port is in use because your watch task is already running when it tries to run again. You don't need to register 'watch' as a task on each subsection of watch. Hope that helps :)