Reputation: 610
I'm trying to write a metalsmith plugin that rebuilds files on file change and reloads the page via tiny-lr.
Watching and rebuilding works fine, but when a file is changed, the tiny-lr server is started again – which results in an error because the server is allready running.
Here's the plugin code:
module.exports = plugin;
var gaze = require('gaze'),
chalk = require('chalk'),
tinylr = require('tiny-lr');
function plugin(){
return function(files, metalsmith, done){
var port = 35729,
server = tinylr();
server.listen(port, function(){
console.log(chalk.cyan('Listening on port', port));
});
gaze(['templates/*', 'src/**/*'], function(err, watcher) {
console.log(chalk.green('Watching files'));
this.on('changed', function(filepath) {
console.log(chalk.red(filepath) + chalk.blue(' was changed.'));
console.log(chalk.yellow('Rebuilding files...'));
metalsmith.build(function(err, files){
console.log(chalk.blue('Build successful'))
});
});
});
done();
}
}
Console output when a file is changed:
Listening on port 35729
Watching files
/Users/benjamin/metal/src/content/index.md was changed.
Rebuilding files...
... Uhoh. Got error listen EADDRINUSE ...
Error: listen EADDRINUSE
at errnoException (net.js:901:11)
at Server._listen2 (net.js:1039:14)
at listen (net.js:1061:10)
at Server.listen (net.js:1127:5)
at Server.listen (/Users/benjamin/Desktop/metal/node_modules/metalsmith-watchall/node_modules/tiny-lr/lib/server.js:145:15)
at /Users/benjamin/Desktop/metal/node_modules/metalsmith-watchall/index.js:26:12
at next (/Users/benjamin/Desktop/metal/node_modules/metalsmith/node_modules/ware/lib/index.js:68:8)
at /Users/benjamin/Desktop/metal/node_modules/metalsmith-templates/node_modules/async/lib/async.js:119:25
at /Users/benjamin/Desktop/metal/node_modules/metalsmith-templates/node_modules/async/lib/async.js:24:16
at convert (/Users/benjamin/Desktop/metal/node_modules/metalsmith-templates/lib/index.js:67:32)
Watching files
Build successful
Why is the server started a second time?
How can I prevent it from being started?
Bonus question:
Why are the console messages not in the order that I would expect from looking at the code? Especially, why does "Build sucessful" appear after "Watching files"? I would think it should appear directly after "Rebuilding files...".
Upvotes: 1
Views: 347
Reputation: 610
Still clueless why the example above doesn't work, but here's something I came up with that does (thanks chuck for reminding me to post a solution...)
module.exports = plugin;
var gaze = require('gaze'),
chalk = require('chalk'),
tinylr = require('tiny-lr');
var watchall = {
running: false
};
function startLiveReloadServer(){
var port = 35729,
server = tinylr();
server.listen(port, function(){
console.log(chalk.cyan('Listening on port', port));
});
watchall.server = server;
};
function startWatcher(metalsmith, files, done){
gaze(['templates/*', 'src/**/*'], function(err, watcher) {
console.log(chalk.green('Watching files'));
this.on('changed', function(filepath) {
console.log(chalk.red(filepath) + chalk.blue(' was changed.'));
console.log(chalk.yellow('Rebuilding files...'));
metalsmith.build(function(err, files){
console.log(chalk.blue('Build successful'))
watchall.server.changed({body:{files:Object.keys(files)}});
});
});
});
done();
};
function plugin(){
return function(files, metalsmith, done){
if ( watchall.running === false ) {
startLiveReloadServer();
startWatcher(metalsmith, files, done);
watchall.running = true;
} else {
done();
};
}
}
Upvotes: 1