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

IT技术 javascript node.js
2021-02-10 16:34:15

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

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 全局变量一无所知。

6个回答

一个好的、最新的替代方案supervisornodemon

监视 node.js 应用程序中的任何更改并自动重新启动服务器 - 非常适合开发

nodemon与不带npx(v8.1 及以下,不建议)的 Node 版本一起使用

$ npm install nodemon -g
$ nodemon app.js

或者nodemonnpx捆绑在 (v8.2+) 中的 Node 版本一起使用

$ npm install nodemon
$ npx nodemon app.js

或者使用 package.json 中的 npm 脚本作为 devDependency:

"scripts": {
  "start": "nodemon app.js"
},
"devDependencies": {
  "nodemon": "..."
}
用于npm install [--save-dev | -D] nodemon将安装限制在项目范围内。
2021-03-20 16:34:15
这只会重新启动服务器,仍然需要手动重新加载 Web 客户端。
2021-03-31 16:34:15
如果你想在Nitrous.io 中使用它—— $ nodemon -L yourfile.js(在coderwall.com/p/aqxl_q 上有完整的解释
2021-04-05 16:34:15
automatically restart the server - perfect for development太夸张了。重新加载服务器可能意味着登录后端服务,这在我的情况下需要很长时间。“完美的开发”类似于热重载类,而进程在内存中运行时不会丢失状态,就像更改源代码时 android studio 所做的那样。
2021-04-09 16:34:15
但在这种情况下,它也会重新启动服务器进程。
2021-04-12 16:34:15

节点主管很棒

用于在保存旧 Node 版本时重新启动(不建议):

npm install supervisor -g
supervisor app.js

用于重新启动保存的 Node 版本npx

npm install supervisor
npx supervisor app.js

或直接调用supervisornpm 脚本:

"scripts": {
  "start": "supervisor app.js"
}
不得不在 Windows 下像这样运行它: "C:\Program Files\nodejs\node.exe" C:\Users\Mark\AppData\Roaming\npm\node_modules\supervisor\lib\cli-wrapper.js app.js
2021-03-15 16:34:15
@Mark 这意味着节点不在您的 PATH
2021-03-21 16:34:15
在 OSx 10.2.8 上,我必须使用 sudo 运行它
2021-04-05 16:34:15
npm install -g 主管。它应该全局安装。
2021-04-07 16:34:15
在应用程序根目录下没有 -g 或 sudo : npm install supervisor, node node_modules/supervisor/lib/cli-wrapper.js app.js(我有一个非 root 安装的节点)
2021-04-11 16:34:15

我找到了一个简单的方法:

delete require.cache['/home/shimin/test2.js']
@jocull 我认为它不安全,因为它可能会重新创建类和函数或任何导出,导致在与 ===
2021-03-13 16:34:15
delete require.cache[require.resolve('./mymodule.js')]; 解决处理真实路径
2021-03-17 16:34:15
如果您想在不重新启动应用程序的情况下重新加载外部库(在我的情况下是 IRC 机器人),这非常棒。
2021-03-19 16:34:15
这太棒了!如此简单,而且效果很好。每当一个请求进来时,我只是取消缓存一堆不保持状态的文件。
2021-03-26 16:34:15
这样做是否安全或被视为“不良做法”或“仅开发”?
2021-04-10 16:34:15

如果有人仍然遇到这个问题并且只想使用标准module来解决它,我做了一个简单的例子:

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 编写的,它不适用于某些特定需求,但可以在一些简单的应用程序中使用。

更新:这个功能是在我的modulesimpleR 中实现的GitHub repo

这是一个伟大而简单的解决方案。我只是将它用于一个应该在主持人告知时从 git 更新自身的机器人。问题是一旦你进入应用程序,你就无法重新启动自己。但是,我可以使用您的方法生成机器人的实例并查看点文件。然后机器人会自我更新,接触 dotfile,并将由启动器自动重新启动。惊人的!
2021-03-30 16:34:15
如果watch不需要文件,可以fs通过侦听不同的信号来完成重新加载
2021-04-06 16:34:15
@Fred 我很高兴听到这个 :) 我将在一个module中实现这个解决方案,很快我猜,我有更多的想法如何扩展它的功能
2021-04-08 16:34:15

nodemon首先出现在谷歌搜索中,它似乎可以解决问题:

npm install nodemon -g
cd whatever_dir_holds_my_app
nodemon app.js