在开发 Node.js 实现的 HTTP 应用时会发现,无论你修改了代码的哪一部份,都必须终止Node.js 再重新运行才会奏效。这是因为 Node.js 只有在第一次引用到某部份时才会去解析脚本文件,以后都会直接访问内存,避免重复载入,而像PHP之类的脚本则总是重新读取并解析脚本(如
果没有专门的优化配置)。Node.js的这种设计虽然有利于提高性能,却不利于开发调试,因为我们在开发过程中总是希望修改后立即看到效果,而不是每次都要终止进程并重启。
supervisor 可以帮助你实现这个功能,它会监视你对代码的改动,并自动重启 Node.js。使用方法很简单,首先使用 npm 安装supervisor:
npm install -g supervisor
linux 下应该要加sudo才能安装。
接下来,使用 supervisor 命令启动 expressjs脚手架生成的 ./bin/www
supervisor --ignore ./view ./bin/www
由于我使用的是jade模板引擎,jade不像node那样将文件缓存到内存,而且,如果是在调试登陆后的页面布局,监视了view文件夹,会使得每次改了一点布局都得重新的登陆,很不方便。所以不必监视view文件夹。采用--ignore参数后面跟用逗号隔开的文件,可以忽略这些文件或文件夹。
另外,supervisor即时采用后台运行,在退出xshell或控制台后,supervisor还是会退出。
PS:实现一个简单supervisor
结合前面提到守护进程,我们可以定时监视文件的变化,如果有变化,就杀进程,由于有守护进程在,他会再重新启动一个进程,这就实现了重启功能。把他应用于博客系统,既能充当守护进程,也能在每次升级博客系统时自动重启。代码如下:
var fs = require('fs'); var files = [ 'routes', 'routes/blog', 'common', 'models', 'app.js' ];//被监视的文件列表 var stamps = {};//被监视文件的时间戳 var change = []; var child = null; function startServer() { var spawn = require('child_process').spawn; child = spawn('node', ['./bin/www']); child.stdout.on('data', function (data) { console.log(data.toString()); }); child.stderr.on('data', function (data) { console.log(data.toString()); }); child.on('exit', function (code) { console.log('子进程已关闭'); child = startServer(); }); child.on('error', function(code, signal){ child.kill(signal); }); return child; } startServer(); ///* setInterval(function () { change = []; for (var i = files.length - 1; i >= 0; i--) { var stat = fs.statSync(files[i]);//读取文件信息 var t = + new Date(stat.mtime);//mtime是修改时间 if (stamps[files[i]] && t > stamps[files[i]]) { change.push(files[i]); } stamps[files[i]] = t; } if (change.length) { console.log("重启"); child.kill(); } }, 2000);