1

我正在尝试编写一个metalsmith 插件,该插件在文件更改时重建文件并通过tiny-lr重新加载页面。

观察和重建工作正常,但是当文件更改时,tiny-lr 服务器会再次启动——这会导致错误,因为服务器已经在运行。

这是插件代码:

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();
  }
}

文件更改时的控制台输出:

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

为什么服务器第二次启动?

我怎样才能防止它被启动?

奖金问题:

为什么控制台消息的顺序与我在查看代码时所期望的顺序不同?特别是,为什么在“观看文件”之后会出现“构建成功”?我认为它应该直接出现在“重建文件...”之后。

4

1 回答 1

1

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();
    };
  }
}
于 2014-08-06T11:52:15.213 回答