require.cache is not empty before require - node.js

According to the description of require.cache
Modules are cached after the first time they are loaded. This means
(among other things) that every call to require('foo') will get
exactly the same object returned, if it would resolve to the same
file.
But When I've tested it in my node REPL, require.cache already has its object before require.
// test code
const utilsPath = require.resolve('../utils')
// logging the cache before require utils module.
console.log('-----')
console.log(require.cache[utilsPath])
console.log('-----')
const utils = require('../utils')
The console output is a Module object, and its key is the utilsPath.
How can require cache has that before require the corresponding module?
I've also tested with another module, but in that case, require cache was empty.
Any advice would really be appreciated!

Related

Is there a way to call resolve() on module.require in Node.js?

It seems that in Node.js 'require' and 'module.require' are not only separate objects but also different types of objects. 'require.resolve' exists but 'module.require.resolve' does not.
Is there any way to call resolve on module.require?
The reason I would like to do that is I would like to call require.main.require.resolve() to see what require.main.require
resolves a given path to.
Here's what I can find out to explain.
require.main gets you the module object for the script that was run first in this node.js process.
require.main.require gets you a function you could use to load scripts as if you were in that main script.
require.main.require does not have a .resolve() method. While require.main.require does get you a require function, as you have found it is not the exact same object that you get when you are in a module itself. It is just a function and appears to have none of the properties that the require object has in your own module.
The require object in your own module gets created by a special function called makeRequireFunction() in the loader (see source code here). That's where the other properties are added to it. But, the require.main.require is the same as process.mainModule and is just the require function by itself, not that special object.
A work-around would be to export resolve() from your entry script then access that exported function from the other script.
In your main module, you could put this:
module.exports.resolve = require.resolve;
Then, you could access that elsewhere with:
require.main.exports.resolve(...);

Object doesn't seem to load with all of its properties. - Node.js

I have two js files on my node server that require each other.
both have objects that are exposed via the module.exports mechanism.
1st file is located under bl/commands.js and uses:
var smUtil = require('./../utils/smUtil');
2nd file is located under utils/smUtil.js and uses:
var commands = require('./../bl/commands');
When a function runs from smUtil.js and uses some properties of commands.js it seems like command is an empty object and the import was not successful.
Here is the catch, when i remove the require of smUtil form inside commands.js everything works, which makes me think that i'm doing a newbe mistake.
Any thoughts?
Node.js documentation about circular dependencies
You are absolutely right that empty objects are returned.
To Quote Node.js documentation
When main.js loads a.js, then a.js in turn loads b.js. At that point, b.js tries to load a.js. In order to prevent an infinite loop, an unfinished copy of the a.js exports object is returned to the b.js module. b.js then finishes loading, and its exports object is provided to the a.js module.
A solution could be to create a separate file to require both the files there and instantiate that file to avoid the circular dependency.
The specific solution which solved my problem was to place var smUtil = require('./../utils/smUtil'); Underneath the module.exports inside commands.js.
However i feel like this solution is not the best one out there.
Thanks to the author of:
coderwall.com/p/myzvmg/circular-dependencies-in-node-js

node.js setting a global variable

I'm new to node js. I searched a lot on stack overflow on this question below, none what I need.
I have an app.js file which initiates node server and a router file. I want to be able to store a global value once and shared across other server side .js files which contains my functions. I also want this variable to be accessible in my .jade file. (I use express BTW)
Is there a way to accomplish this?
Thanks.
The Node.js documentation says under Module Caching
Caching Modules are cached after the first time they are loaded. This means (among other things) that every call to require('foo') will
get exactly the same object returned, if it would resolve to the same
file.
Multiple calls to require('foo') may not cause the module code to be
executed multiple times. This is an important feature. With it,
"partially done" objects can be returned, thus allowing transitive
dependencies to be loaded even when they would cause cycles.
If you want to have a module execute code multiple times, then export
a function, and call that function.
Which means you can easily expose a global object simply by putting it in its own module.
//config.js
var config = {
dbUrl: 'mogodb://localhost:2107/persons'
};
module.exports = config;
And then when you want to gain access to that object, you simply do:
var config = require('./config');
And that's done, you get access to the same instance everywhere.
You'll want to limit the usage of global vars in Node. This is because unlike any other server side language, Node is a persistent process that share all request. So you cannot setup user state globally as those will be shared across all user accessing your site.
In raw node, there's two global context:
global.foo = 'bar';
// and the process object
process.some_var = 1;
In Express, you can setup application wide vars using app.set
But, most of the time you'll want to share data by adding them to the request or the response objects. That is because those objects are "user" specifics, unlike the global namespace.
For the template, you'll always want to pass in the context:
app.render('email', Object.assign( aSharedObject, {
specific: 'values'
}));
i would use process.env or if you are using nconf put it into the app configuration as Jordan said, globals are BAD idea, also if you don't want to include nconf or any other conf module or use process.env then you can create a module and export a set of getters and setters to handle the value

What is the use of module.parent in node.js? How can I refer to the require()ing module?

