如何在Node.js中自动重新加载文件?

编辑:使用http://github.com/isaacs/node-supervisor ; 这是一个老问题,代码示例是使用过时的Node.js API制作的。

关于如何在Node.js中实现文件的自动重装的任何想法? 我厌倦了每次更改文件时重新启动服务器。 显然Node.js的require()函数不会重新加载文件,如果他们已经被要求,所以我需要做这样的事情:

 var sys = require('sys'), http = require('http'), posix = require('posix'), json = require('./json'); var script_name = '/some/path/to/app.js'; this.app = require('./app').app; process.watchFile(script_name, function(curr, prev){ posix.cat(script_name).addCallback(function(content){ process.compile( content, script_name ); }); }); http.createServer(this.app).listen( 8080 ); 

app.js文件中我有:

 var file = require('./file'); this.app = function(req, res) { file.serveFile( req, res, 'file.js'); } 

但是这也是行不通的 – 我在process.compile()语句中得到一个错误,说'require'没有被定义。 process.compile正在评估app.js ,但是并不知道node.js全局variables。

一个好的,最新的supervisor替代者是nodemon

监控node.js应用程序中的任何更改,并自动重新启动服务器 – 完美的开发

要使用nodemon

 $ npm install nodemon -g $ nodemon app.js 

节点监督员真棒

用法重新开始保存:

 npm安装主pipe-g
主pipeapp.js

由艾萨克斯 – http://github.com/isaacs/node-supervisor

我发现一个简单的方法:

 delete require.cache['/home/shimin/test2.js'] 

在Googlesearch中, nodemon首先出现了,而且它似乎有诀窍:

 npm install nodemon -g cd whatever_dir_holds_my_app nodemon app.js 

如果有人仍然想到这个问题,只想用标准模块来解决这个问题,我举个简单的例子:

 var process = require('process'); var cp = require('child_process'); var fs = require('fs'); var server = cp.fork('server.js'); console.log('Server started'); fs.watchFile('server.js', function (event, filename) { server.kill(); console.log('Server stopped'); server = cp.fork('server.js'); console.log('Server started'); }); process.on('SIGINT', function () { server.kill(); fs.unwatchFile('server.js'); process.exit(); }); 

