Javascript 如何在Node.js中自动重新加载文件?
关于如何在Node.js中实现文件的自动重新加载,有什么想法吗?我厌倦了每次更改文件时都重新启动服务器。 显然,Node.js'Javascript 如何在Node.js中自动重新加载文件?,javascript,node.js,Javascript,Node.js,关于如何在Node.js中实现文件的自动重新加载,有什么想法吗?我厌倦了每次更改文件时都重新启动服务器。 显然,Node.js'require()函数不会重新加载已经需要的文件,因此我需要执行如下操作: var sys = require('sys'), http = require('http'), posix = require('posix'), json = require('./json'); var script_name = '/
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全局文件没有任何线索。编辑:我的答案已过时。Node.js是一种变化非常快的技术
我还想知道如何重新加载模块。我修改了node.js,并在Github上发布了源代码。唯一的区别是功能require
。它有一个可选的第二个参数reload
require(url, reload)
要在当前目录中重新加载app.js
,请使用
app = require("./app", true);
写这样的东西,你就有了自动重新加载:
process.watchFile(script_name, function(curr, prev) {
module = reload(script_name, true);
});
我看到的唯一问题是变量模块
,但我现在正在研究它。node.js邮件列表中最近有一个关于这个主题的问题。简短的回答是否定的,目前不可能自动重新加载所需的文件,但有几个人已经开发了添加此功能的修补程序 您可以通过以下方式安装节点管理器
npm install supervisor
请参阅是一篇关于节点热重新加载的博客文章。它提供了一个可用于替换节点安装以启用热重新加载的
从博客:
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,上面的代码都不会出现,并用新代码替换本地RequestHandler。任何请求都将使用旧代码,而任何新请求都将使用新代码。所有这些都不需要关闭服务器,跳转任何请求,预先终止任何请求,甚至使用智能负载平衡器
解决方案地址:
请注意,您必须自己注意所使用的引用
这意味着如果您这样做了:var x=require('foo');y=x;z=x.bar;热装
它
这意味着您必须替换存储在x、y和z中的引用。在热重加载回调函数中
有些人将热重新加载与自动重新启动混为一谈
我的nodejs自动启动模块还具有upstart集成,可以在启动时自动启动。
如果你有一个小应用程序,自动重启是可以的,但当你有一个大应用程序时,热重新加载更合适。只是因为热重新加载速度更快
我也喜欢我的节点流入模块。节点管理器非常棒
保存时重新启动的用法:
npm install supervisor -g
supervisor app.js
npm安装主管-g
supervisor app.js
通过isaacs-我正在制作一个非常小的节点“东西”,可以随意加载/卸载模块(因此,您可以在不关闭整个应用程序的情况下重新启动部分应用程序)。
我合并了一个(非常愚蠢的)依赖关系管理,所以如果你想停止一个模块,所有依赖它的模块也会停止
到目前为止还不错,但后来我偶然发现了如何重新加载模块的问题。显然,可以从“require”缓存中删除模块,然后完成任务。因为我不想直接更改节点源代码,所以我想出了一个非常棘手的方法:在堆栈中搜索跟踪对“require”函数的最后一次调用,获取对其“cache”字段的引用,然后..删除对节点的引用:
更简单的是,实际上:
var deleteCache = function(moduleFullpathAndExt) {
delete( require.cache[ moduleFullpathAndExt ] )
}
显然,这很好用。我完全不知道这个论点[“1”]是什么意思,但它正在发挥作用。我相信节点人员有一天会实现重新加载功能,所以我想现在这个解决方案也是可以接受的。
(顺便说一句,我的“东西”就在这里:,几周后去那里,你应该知道我在说什么)我找到了一个简单的方法:
delete require.cache['/home/shimin/test2.js']
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编写的,它不适合某些特定的需求,但可以在一些简单的应用程序中使用
更新:
此功能在我的模块中实现,一个好的、最新的监管者的替代方案是:
"scripts": {
"start": "nodemon -e css,ejs,js,json --watch app"
}
var express = require('express');
var reload = require('reload');
var app = express();
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function() {
console.log( 'server is running on port ' + app.get('port'));
});
reload(server, app);
<script src="/reload/reload.js"></script>
监视node.js应用程序中的任何更改,并自动重新启动服务器-非常适合开发
要使用nodemon
:
$ npm install nodemon -g
$ nodemon app.js
使用以下命令:
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");
config将自动重新加载:)loaddir是我递归快速加载目录的解决方案
可以返回
{'path/to/file':'fileContents…}
或
{path:{to:{file:'fileContents'}}}
它具有回调
,当文件更改时将调用该回调
它处理的情况是,文件足够大,以至于watch
在完成编写之前被调用
我在项目中使用它已经有一年左右了,最近刚刚给它添加了一些承诺
帮我测试一下
您可以使用自动重新加载来重新加载模块,而无需关闭服务器
安装
例子
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' }
另一个简单的解决方案是使用fs.readFile,而不是使用require
您可以保存包含json对象的文本文件,并在服务器上创建重新加载该对象的间隔
优点:
- 无需使用外部LIB
- 与生产相关(更改时重新加载配置文件)
- 易于实现<
forever -w start server.js
"scripts": {
"dev": "cross-env NODE_ENV=development nodemon --watch server --inspect ./server/server.js"
}
{
"type": "node",
"request": "attach",
"name": "Attach",
"protocol": "inspector",
"port": 9229
}
nodemon npm start
DEBUG=yourapp:* nodemon npm start
nodemon your-app-file.js
@echo off
:serve
start /wait node.exe %*
goto :serve
NodeAPP (folder)
|-- app (folder)
|-- all other file is here
|-- node_modules (folder)
|-- package.json
|-- server.js (my server file)
npm install [-g] [--save-dev] reload
"scripts": {
"start": "nodemon -e css,ejs,js,json --watch app"
}
var express = require('express');
var reload = require('reload');
var app = express();
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function() {
console.log( 'server is running on port ' + app.get('port'));
});
reload(server, app);
<script src="/reload/reload.js"></script>
npm start
const cleanCache = (moduleId) => {
const module = require.cache[moduleId];
if (!module) {
return;
}
// 1. clean parent
if (module.parent) {
module.parent.children.splice(module.parent.children.indexOf(module), 1);
}
// 2. clean self
require.cache[moduleId] = null;
};
const http = require('http');
const hostname = 'localhost';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html; charset=UTF-8');
res.write('Simple refresh!');
res.write(`<script src=${process.env.BROWSER_REFRESH_URL}></script>`);
res.end();
})
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
if (process.send) {
process.send({ event: 'online', url: `http://${hostname}:${port}/` })
}
});