I was looking in the node.js module documentation, and noticed that each module has a property- module.parent. I tried to use it, but got burnt by the module caching- module.parent only ever seems to the module that first require()'d it, irrespective of current context.
So what is the usage of it? Is there any other way for me to get a reference to the current require()ing module? Right now I'm wrapping the module in a function, so that it is called like:
require("mylibrary")(module)
but that seems sub-optimal.
The "parent" is the module that caused the script to be interpreted (and cached), if any:
// $ node foo.js
console.log(module.parent); // `null`
// require('./foo')
console.log(module.parent); // `{ ... }`
What you're expecting is the "caller," which Node doesn't retain for you. For that, you'll need the exported function you're currently using to be a closure for the value.
There is a workaround for this. Node adds a module to the module cache before it finishes loading it. This means that a module can delete itself from the module cache while it's loading! Then every time the module is require'd a new instance of the module is loaded.
Magic.js
console.log('Required by ' + module.parent.filename);
delete require.cache[__filename];
Module1.js
//prints "Required by Module1.js"
require('./Magic');
Module2.js
//prints "Required by Module2.js"
require('./Magic');
Of course the side-effect of this is that your module is no longer a singleton, so you have to code Magic.js with that in mind. If you need to store global data you can always keep it in a require()'ed module that doesn't delete itself from the cache.
Update for 2022
Note the technique described above doesn't work for ES Modules included with import. As far as I know there is no good way to detect the importing ES Module.

Understanding Node.js modules: multiple requires return the same object?

I have a question related to the node.js documentation on module caching:
Modules are cached after the first time they are loaded. This means
(among other things) that every call to require('foo') will get
exactly the same object returned, if it would resolve to the same
file.
Multiple calls to require('foo') may not cause the module code to be
executed multiple times. This is an important feature. With it,
"partially done" objects can be returned, thus allowing transitive
dependencies to be loaded even when they would cause cycles.
What is meant with may?
I want to know if require will always return the same object. So in case I require a module A in app.js and change the exports object within app.js (the one that require returns) and after that require a module B in app.js that itself requires module A, will I always get the modified version of that object, or a new one?
// app.js
var a = require('./a');
a.b = 2;
console.log(a.b); //2
var b = require('./b');
console.log(b.b); //2
// a.js
exports.a = 1;
// b.js
module.exports = require('./a');
If both app.js and b.js reside in the same project (and in the same directory) then both of them will receive the same instance of A. From the node.js documentation:
... every call to require('foo') will get exactly the same object returned, if it would resolve to the same file.
The situation is different when a.js, b.js and app.js are in different npm modules. For example:
[APP] --> [A], [B]
[B] --> [A]
In that case the require('a') in app.js would resolve to a different copy of a.js than require('a') in b.js and therefore return a different instance of A. There is a blog post describing this behavior in more detail.
node.js has some kind of caching implemented which blocks node from reading files 1000s of times while executing some huge server-projects.
This cache is listed in the require.cache object. I have to note that this object is read/writeable which gives the ability to delete files from the cache without killing the process.
http://nodejs.org/docs/latest/api/globals.html#require.cache
Ouh, forgot to answer the question. Modifying the exported object does not affect the next module-loading. This would cause much trouble... Require always return a new instance of the object, no reference. Editing the file and deleting the cache does change the exported object
After doing some tests, node.js does cache the module.exports. Modifying require.cache[{module}].exports ends up in a new, modified returned object.
Since the question was posted, the document has been updated to make it clear why "may" was originally used. It now answers the question itself by making things explicit (my emphasis to show what's changed):
Modules are cached after the first time they are loaded. This means
(among other things) that every call to require('foo') will get
exactly the same object returned, if it would resolve to the same
file.
Provided require.cache is not modified, multiple calls to
require('foo') will not cause the module code to be executed multiple
times. This is an important feature. With it, "partially done" objects
can be returned, thus allowing transitive dependencies to be loaded
even when they would cause cycles.
For what I have seen, if the module name resolve to a file previosuly loaded, the cached module will be returned, otherwise the new file will be loaded separately.
That is, caching is based on the actual file name that gets resolved. This is because, in general, there can be different versions of the same package that are installed at different levels of the file hierarchy and that must be loaded accordingly.
What I am not sure about is wether there are cases of cache invalidation not under the programmer's control or awareness, that might make it possible to accidentaly reload the very same package file multiple times.
In case the reason why you want require(x) to return a fresh object every time is just because you modify that object directly - which is a case I ran into - just clone it, and modify and use only the clone, like this:
var a = require('./a');
a = JSON.parse(JSON.stringify(a));
try drex: https://github.com/yuryb/drex
drex is watching a module for updates and cleanly re-requires the
module after the update. New code is being require()d as if the new
code is a totally different module, so require.cache is not a problem.
When you require an object, you are requiring its reference address, and by requiring the object twice, you will get the same address! To have copies of the same object, You should copy (clone) it.
var obj = require('./obj');
a = JSON.parse(JSON.stringify(obj));
b = JSON.parse(JSON.stringify(obj));
c = JSON.parse(JSON.stringify(obj));
Cloning is done in multiple ways, you can see this, for further information.

Resources