此示例仅适用于一个文件(server.js),但可以使用文件数组适应多个文件,使用for循环获取所有文件名或通过观察目录:

 fs.watch('./', function (event, filename) { // sub directory changes are not seen console.log(`restart server`); server.kill(); server = cp.fork('server.js'); }) 

这个代码是为Node.js 0.8 API编写的,它不适用于某些特定的需求,但可以在一些简单的应用程序中工作。

更新:这个function是在我的模块simpleR , GitHub回购实施

有可以安装的Node-Supervisor

 npm install supervisor 

请参阅http://github.com/isaacs/node-supervisor

编辑:我的回答是过时的。 Node.js是一个非常快速的变化技术。

我也想知道重装模块。 我修改了node.js,并在nalply / node上的Github上发布了源代码。 唯一的区别是functionrequire 。 它有一个可选的第二个参数reload

 require(url, reload) 

重新加载当前目录中的app.js使用

 app = require("./app", true); 

写这样的东西,你有自动重新加载:

 process.watchFile(script_name, function(curr, prev) { module = reload(script_name, true); }); 

我看到的唯一的问题是variablesmodule ,但我现在正在工作。

这个问题的另一个解决scheme是永远使用

Forever的另一个有用的function是,当任何源文件发生变化时,它可以select性地重启你的应用程序。 这使您无需在每次添加function或修复错误时手动重新启动。 要在此模式下启动Forever,请使用-w标志:

 forever -w start server.js 

在node.js邮件列表中有一个关于这个主题的最近的线程 。 简短的答案是否定的,它目前不可能自动重新加载所需的文件,但是有几个人开发了添加此function的补丁。

这里是一个关于Hot Reloading for Node的博客文章。 它提供了一个github节点分支 ,您可以使用它来replace您的节点安装以启用热重新加载。

从博客:

 var requestHandler = require('./myRequestHandler'); process.watchFile('./myRequestHandler', function () { module.unCacheModule('./myRequestHandler'); requestHandler = require('./myRequestHandler'); } var reqHandlerClosure = function (req, res) { requestHandler.handle(req, res); } http.createServer(reqHandlerClosure).listen(8000); 

现在,无论何时修改myRequestHandler.js,上面的代码都会注意到并用新的代码replace本地的requestHandler。 任何现有的请求将继续使用旧的代码,而任何新的传入的请求将使用新的代码。 所有这些都不closures服务器,反弹任何请求,过早地杀死任何请求,甚至依靠智能负载平衡器。

我正在制作一个相当小的节点“东西”,它能够随意加载/卸载模块(所以,也就是说,您可以重新启动应用程序的一部分,而不需要closures整个应用程序)。 我正在合并一个(非常愚蠢的)依赖pipe理,所以如果你想停止一个模块,所有依赖它的模块也将被停止。

到目前为止这么好,但后来我偶然发现如何重新加载模块的问题。 显然,可以从“require”caching中删除模块并完成工作。 由于我并不热衷于直接更改节点源代码,所以我提出了一个非常黑客的问题,那就是:在堆栈中search最后一次调用“require”函数,获取对其“cache”字段的引用然后,删除对节点的引用:

  var args = arguments while(!args['1'] || !args['1'].cache) { args = args.callee.caller.arguments } var cache = args['1'].cache util.log('remove cache ' + moduleFullpathAndExt) delete( cache[ moduleFullpathAndExt ] ) 

实际上更容易:

 var deleteCache = function(moduleFullpathAndExt) { delete( require.cache[ moduleFullpathAndExt ] ) } 

显然,这工作得很好。 我完全不知道这个论点[1]是什么意思,但是它正在做它的工作。 我相信节点家伙有一天会实现一个重新加载设施,所以我想现在这个解决scheme也是可以接受的。 (顺便说一句,我的“东西”将在这里: https : //github.com/cheng81/wirez ,在几个星期后去那里,你应该看看我在说什么)

node-dev工作得很好。 npm install node-dev

它甚至会在服务器重新加载时给出桌面通知,并且会在消息上给出成功或错误。

在命令行上启动您的应用程序:

node-dev app.js

解决scheme: http : //github.com/shimondoodkin/node-hot-reload

注意你必须自己照顾使用的参考。

这意味着如果你做了:var x = require('foo'); Y = X; Z = x.bar; 并热重新加载它。

这意味着你必须replace存储在x,y和z中的引用。 在热realoadcallback函数中。

有些人混淆热重新加载和自动重新启动我的nodejs-autorestart模块也具有新贵的整合,以启用启动自动启动。 如果你有一个小应用程序自动重启是好的,但是当你有一个大的应用程序热重载更合适。 只是因为热重新加载更快。

另外我喜欢我的节点stream入模块。

没有必要使用nodemon或其他类似的工具。 只需使用您的IDE的function。

IntelliJ WebStorm可能是最好的一个,它具有node.js的热重载function(自动服务器和浏览器重载)。

用这个:

 function reload_config(file) { if (!(this instanceof reload_config)) return new reload_config(file); var self = this; self.path = path.resolve(file); fs.watchFile(file, function(curr, prev) { delete require.cache[self.path]; _.extend(self, require(file)); }); _.extend(self, require(file)); } 

你现在要做的是:

 var config = reload_config("./config"); 

和configuration将自动重新加载:)

loaddir是我的recursion加载目录的解决scheme。

可以返回

{ 'path/to/file': 'fileContents...' }{ path: { to: { file: 'fileContents'} } }

它有callback ,当文件被改变时会被调用。

它处理文件足够大的情况,以防止在完成写操作之前调用watch

我在一年左右的时间里一直在项目中使用它,最近又增加了许多的承诺。

帮我试战一下吧!

https://github.com/danschumann/loaddir

您可以使用自动重新加载来重新加载模块而不closures服务器。

安装

 npm install auto-reload 

data.json

 { "name" : "Alan" } 

test.js

 var fs = require('fs'); var reload = require('auto-reload'); var data = reload('./data', 3000); // reload every 3 secs // print data every sec setInterval(function() { console.log(data); }, 1000); // update data.json every 3 secs setInterval(function() { var data = '{ "name":"' + Math.random() + '" }'; fs.writeFile('./data.json', data); }, 3000); 

结果:

 { name: 'Alan' } { name: 'Alan' } { name: 'Alan' } { name: 'Alan' } { name: 'Alan' } { name: '0.8272748321760446' } { name: '0.8272748321760446' } { name: '0.8272748321760446' } { name: '0.07935990858823061' } { name: '0.07935990858823061' } { name: '0.07935990858823061' } { name: '0.20851597073487937' } { name: '0.20851597073487937' } { name: '0.20851597073487937' } 

另一个简单的解决scheme是使用fs.readFile而不是使用require,您可以保存包含json对象的文本文件,并在服务器上创build一个间隔来重新加载此对象。

优点:

  • 不需要使用外部库
  • 与生产相关(更改时重新加载configuration文件)
  • 容易实施

缺点:

  • 你不能重新加载模块 – 只是一个包含键值数据的JSON

对于使用Vagrant和PHPStorm的人来说, 文件监视器是一种更快的方法

  • 禁用文件的立即同步,所以你只在保存时运行该命令,然后为* .js文件和工作目录创build一个范围,并添加此命令

    stream浪ssh -c“/var/www/gadelkareem.com/forever.sh restart”

forever.sh就是这样

 #!/bin/bash cd /var/www/gadelkareem.com/ && forever $1 -l /var/www/gadelkareem.com/.tmp/log/forever.log -a app.js 

我最近才想到这个问题,因为通常的嫌疑人并没有使用链接包。 如果您像我一样在开发过程中利用npm link来有效npm link理由多个包组成的项目,则重要的是依赖项中发生的更改也会触发重新加载。

在尝试了node-mon和pm2之后,甚至按照他们的说明来另外观察node_modules文件夹,但他们仍然没有select更改。 虽然在这里有一些自定义的解决scheme,但对于这样的事情,单独的包是更清洁的。 我今天遇到了node-dev ,没有任何选项或configuration,它完美的工作。

从自述文件:

与supervisor或nodemon等工具相比,它不会扫描文件系统以查看要监视的文件。 而是挂钩到Node的require()函数中,只查看实际需要的文件。