首页 文章

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

提问于
浏览
344

关于如何在Node.js中实现文件自动重载的任何想法?我'm tired of restarting the server every time I change a file. Apparently 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全局变量没有任何线索 .

24 回答

  • 0

    nodemon在google搜索中首先出现,似乎可以解决这个问题:

    npm install nodemon -g
    cd whatever_dir_holds_my_app
    nodemon app.js
    
  • 393

    没必要使用nodemon或其他类似的工具 . 只需使用IDE的功能 .

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

  • 8

    您可以安装Node-Supervisor

    npm install supervisor
    

    http://github.com/isaacs/node-supervisor

  • 2

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

    请注意,您必须自己照顾所使用的参考文献 .

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

    这意味着你必须替换存储在x,y和z中的引用 . 在热的reaload回调函数中 .

    有些人混淆热重载和自动重启我的nodejs-autorestart模块也有upstart集成以启用启动时自动启动 . 如果你有一个小应用程序自动重启很好,但是当你有一个大的应用程序热重新加载更合适 . 仅仅因为热重载更快 .

    我也喜欢我的节点流入模块 .

  • 0

    我最近提出这个问题,因为通常的嫌疑人没有使用链接包 . 如果你像我一样在开发过程中利用 npm link 来有效地处理由许多软件包组成的项目,那么依赖项中发生的更改也会引发重新加载 .

    在尝试了node-mon和pm2后,即使按照他们的指示进行额外观察node_modules文件夹,他们仍然没有接收到更改 . 虽然这里的答案中有一些自定义解决方案,但对于类似的东西,单独的包更清洁 . 我今天遇到了node-dev它完美无缺,没有任何选项或配置 .

    从自述文件:

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

  • 0

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

  • 0

    这是一种在Windows中使用的低技术方法 . 把它放在一个名为 serve.bat 的批处理文件中:

    @echo off
    
    :serve
    start /wait node.exe %*
    goto :serve
    

    现在,不要从cmd shell运行 node app.js ,而是运行 serve app.js .

    这将打开一个运行服务器的新shell窗口 . 批处理文件将阻塞(因为 /wait ),直到您关闭shell窗口,此时原始cmd shell将询问"Terminate batch job (Y/N)?"如果您回答"N",则服务器将重新启动 .

    每次要重新启动服务器时,请关闭服务器窗口并在cmd shell中回答“N” .

  • 0

    node-supervisor太棒了

    用于在保存时重启:

    npm install supervisor -g
    supervisor app.js
    

    by isaacs - http://github.com/isaacs/node-supervisor

  • 1

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

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

    要使用 nodemon

    $ npm install nodemon -g
    $ nodemon app.js
    
  • 1

    您可以使用自动重新加载来重新加载模块而无需关闭服务器 .

    安装

    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' }
    
  • 299

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

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

    如果有人仍然提出这个问题,并希望仅使用标准模块来解决它,我做了一个简单的例子:

    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而制作的,它不适合某些特定需求,但可以在一些简单的应用程序中使用 .

    更新:此功能在我的模块simpleRGitHub repo中实现

  • 3

    Here是一篇关于Hot Reloading for Node的博客文章 . 它提供了github Node branch,您可以使用它来替换您的Node安装以启用热重新加载 .

    来自博客:

    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 . 任何现有请求将继续使用旧代码,而任何新传入请求将使用新代码 . 所有这些都没有关闭服务器,弹出任何请求,过早地杀死任何请求,甚至依赖智能负载均衡器 .

  • 0

    对于使用Vagrant和PHPStorm的人来说,file watcher是一种更快的方法

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

    vagrant 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
    
  • 14

    我正在努力制作一个相当小的节点“东西”,能够随意加载/卸载模块(因此,你可以重新启动部分应用程序,而无需关闭整个应用程序) . 我正在整合一个(非常愚蠢的)依赖管理,所以如果你想停止一个模块,所有依赖于它的模块也将被停止 .

    到目前为止一直很好,但后来我偶然发现了如何重新加载模块的问题 . 显然,可以从"require"缓存中删除该模块并完成工作 . 由于我不想直接更改节点源代码,我想出了一个非常hacky-hack,即:在堆栈中搜索跟踪最后一次调用"require"函数,获取对它的"cache"字段的引用和..well ,删除对节点的引用:
    var args = arguments
    while(!args ['1'] ||!args ['1'] . cache)
    var cache = args ['1'] . cache
    util.log('删除缓存'moduleFullpathAndExt)
    删除(cache [moduleFullpathAndExt])
    实际上更容易:

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

    显然,这很好用 . 我完全不知道那些论点["1"]意味着什么,但它正在做它的工作 . 我相信节点人员有一天会实施重装工具,所以我想现在这个解决方案也是可以接受的 . (顺便说一句 . 我的"thing"将会在这里:https://github.com/cheng81/wirez,过几个星期去那里,你应该看看我在说什么)

  • 18

    loaddir是我以递归方式快速加载目录的解决方案 .

    可以回来

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

    它有 callback ,将在文件更改时调用 .

    它处理文件足够大的情况,以便在完成写入之前调用 watch .

    我在项目中使用它已经有一年左右的时间了,而且最近才增加了对它的承诺 .

    帮我战斗吧!

    https://github.com/danschumann/loaddir

  • -1

    另一个简单的解决方案是 use fs.readFile instead of using require 你可以保存一个包含json对象的文本文件,并在服务器上创建一个间隔来重新加载这个对象 .

    优点:

    • 无需使用外部库

    • 与 生产环境 相关(在更改时重新加载配置文件)

    • 易于实施

    缺点:

    • 你无法重新加载模块 - 只是一个包含键值数据的json
  • 1

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

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

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

    node-dev app.js

  • 3

    您可以使用 NPM 中的 nodemon . 如果您使用的是Express Generator,那么您可以在项目文件夹中使用此命令:

    nodemon npm start
    

    或使用调试模式

    DEBUG=yourapp:* nodemon npm start
    

    希望这有帮助 .

  • 0

    Edit: 我的回答已经过时了 . Node.js是一种快速变化的技术 .

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

    require(url, reload)
    

    要在当前目录中重新加载 app.js ,请使用

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

    写这样的东西,你有 auto -reload:

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

    我看到的唯一问题是变量 module ,但我现在正在努力 .

  • 0

    这个问题的另一个解决方案是使用forever

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

    forever -w start server.js
    
  • 4

    nodemon 很棒 . 我只是为调试和观看选项添加了更多参数 .

    的package.json

    "scripts": {
        "dev": "cross-env NODE_ENV=development nodemon --watch server/**/*.js --inspect ./server/server.js"
      }
    

    nodemon --watch server/**/*.js --inspect ./server/server.js

    鉴于:

    --watch server/**/*.js 仅在更改 server 文件夹中的.js文件时重新启动服务器 .

    --inspect 启用远程调试 .

    ./server/server.js 切入点 .

    然后将以下配置添加到 launch.json (VS代码)并随时开始调试 .

    {
        "type": "node",
        "request": "attach",
        "name": "Attach",
        "protocol": "inspector",
        "port": 9229
    }
    

    请注意,最好将 nodemon 安装为项目的dev依赖项 . 所以你的团队成员不需要安装它或记住命令参数,它们只是 npm run dev 并开始黑客攻击 .

  • 78

    现在使用具有热选项的WebPack开发服务器 . 你可以在package.json中添加这样的脚本: "hot": "cross-env NODE_ENV=development webpack-dev-server --hot --inline --watch-poll",

    并且文件中的每个更改都将自动触发重新编译

  • 5

    用这个:

    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会自动重新加载:)

相关问题