My first question is : Who is responsible to handle require
statements in a Nodejs application ? is it Node itself ? or CommonJS ? or RequireJS ? Is CommonJS included in Node ? what about RequireJS?
Now my second question :
I have an if-else statement , which decides if we are rendering on server side or client side. I want to load different libraries when it's rendering on client side or server side. Is it possible to load the modules in runtime ? exactly at the moment it's required ?
if (typeof window === undefined){
var serverSideLibrary = require('A');
//....
}else{
var clientSideLibrary = require('B');
}
It looks like Node loads everything required before starting the application. So it's not important if you require it at the top of the code or in that if-else block.
In Node.js, Node itself handles require
. And you're mistaken—a require
is not evaluated until the program's evaluation reaches it. If you have this code:
var mod;
setInterval(function() {
if (true) {
mod = require("a");
} else {
mod = require("b");
}
}, 5000);
...you can be sure of two things: 1. Module b
will never be loaded, and 2. Module a
won't be loaded until five seconds have elapsed.
In the browser, require
is only defined if you use a library that defines it, like RequireJS, Browserify or Webpack. In general these tools stay close to Node's behavior: While the browser might download all of the code at once (especially if you have a build step that puts all of your modules into a single file), they will wrap each module in a function so that it won't actually be evaluated until it's require
d.
If you want to load different modules depending on whether your code is running on the client or the server, I would recommend doing this in your build step—most build tools, like those mentioned above, have this functionality or it's available as a plugin—instead of just an if
statement, because with the if
statement you're still making the browser download code it's never going to use.
Override the .js
file extension to hide .js
files from the directory loop which happens by default when require
is called, and create custom methods which programmatically call require on demand:
var fs = require('fs'),
IonicAppLib = module.exports,
path = require('path');
var camelCase = function camelCase(input) {
return input.toLowerCase().replace(/-(.)/g, function(match, group1) {
return group1.toUpperCase();
});
};
//
// Setup all modules as lazy-loaded getters.
//
fs.readdirSync(path.join(__dirname, 'lib')).forEach(function (file) {
file = file.replace('.js', '');
var command;
if (file.indexOf('-') > 0) {
// console.log('file', file);
command = camelCase(file);
} else {
command = file;
}
IonicAppLib.__defineGetter__(command, function () {
return require('./lib/' + file);
});
});
IonicAppLib.__defineGetter__('semver', function () {
return require('semver');
});
which wraps the accessor for the variable assigned to the require
call:
var IonicAppLib = require('ionic-app-lib');
References
Lazy loading your node modules - Josh Bavari's Ramblings
nodejs module.require and require
Auto require a directory in Node.js (Example)
Modules: Exports Shortcut | Node.js v7.10.0 Documentation
node/module.js at master · nodejs/node · GitHub
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With