grunt-contrib-watch
grunt-contrib-watch copied to clipboard
livereload error when running concurrent watch tasks
I'm using watch with https://github.com/sindresorhus/grunt-concurrent in a setup that looks sort of like this:
concurrent:
development: [
"watch:coffee"
"watch:jade"
]
watch:
options:
livereload: true
jade:
[config for jade...]
coffee:
[config for coffee..]
When I run concurrent:development
I get the error: "Fatal error: Port 35729 is already in use by another process." It will happen on whatever the second watch
task I put in my concurrent task. I'm guessing the first watch
task ends up spinning up the livereload server, and then the second one attempts to as well on the same port causing it to fail. Is there a better way to achieve what I'm attempting?
Just do grunt watch
. The watch task will already watch all targets in your watch config concurrently and then only run the tasks configured for the corresponding files.
That does work, but I forgot to mention that I have another watch task that I don't want to always run (one for end to end testing). So, I specifically want to just run only a couple of the defined watch tasks.
concurrent:
development: [
"watch:coffee"
"watch:jade"
]
watch:
options:
livereload: true
jade:
[config for jade...]
coffee:
[config for coffee..]
e2e:
[config for e2e, watches some files that coffee watches already...]
@colinkahn Did you ever find a work around? Trying to do exactly the same thing - different group of watches for when running tests.
Also trying to do the same thing... :) @colinkahn , @colinkahn, have you find a solution ?
You can do a dynamic alias task:
// Run with: grunt switchwatch:target1:target2 to only watch those targets
grunt.registerTask('switchwatch', function() {
var targets = Array.prototype.slice.call(arguments, 0);
Object.keys(grunt.config('watch')).filter(function(target) {
return !(grunt.util._.indexOf(targets, target) !== -1);
}).forEach(function(target) {
grunt.log.writeln('Ignoring ' + target + '...');
grunt.config(['watch', target], {files: []});
});
grunt.task.run('watch');
});
It might be worth adding this feature to the watch itself. atm it takes in only a single target where it could accept an array as well.
Works great :) Thx @shama !!
+1 to adding this feature into watch itself.
I am able to get it working using watch task inbuilt configuration. Instead of
livereload:true
do
livereload:12345
Read https://github.com/gruntjs/grunt-contrib-watch#optionslivereload
I get the same error "Fatal error: Port 35729 is already in use by another process." when I try to use grunt-contrib-watch in conjunction with grunt-express or grunt-express-server. I'm trying to run the express server on a different port for mocking out the backend. I don't have any livereload options enabled for the express server, yet I get this error whenever I enable livereload in grunt-contrib-watch on its default port.
@seglo What does your config look like? 35729
is a fairly unique port so I suspect you have multiple watch task targets starting livereload servers (or maybe another tab running grunt watch?)
@shama I made sure I have no other tabs or processes running on that port. It has to be some kind of conflicting config in my grunt file. My grunt file is pretty large.. it's basically the grunt file the yeoman generator-angular creates. Here are my watch and express configs (based on the yo-angular template config):
// The actual grunt server settings
connect: {
options: {
port: 9000,
// Change this to '0.0.0.0' to access the server from outside.
hostname: 'localhost',
//livereload: 35729
},
livereload: {
options: {
open: true,
base: [
'.tmp',
'<%= yeoman.app %>'
]
}
},
test: {
options: {
port: 9001,
base: [
'.tmp',
'test',
'<%= yeoman.app %>'
]
}
},
dist: {
options: {
base: '<%= yeoman.dist %>'
}
}
},
...
// Watches files for changes and runs tasks based on the changed files
watch: {
js: {
files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
tasks: ['newer:jshint:all'],
options: {
livereload: true /* when I set this to a port like "12345" I can run concurrently, but when it's set to true I get the error */
}
},
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: {
livereload: '<%= connect.options.livereload %>'
},
files: [
'<%= yeoman.app %>/{,*/}*.html',
'.tmp/styles/{,*/}*.css',
'<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
]
}
},
...
express : {
mockApi: {
options: {
server: path.resolve('./mock-api.js'),
port: 3000
}
}
},
EDIT: Added connect config for reference.
@seglo The problem is this: livereload: '<%= connect.options.livereload %>'
points to a non-existent place in the config (because it is commented out above). So the watch task will use the default settings and start up a live reload server on 35729
.
I'm not sure why they have livereload
configured within the watch:js and watch:livereload. It only needs to be configured once. I would remove watch.js.options
and just let the watch:livereload target handle which files trigger it. Then if commenting out //livereload: 35729
be sure to update livereload: '<%= connect.options.livereload %>'
to point to something.
Run this command : $ lsof | grep 35729 see what other app useing the same port 1- make sure you have only on terminal window open 2 - if you install the live reload to sublime text just change the port
I remember dealing with this. Here's how I solved it.
I came across this issue when I was trying to solve a similar problem; the solution I opted for was to have a separate watch task to watch the built files and only trigger livereload on that, it didn't occur to me to do that until I read through all the docs so leaving this here hoping it's useful to someone else too.
grunt.initConfig({
'scripts-app': {
files: ['source/scripts/**/*.js'],
tasks: ['lint', 'scripts'],
options: {
spawn: false,
},
},
assets: {
files: ['source/assets/**/*'],
tasks: ['assets'],
options: {
spawn: false,
},
},
html: {
files: ['source/html/**/*'],
tasks: ['template'],
options: {
spawn: false,
},
},
livereload: {
options: { livereload: true },
files: ['public/**/*'],
},
},
concurrent: {
watch: {
tasks: ['watch:scripts', 'watch:assets', 'watch:html', 'watch:livereload'],
options: {
logConcurrentOutput: true,
},
},
},
});