How to auto-reload files in Node.js?
关于如何在Node.js中实现文件自动重载的任何想法? 每次更改文件时,我都厌倦了重启服务器。
显然Node.js'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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文件中我有:
1 2 3 4 | var file = require('./file'); this.app = function(req, res) { file.serveFile( req, res, 'file.js'); } |
但是这也没有用 - 我在
Monitor for any changes in your node.js application and automatically restart the server - perfect for development
要使用
1 2 | $ npm install nodemon -g $ nodemon app.js |
node-supervisor太棒了
用于在保存时重启:
1 2 | npm install supervisor -g supervisor app.js |
by isaacs - http://github.com/isaacs/node-supervisor
我找到了一个简单的方法:
1 | delete require.cache['/home/shimin/test2.js'] |
nodemon在google搜索中首先出现,似乎可以解决这个问题:
1 2 3 | npm install nodemon -g cd whatever_dir_holds_my_app nodemon app.js |
如果有人仍然只是使用标准模块来解决这个问题我做了一个简单的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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循环获取所有文件名,或者通过查看目录:
1 2 3 4 5 | 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编写的,它不适合某些特定需求,但可以在一些简单的应用程序中使用。
更新:
这个功能在我的模块simpleR,GitHub repo中实现
您可以安装Node-Supervisor
1 | npm install supervisor |
请参阅http://github.com/isaacs/node-supervisor
编辑:我的答案已经过时了。 Node.js是一种快速变化的技术。
我也想知道重装模块。 我修改了node.js,并在nalply / node的Github上发布了源代码。 唯一的区别是函数
1 | require(url, reload) |
要在当前目录中重新加载
1 | app = require("./app", true); |
写这样的东西,你有自动重新加载:
1 2 3 | process.watchFile(script_name, function(curr, prev) { module = reload(script_name, true); }); |
我看到的唯一问题是变量
这个问题的另一个解决方案是永远使用
Another useful capability of Forever is that it can optionally restart
your application when any source files have changed. This frees you
from having to manually restart each time you add a feature or fix a
bug. To start Forever in this mode, use the -w flag:
1 | forever -w start server.js |
的package.json
1 2 3 | "scripts": { "dev":"cross-env NODE_ENV=development nodemon --watch server --inspect ./server/server.js" } |
命令:
鉴于:
然后将以下配置添加到
1 2 3 4 5 6 7 | { "type":"node", "request":"attach", "name":"Attach", "protocol":"inspector", "port": 9229 } |
请注意,最好将
有关
在node.js邮件列表上有一个关于这个主题的最新帖子。 简短的回答是否定的,目前不可能自动重新加载所需的文件,但有几个人开发了添加此功能的补丁。
node-dev工作得很好。 npm
它甚至会在重新加载服务器时发出桌面通知,并会在消息上显示成功或错误。
在命令行上启动您的应用程序:
我正在努力制作一个相当小的节点"东西",它能够随意加载/卸载模块(因此,你可以重新启动部分应用程序,而无需关闭整个应用程序)。
我正在合并一个(非常愚蠢的)依赖管理,所以如果你想停止一个模块,所有依赖于它的模块也将被停止。
到目前为止一切顺利,但后来我偶然发现了如何重新加载模块的问题。显然,可以从"require"缓存中删除模块并完成工作。由于我不想直接更改节点源代码,我想出了一个非常hacky-hack,即:在堆栈中搜索最后一次调用"require"函数,获取对它的"cache"字段的引用and..well,删除对节点的引用:
<击>
1 2 3 4 5 6 7 | 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 ] ) |
击>
实际上更容易:
1 2 3 | var deleteCache = function(moduleFullpathAndExt) { delete( require.cache[ moduleFullpathAndExt ] ) } |
显然,这很好用。我完全不知道那些论点["1"]意味着什么,但它正在做它的工作。我相信节点人员有一天会实现重装设备,所以我想现在这个解决方案也是可以接受的。
(顺便说一句。我的"事情"将在这里:https://github.com/cheng81/wirez,几周后去那里,你应该看看我在说什么)
您可以使用NPM中的nodemon。
如果您使用Express生成器,那么您可以在项目文件夹中使用此命令:
1 | nodemon npm start |
或使用调试模式
1 | DEBUG=yourapp:* nodemon npm start |
你也可以直接跑
1 | nodemon your-app-file.js |
希望这有帮助。
这是一篇关于Hot Reloading for Node的博客文章。 它提供了一个github Node分支,您可以使用它来替换Node的安装以启用Hot Reloading。
来自博客:
1 2 3 4 5 6 7 8 9 10 11 12 | 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); |
Now, any time you modify myRequestHandler.js, the above code will no-tice and re-place the local re-questHandler with the new code. Any ex-ist-ing re-quests will con-tin-ue to use the old code, while any new in-com-ing re-quests will use the new code. All with-out shut-ting down the serv-er, bounc-ing any re-quests, pre-ma-ture-ly killing any re-quests, or even re-ly-ing on an in-tel-li-gent load bal-ancer.
没必要使用nodemon或其他类似的工具。 只需使用IDE的功能。
可能最好的一个是IntelliJ WebStorm,它具有node.js的热重载功能(自动服务器和浏览器重新加载)。
解决方案:
http://github.com/shimondoodkin/node-hot-reload
请注意,您必须自己照顾所使用的参考文献。
这意味着如果你这样做:var x = require('foo');Y = X; Z= x.bar; 和热重新加载
它。
这意味着你必须替换存储在x,y和z中的引用。 在热的reaload回调函数中。
有些人将热重载与自动重启混淆
我的nodejs-autorestart模块还具有upstart集成,可以在启动时启用自动启动。
如果你有一个小应用程序自动重启是好的,但是当你有一个大的应用程序热重新加载更合适。 仅仅因为热重载更快。
我也喜欢我的节点流入模块。
这是一种在Windows中使用的低技术方法。 将其放在名为
1 2 3 4 5 | @echo off :serve start /wait node.exe %* goto :serve |
现在,不要从cmd shell运行
这将打开一个运行服务器的新shell窗口。 批处理文件将阻塞(因为
每次要重新启动服务器时,请关闭服务器窗口并在cmd shell中回答"N"。
我的app结构:
1 2 3 4 5 6 | NodeAPP (folder) |-- app (folder) |-- all other file is here |-- node_modules (folder) |-- package.json |-- server.js (my server file) |
首先使用此命令重新加载:
1 | npm install [-g] [--save-dev] reload |
然后改变package.json:
1 2 3 | "scripts": { "start":"nodemon -e css,ejs,js,json --watch app" } |
现在你必须在服务器文件中使用reload:
1 2 3 4 5 6 7 8 9 10 11 | 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); |
对于最后一次更改,您的响应结束发送此脚本:
1 | <script src="/reload/reload.js"> |
现在使用以下代码启动您的应用:
1 | npm start |
您可以使用自动重新加载来重新加载模块而无需关闭服务器。
安装
1 | npm install auto-reload |
例
data.json
1 | {"name" :"Alan" } |
test.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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); |
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | { 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' } |
loaddir是我以递归方式快速加载目录的解决方案。
可以回来
要么
它有
它处理文件足够大以至于
我在项目中使用它已经有一年左右的时间了,最近又添加了许可证。
帮我战斗吧!
https://github.com/danschumann/loaddir
1 2 3 4 5 6 7 8 9 10 11 12 | 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; }; |
另一个简单的解决方案是使用fs.readFile而不是使用require
您可以保存包含json对象的文本文件,并在服务器上创建一个间隔来重新加载此对象。
优点:
- 无需使用外部库
- 与生产相关(在更改时重新加载配置文件)
- 易于实施
缺点:
- 你不能重新加载一个模块 - 只是一个包含键值数据的json
对于使用Vagrant和PHPStorm的人来说,文件观察器是一种更快的方法
-
禁用文件的立即同步,以便仅在保存时运行命令,然后为* .js文件和工作目录创建范围并添加此命令
vagrant ssh -c"/var/www/gadelkareem.com/forever.sh restart"
forever.sh就像
1 2 3 | #!/bin/bash cd /var/www/gadelkareem.com/ && forever $1 -l /var/www/gadelkareem.com/.tmp/log/forever.log -a app.js |
我最近提出这个问题,因为通常的嫌疑人没有使用链接包。 如果你像我一样,并且在开发过程中利用
在尝试了node-mon和pm2之后,即使按照他们的指示进行额外观察node_modules文件夹,他们仍然没有接收到更改。 虽然这里的答案中有一些自定义解决方案,但对于类似的东西,单独的包更清洁。 我今天遇到了node-dev,它完美无缺,没有任何选项或配置。
从自述文件:
In contrast to tools like supervisor or nodemon it doesn't scan the filesystem for files to be watched. Instead it hooks into Node's require() function to watch only the files that have been actually required.
用这个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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)); } |
你现在要做的就是:
1 | var config = reload_config("./config"); |
并且config会自动重新加载:)
现在使用带有热选项的WebPack开发服务器。
你可以在package.json中添加这样的脚本:
并且文件中的每个更改都将自动触发重新编译