views:

1158

answers:

6

Any ideas on how I could implement an auto-reload of files in node.js. I'm tired of restarting the server every time I change a file. Apparently Node.js' require() function does not reload files if they already have been required, so I need to do something like this:

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 );

And in the app.js file I have:

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

But this also isn't working - I get an error in the process.compile() statement saying that 'require' is not defined. process.compile is evaling the app.js, but has no clue about the node.js globals.

+3  A: 

I also wondered about reloading modules. I modified node.js and have published the source at Github at nalply/node. The only difference is the function require. It has an optional second argument reload.

require(url, reload)

To reload app.js in current directory use

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

Write something like this, and you have auto-reload:

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

The only problem I see is the variable module, but I am working at it now.

nalply
+3  A: 

Take a look at require.hot() patch by Felix Geisendörfer. I use it with modified Nerve framework.

Kuroki Kaze
+1 interesting!
nalply
+4  A: 

There was a recent thread about this subject on the node.js mailing list. The short answer is no, it's currently not possible auto-reload required files, but several people have developed patches that add this feature.

Xavi
+1 Yes. I participated in the discussion. I admitted that my solution is too simple. It only works if the hot module itself does not require further modules. Felix' solution is more well thought-out but it is debated if *auto*-reload really belongs to the core.
nalply
+1 Yes. Actually, discussion was started by me :)
Kuroki Kaze
+1  A: 

There is Node-Supervisor that you can install by

npm install supervisor

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

Richard Metzler
It's more about restarting the server if it crashes. node-supervisor also restarts the whole process when watched files have been changed. It is not hot-reload in the strict sense.
nalply
Although not really hot-loading, this tool is really useful if you just want the code to autoreload while you're developing so you don't have to restart node in the command line after every change.
Derek Dahmer
A: 

Here is a blog post about Hot Reloading for Node. It provides a github Node branch that you can use to replace your installation of Node to enable Hot Reloading.

From the blog:

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.

Chetan
The only thing with this solution is that it's a fork of an older version of Node, so it will have to be tweaked and merged with the latest version before using (unless you don't mind using an older version of Node).
Chetan
A: 

solution at: http://github.com/shimondoodkin/node-hot-reload

notice that you have to take care by yourself of the references used.

that means if you did : var x=require('foo'); y=x;z=x.bar; and hot reloaded it.

it means you have to replace the references stored in x, y and z. in the hot reaload callback function.

some people confuse hot reload with auto restart my nodejs-autorestart module also has upstart integration to enable auto start on boot. if you have a small app auto restart is fine, but when you have a large app hot reload is more suitable. simply because hot reload is faster.

Also I like my node-inflow module.

Shimon Doodkin