I'm fairly new to Node.js and am having trouble understanding the way to go about loading libraries or files, in runtime. Apparently, it is a bad idea to load files in runtime using Node.js's native "require" function because it is blocking i/o, and therefore should not be used from within request handlers. So, I'm assuming something like this is to be avoided:
var http = require('http').createServer(function(req, res) {
var file = require('./pages/'+req.url);
res.end();
}).listen(8080);
So then is there a way to require files in runtime, in a non-blocking/asynchronous way?
I don't think it would always be possible to load files in "boot time" rather than runtime because like in the example above, the only way to know what file to load/require is by getting the name through the req.url
property.
So that seems like the only option. Unless, all the files in the folder are preloaded and then called upon by name, in the callback (By using fs.readdirSync
or something to iterate through all the files in the folder and pare the gotten files' names to the req.url
property), but that seems wasteful. "Preloading" all the files in the folder (maybe around 50 files) and then only using 1 of them, doesn't seem like a good idea. Am I wrong?
Either way, I would just like to know if there is a way to require files in runtime in a better, non-blocking/asynchronous way.
Thank you!
I'm fairly new to Node.js and am having trouble understanding the way to go about loading libraries or files, in runtime. Apparently, it is a bad idea to load files in runtime using Node.js's native "require" function because it is blocking i/o, and therefore should not be used from within request handlers. So, I'm assuming something like this is to be avoided:
var http = require('http').createServer(function(req, res) {
var file = require('./pages/'+req.url);
res.end();
}).listen(8080);
So then is there a way to require files in runtime, in a non-blocking/asynchronous way?
I don't think it would always be possible to load files in "boot time" rather than runtime because like in the example above, the only way to know what file to load/require is by getting the name through the req.url
property.
So that seems like the only option. Unless, all the files in the folder are preloaded and then called upon by name, in the callback (By using fs.readdirSync
or something to iterate through all the files in the folder and pare the gotten files' names to the req.url
property), but that seems wasteful. "Preloading" all the files in the folder (maybe around 50 files) and then only using 1 of them, doesn't seem like a good idea. Am I wrong?
Either way, I would just like to know if there is a way to require files in runtime in a better, non-blocking/asynchronous way.
Thank you!
Share Improve this question asked Sep 14, 2013 at 19:18 user2779891user2779891 331 silver badge3 bronze badges1 Answer
Reset to default 7The function require()
is generally used for caching modules or configuration files before most of your application runs. You can think of using require()
somewhat like this:
var file = fs.readFileSync('/path');
// depending on the file type
eval(file);
JSON.parse(file);
The reason it is done this way is so that dependencies are loaded in order. If you want to read a file after initializing the application, you should use a asynchronous read, and respond in the callback like this:
var http = require('http');
http.createServer(function(req, res) {
fs.readFile('./pages/' + req.url, function(err, data) {
res.end(data);
});
}).listen(8080);
If you needed to check if a file existed, then you could use fs.stat()
to check the existence of a file, rather than querying the directory.
var http = require('http');
http.createServer(function(req, res) {
var file = './pages/' + req.url;
fs.stat(file, (err, stats) {
if (err || !stats.isFile()) {
res.writeHead(404);
res.send();
return;
}
fs.readFile(file, function(err, data) {
res.writeHead(200);
res.end(data);
});
});
}).listen(8080);