简体   繁体   中英

How to update server's content without restarting it? (node.js)

So I have a simple node.js server which serves only dynamic content:

// app.js
var app = require('express')();

app.get('/message/:poster', function(request, response) {
    response.writeHeader(200, {'content-type': 'text/html'});

    // some database queries

    response.end(""+
    "<!DOCTYPE html>"+
    "<html>"+
        "<head>"+
            "<title>messages of "+request.params.poster+"</title>"+
            "<script src='http://example.com/script.js'></script>"+
            "<link rel='stylesheet' href='http://example.com/style.css'>"+
        "</head>"+
        "<body>"+
        "" // and so on
    );
})

app.listen(2345);

Now, suppose I want to update my HTML.
And suppose further that I don't want to restart the server.
Is there a way of achieving this?

I tried exporting the part to send to an external file like:

// lib.js
module.exports.message = function(request, response) {
    response.writeHeader(200, {'content-type': 'text/html'})

    //some database queries

    response.end(""+
    "<!DOCTYPE html>"+
    "<html>"+
        "<head>"+
            "<title>messages of "+request.params.poster+"</title>"+
            "<script src='http://example.com/script.js></script>"+
            "<link rel='stylesheet' href='http://example.com/style.css'>"+
        "</head>"+
        "<body>"+
        "" //and so on
    );
}

and

// app.js
var app = require('express')();

app.get('/message/:poster', require('./lib.js').message)

app.listen(2345);

And it works but if I update lib.js it doesn't update. It seems to be making a copy of that function.
Then I tried

// app.js
var app = require('express')();

app.get('/message/:poster', function(request, response) {
    require('./lib.js').message(request, response);
})

app.listen(2345);

But this doesn't update either.
Seems like the function gets cached and reused all the time(once I start the server). I dare say that there must be a way to set it so that it either revalidates the function each time(checking if the file containing it changed) and if so updates its cache, or we can set it to update the function each n amount of time, or even better, since we're in node, having an event listener for changes to the files containing the function and as the function changes, event fires and the function in cache gets updated.
So how do we get one of the above behaviors? Or something else? I know to restart a server may take only 100ms but restarting it would interrupt all the currently active websockets, which is not an option.
NOTE: I don't want to use any templating languages like jade, ejc etc.

By requiring a module its module.exports is cached for all future calls to require . You can programmatically empty the cache: http://nodejs.org/docs/latest/api/globals.html#globals_require_cache . If you additionally want to do it upon a file change you can use fs.watch : http://nodejs.org/api/fs.html#fs_fs_watch_filename_options_listener .

If you dont want to loose any request in production - just gracefull restart your app using PM2, Forever, etc. If you want to automatic apply your changes in development - use Nodemon. I dont know any other reason why you dont like to restart app.

Exporting the content to other module seems like a good way to tackle this requirement. But the problem is: modules are only instantiated once and cached for later requests, that's why when you update the lib.js it doesn't reflect the updated content.

What are you looking for is a way for hot loading node.js modules to get a fresh instance of the module every time it changes. You can use node-hotswap

require('hotswap');

and for any module you want to track the changes:

module.change_code = 1;

could you not just use the read/write API for nodejs?

http://nodejs.org/api/fs.html

Request->ReadFile->Send Content to client

At least for static content as html.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM