How do you require a file within itself in node.js? E.g. api.js:
var api = require(./api.js);
What is the best practice for doing this?
You can totally do it. Try this, for instance (in a file named a.js):
exports.foo = 'foo';
var a = require('./a');
console.log(a);
exports.bar = 'bar';
console.log(a);
At the point where require executes, it will return the module a as it exists at the point where require runs so the field foo will be defined but not bar.
There's no point to doing this though. You use require to bring into your current scope an object which would otherwise not be available (namely, a module). But you don't need to do this to access the module you are currently in: it is already fully available.
The code above works because Node has rules to handle cyclic dependencies. And here you have a module which is cyclicly dependent on itself. Rather than go into an infinite loop of requires, Node has require return the module as built up to that point: a partial module. And the modules in a cyclic dependency have to be designed to handle the fact that they may get partial modules.
Cyclic dependencies are to be avoided as much as possible. Most of the time this means refactoring the modules to avoid the mutual dependency by moving functionality into one or more new modules.
So, again, the best practice is to not do this in the first place.
Related
I got to the point that I'd like to have a factory to manage all my dependencies for the modules in a single place instead of having a lot of statements using require all over the place in my code.
I've looked at some approaches that rely on AMD, but I'd like to know how to do it by using node.js / express combination with the OOB module loader which I think it uses common.js.
I've been thinking of doing something like this:
module.exports = {
lib:[],
load:function(name){
if(this.lib[name]!==undefined && this.lib[name]!==null){
return this.lib[name];
}
switch(name)
{
case 'express':
this.lib[name] = require('express');
break;
case 'morgan':
this.lib[name] = require('morgan');
break;
case 'body-parser':
this.lib[name] = require('body-parser');
break;
}
console.log(this.lib);
return this.lib[name];
}
};
Some people say that's more than a factory its a mediator pattern, so either way I just wanted to illustrate my point.
my basic requirement is to handle all the dependencies from a single place in the system if I need to change a dependency I just change it on this file and automatically updates through the whole system.
so is there a better way to handle this? any Implementation that already have done this approach?
thanks!
Technically this is what require() does internally.
require('foo'); require('foo')
guarantees that it will load and run foo only once. The second call will return a cached copy from its internal array.
You can achieve the same naming indirection (and an API adapter if you'll ever decide to change the implementation without changing callers) by requiring JS files or your node modules that re-export modules you actually use (e.g. require('./my-express-wrapper') instead of require('express')).
if I need to change a dependency I just change it on this file and automatically updates through the whole system.
I'd be concerned that it will cause code to be surprising:
require('factory').load('body-parser'); // loads Formidable!?
I see little benefit in having such layer of indirection:
Even in the best case of drop-in-replacement it saves very little work, because project-global find'n'replace of require('foo') with require('bar') is an easy task in most text editors.
The hard part of replacing module (which is unlikely to be 100% compatible) is getting existing code to correctly work with it. This is not avoided by use of the factory pattern. You'll need to write an adapter either way, and sometimes it may even be better to actually change uses of the module everywhere than to write an emulation layer for an API that probably wasn't good anyway.
I'm starting out a long term project, based on Node.js, and so I'm looking to build upon a solid dependency injection (DI) system.
Although Node.js at its core implies using simple module require()s for wiring components, I find this approach not best suited for a large project (e.g. requiring modules in each file is not that maintainable, testable or dynamic).
Now, I'd done my bits of research before posting this question and I've found out some interesting DI libraries for Node.js (see wire.js and dependable.js).
However, for maximal simplicity and minimal repetition I've come up with my own proposition of implementing DI:
You have a module, di.js, which acts as the container and is initialized by pointing to a JSON file storing a map of dependency names and their respective .js files.
This already provides a dynamic nature to the DI, as you may easily swap test/development dependencies.
The container can return dependencies by using an inject() function, which finds the dependency mapping and calls require() with it.
For simplicity, the module is assigned to a global variable, i.e. global.$di, so that any file in the project may use the container/injector by calling $di.inject().
Here's the gist of the implementation:
File di.js
module.exports = function(path) {
this.deps = require(path);
return {
inject: function(name) {
if (!deps[name])
throw new Error('dependency "' + name + '" isn\'t registered');
return require(deps[name]);
}
};
};
Dependency map JSON file
{
"vehicle": "lib/jetpack",
"fuel": "lib/benzine",
"octane": "lib/octane98"
}
Initialize the $di in the main JavaScript file, according to development/test mode:
var path = 'dep-map-' + process.env.NODE_ENV + '.json;
$di = require('di')(path);
Use it in some file:
var vehicle = $di.inject('vehicle');
vehicle.go();
So far, the only problem I could think of using this approach is the global variable $di.
Supposedly, global variables are a bad practice, but it seems to me like I'm saving a lot of repetition for the cost of a single global variable.
What can be suggested against my proposal?
Overall this approach sounds fine to me.
The way global variables work in Node.js is that when you declare a variable without the var keyword, and it gets added to the global object which is shared between all modules. You can also explicitly use global.varname. Example:
vehicle = "jetpack"
fuel = "benzine"
console.log(vehicle) // "jetpack"
console.log(global.fuel) // "benzine"
Variables declared with var will only be local to the module.
var vehicle = "car"
console.log(vehicle) // "car"
console.log(global.vehicle) // "jetpack"
So in your code if you are doing $di = require('di')(path) (without var), then you should be able to use it in other modules without any issues. Using global.$di might make the code more readable.
Your approach is a clear and simple one which is good. Whether you have a global variable or require your module every time is not important.
Regarding testability it allows you to replace your modules with mocks. For unit testing you should add a function that makes it easy for you to apply different mocks for each test. Something that extends your dependency map temporarily.
For further reading I can recommend a great blog article on dependency injection in Node.js as well as a talk on the future dependency injector of angular.js which is designed by some serious masterminds.
BTW, you might be interested in Fire Up! which is a dependency injection container I implemented.
I'm refactoring a large javascript codebase to use RequireJS. Unfortunately, many of the files I'm dealing with are not object-oriented, and cannot return an object without significant modification. Is there a more efficient way to give 'dependent' modules access to the functions and variables contained in a module (without returning an object) ?
I have read about using the exports syntax for defining modules, but it is very unclear whether that would be a valid solution for this situation.
In a defined module, the exports object is what gets exported from the module and passed to whatever module requires it.
Consider this:
define(["exports"], function(exports){
exports.myCustomFunction = function(){};
exports.myCustomObject = {};
exports.myCustomVariable = true;
})
This module will place all the disparate functions and/or objects that you want made public onto the exports object.
At this point RequireJS will use that exports object to pass to a module that requires it:
require(["nameOfCustomModule|filename"], function(myCustomModule){
//evaluates to true
console.log(myCustomModule.myCustomVariable);
})
Here's a simple fiddle. Just bring up your console and you will see the value logged there. http://jsfiddle.net/xeucv/
Hope this clears it up a bit!
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.
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.