
Node.JS Get rid of require () forever
Analyzing the source codes of past projects, the popularity rating of direct function calls showed that a direct call
In a previous Node.JS article Downloading Modules on DemandI talked about the possibility of automatically loading a module the first time I access its named link. To be honest, at the time of writing that article, I was not sure that this approach would not cause strange behavior of the node process. But, today I can proudly guarantee that it
Today it’s not about stability anymore.
I note in advance, in no case do I agitate to use the proposed method in production. The practice is presented for familiarization and does not claim to be a “true practice”. A loud headline is just to get attention.
Suppose we are working on a project with the name
Create an executable file of our project, for example, at:
Inside we will try to call the connected modules without preliminary
Now create a file
For example, here:
According to the documentation , all the predefined variables and constants of each node module are properties
Fill the
You can present the list of modules in the form of an array or a map (
Now, it remains only to launch this economy. Add the key
There are no errors. The script worked as it should:
If you have many projects, for the convenience of project deployment, you can create your own
Expanding the last case, I note that you can even use several of these
As noted in a comment below , the
Finally, I repeat from the last article: If it is
Otherwise, the one
Thanks for attention. Successful refactoring to everyone!
require()
is found in node-module code almost as often as Array#forEach()
. The most annoying thing is that most often we plug in modules "util"
, "fs"
and "path"
, a little less often "url"
. The presence of other connected modules depends on the task of the module. Moreover, speaking of the module "util"
, it is loaded into the memory of the node process, even if you have never connected it. In a previous Node.JS article Downloading Modules on DemandI talked about the possibility of automatically loading a module the first time I access its named link. To be honest, at the time of writing that article, I was not sure that this approach would not cause strange behavior of the node process. But, today I can proudly guarantee that it
demandLoad()
has been working for half a year in production. As we just did not drive it ... This is a load testing of a specific process, and work demandLoad()
in the worker processes of clusters, and the work of the process under a small load for a long time. Results were compared using demandLoad()
and using require()
. No significant deviations in comparison were observed. Today it’s not about stability anymore.
demandLoad()
. If anyone is interested, ask questions in the comments, take screenshots, I can talk about test methods and tools, other possibilities of using the approach. Today, as follows from the title of the article, we will get rid of those who have already got tired of it require()
in the caps of each node-module. I note in advance, in no case do I agitate to use the proposed method in production. The practice is presented for familiarization and does not claim to be a “true practice”. A loud headline is just to get attention.
Suppose we are working on a project with the name
"mytestsite.com"
, and we have it here:~/projects/mytestsite.com
Create an executable file of our project, for example, at:
~/projects/mytestsite.com/lib/bin/server.js
Inside we will try to call the connected modules without preliminary
require()
:console.log(util.inspect(url.parse('https://habrahabr.ru/')));
Now create a file
"require-all.js"
somewhere, outside of all projects. For example, here:
~/projects/general/require-all.js
According to the documentation , all the predefined variables and constants of each node module are properties
global
. Accordingly, we can define our global objects. So we must do with all the modules we use. Fill the
require-all.js
list of all used modules in all projects:// нет смысла оставлять неподгруженным модуль "util",
// т.к. его все равно до загрузки подгружает модуль "console".
// А console.log(), если ему передать объект единственным параметром,
// в свою очередь вызывает util.inspect()
global.util = require('util');
// так выглядит подключение других стандартных модулей, например:
demandLoad(global, 'fs', 'fs');
demandLoad(global, 'path', 'path');
demandLoad(global, 'url', 'url');
// абсолютно так же выглядит подключение npm-модулей, например:
demandLoad(global, 'express', 'express');
// а, вот, например, так можно подключить локальный модуль:
demandLoad(global, 'routes', './../mytestsite.com/lib/routes');
// определение demandLoad
function demandLoad(obj, name, modPath){
// тело вырезано для простоты схемы
// необходимо взять из статьи по ссылке выше.
}
You can present the list of modules in the form of an array or a map (
Map
), and, for example, go through it / it in a loop so as not to repeat a line of code with a call demandLoad()
. You can, for example, read the list of used npm modules from package.json
. If, for example, the number of modules used is very high, and you do not want to clog the global scope, you can define, for example, an empty object m
( let m = {}
), define it m
in global
( global['m'] = m
), and m
apply it to it already demandLoad()
. As they say, to whom it is more convenient. Now, it remains only to launch this economy. Add the key
--require
to launch node (version> = 4.x):node --require ~/projects/general/require-all.js \
~/projects/mytestsite.com/lib/bin/server.js
There are no errors. The script worked as it should:
Url {
protocol: 'https:',
slashes: true,
auth: null,
host: 'habrahabr.ru',
port: null,
hostname: 'habrahabr.ru',
hash: null,
search: null,
query: null,
pathname: '/',
path: '/',
href: 'https://habrahabr.ru/' }
If you have many projects, for the convenience of project deployment, you can create your own
require-all.js
inside each project individually.node --require ~/projects/mytestsite.com/lib/require-all.js \
~/projects/mytestsite.com/lib/bin/server.js
Expanding the last case, I note that you can even use several of these
require-all.js
at the same time:node --require ~/projects/general/require-all.js \
--require ~/projects/mytestsite.com/lib/require-all.js \
~/projects/mytestsite.com/lib/bin/server.js
As noted in a comment below , the
--require
+ bundle global
can also be used to extend / overload the standard features of node. Finally, I repeat from the last article: If it is
demandLoad()
defined not in our file (1) (where we call it from demandLoad()
), but in some file (2), moreover, file (1) and file (2) are in different directories, the last parameter must be transferred full path to the module, for example:demandLoad(global, 'routes', path.join(__dirname, './../mytestsite.com/lib/routes'));
Otherwise, the one
require()
that is called from demandLoad()
will search for the module relative to the folder where the same file (2) with the description is located demandLoad()
, instead of looking for the module relative to the file (1) from where we call demandLoad()
. Thanks for attention. Successful refactoring to everyone!