[javascript] How to auto-reload files in Node.js?

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.

This question is related to javascript node.js

The answer is


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

Edit: My answer is obsolete. Node.js is a very fast changing technology.

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.


You can do it with browser-refresh. Your node app restarts automatically, your result page in browser also refreshes automatically. Downside is that you have to put js snippet on generated page. Here's the repo for the working example.

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}/` })
    }

});

Nowadays WebPack dev server with hot option is used. you can add a script like this in your package.json : "hot": "cross-env NODE_ENV=development webpack-dev-server --hot --inline --watch-poll",

and every change in your files will trigger a recompile automatically


yet another solution for this problem is using forever

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:

forever -w start server.js

i found a simple way:

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

node-dev works great. npm install node-dev

It even gives a desktop notification when the server is reloaded and will give success or errors on the message.

start your app on command line with:

node-dev app.js


You can use auto-reload to reload the module without shutdown the server.

install

npm install auto-reload

example

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

Result:

{ 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 is my solution for quick loading of a directory, recursively.

can return

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

It has callback which will be called when the file is changed.

It handles situations where files are large enough that watch gets called before they're done writing.

I've been using it in projects for a year or so, and just recently added promises to it.

Help me battle test it!

https://github.com/danschumann/loaddir


Not necessary to use nodemon or other tools like that. Just use capabilities of your IDE.

Probably best one is IntelliJ WebStorm with hot reload feature (automatic server and browser reload) for node.js.


There is Node-Supervisor that you can install by

npm install supervisor

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


another simple solution is to use fs.readFile instead of using require you can save a text file contaning a json object, and create a interval on the server to reload this object.

pros:

  • no need to use external libs
  • relevant for production (reloading config file on change)
  • easy to implement

cons:

  • you can't reload a module - just a json containing key-value data

my app structure:

NodeAPP (folder)
   |-- app (folder)
      |-- all other file is here
   |-- node_modules (folder)
   |-- package.json
   |-- server.js (my server file)

first install reload with this command:

npm install [-g] [--save-dev] reload

then change package.json:

"scripts": {
    "start": "nodemon -e css,ejs,js,json --watch app"
}

now you must use reload in your server file:

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

and for last change, end of your response send this script:

<script src="/reload/reload.js"></script>

now start your app with this code:

npm start

I recently came to this question because the usual suspects were not working with linked packages. If you're like me and are taking advantage of npm link during development to effectively work on a project that is made up of many packages, it's important that changes that occur in dependencies trigger a reload as well.

After having tried node-mon and pm2, even following their instructions for additionally watching the node_modules folder, they still did not pick up changes. Although there are some custom solutions in the answers here, for something like this, a separate package is cleaner. I came across node-dev today and it works perfectly without any options or configuration.

From the Readme:

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.


node-supervisor is awesome

usage to restart on save:

npm install supervisor -g
supervisor app.js

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


If somebody still comes to this question and wants to solve it using only the standard modules I made a simple example:

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

This example is only for one file (server.js), but can be adapted to multiple files using an array of files, a for loop to get all file names, or by watching a directory:

fs.watch('./', function (event, filename) { // sub directory changes are not seen
    console.log(`restart server`);
    server.kill();
    server = cp.fork('server.js');    
})

This code was made for Node.js 0.8 API, it is not adapted for some specific needs but will work in some simple apps.

UPDATE: This functional is implemented in my module simpleR, GitHub repo


I have tried pm2 : installation is easy and easy to use too; the result is satisfying. However, we have to take care of which edition of pm2 that we want. pm 2 runtime is the free edition, whereas pm2 plus and pm2 enterprise are not free.

As for Strongloop, my installation failed or was not complete, so I couldn't use it.


I am working on making a rather tiny node "thing" that is able to load/unload modules at-will (so, i.e. you could be able to restart part of your application without bringing the whole app down). I am incorporating a (very stupid) dependency management, so that if you want to stop a module, all the modules that depends on that will be stopped too.

So far so good, but then I stumbled into the issue of how to reload a module. Apparently, one could just remove the module from the "require" cache and have the job done. Since I'm not keen to change directly the node source code, I came up with a very hacky-hack that is: search in the stack trace the last call to the "require" function, grab a reference to it's "cache" field and..well, delete the reference to the node:

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

Even easier, actually:

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

Apparently, this works just fine. I have absolutely no idea of what that arguments["1"] means, but it's doing its job. I believe that the node guys will implement a reload facility someday, so I guess that for now this solution is acceptable too. (btw. my "thing" will be here: https://github.com/cheng81/wirez , go there in a couple of weeks and you should see what I'm talking about)


You can use nodemon from NPM. And if you are using Express generator then you can using this command inside your project folder:

nodemon npm start

or using Debug mode

DEBUG=yourapp:* nodemon npm start

you can also run directly

nodemon your-app-file.js

Hope this help.


nodemon came up first in a google search, and it seems to do the trick:

npm install nodemon -g
cd whatever_dir_holds_my_app
nodemon app.js

Here's a low tech method for use in Windows. Put this in a batch file called serve.bat:

@echo off

:serve
start /wait node.exe %*
goto :serve

Now instead of running node app.js from your cmd shell, run serve app.js.

This will open a new shell window running the server. The batch file will block (because of the /wait) until you close the shell window, at which point the original cmd shell will ask "Terminate batch job (Y/N)?" If you answer "N" then the server will be relaunched.

Each time you want to restart the server, close the server window and answer "N" in the cmd shell.


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.


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.


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.


Use this:

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

All you have to do now is:

var config = reload_config("./config");

And config will automatically get reloaded :)


nodemon is a great one. I just add more parameters for debugging and watching options.

package.json

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

The command: nodemon --watch server --inspect ./server/server.js

Whereas:

--watch server Restart the app when changing .js, .mjs, .coffee, .litcoffee, and .json files in the server folder (included subfolders).

--inspect Enable remote debug.

./server/server.js The entry point.

Then add the following config to launch.json (VS Code) and start debugging anytime.

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

Note that it's better to install nodemon as dev dependency of project. So your team members don't need to install it or remember the command arguments, they just npm run dev and start hacking.

See more on nodemon docs: https://github.com/remy/nodemon#monitoring-multiple-directories


For people using Vagrant and PHPStorm, file watcher is a faster approach

  • disable immediate sync of the files so you run the command only on save then create a scope for the *.js files and working directories and add this command

    vagrant ssh -c "/var/www/gadelkareem.com/forever.sh restart"

where forever.sh is like

#!/bin/bash

cd /var/www/gadelkareem.com/ && forever $1 -l /var/www/gadelkareem.com/.tmp/log/forever.log -a app.js