Reputation: 554
So I'm using modules in a personal project for the usual reasons (namespace protection and dependency handling (require) and public API definition (exports)). I wrote my own require() method and am using the standard module pattern -- i.e.:
var myModule = (function() {
var exports = {};
function sayHello() {
return "hi";
}
exports.sayHello = sayHello;
return exports;
})();
So I want to standardize my stuff on CommonJS standard (this is for server-side JS and my question is not about CommonJS versus other module standards). Everything I read about CommonJS says that a module looks like this
function sayHello() {
return "hi";
}
exports.sayHello = sayHello
And that's it! But that's not a module. Something must be wrapping this as an actual module! I have not found a single site discussing CommonJS modules that says how this gets turned into an actual module. Am I missing something that everybody else seems to know?
So my questions are:
What is doing the wrapping? -- i.e., what turns it into an actual module? A library of some sort, I assume.
What does this final, wrapped, CommonJS module look like? I want to write an implementation of the CommonJS standard, but can't find any documentation of what that final module is supposed to look like.
Is the "exports" variable in the global scope? If not, what is providing the exports object to the module if it's not being explicitly declared in the body of the module code? And who's doing it - the caller of the module?
Dang. It seemed simple when I wrote it myself. Now it seems like magic. A link to some comprehensive documentation would be great.
NOTE: I know very little about node.js and don't intend to use it in this project, so if you answer, please don't answer in node.js-speak.
Upvotes: 3
Views: 1384
Reputation: 6655
I hope that node.js documentation can answer all of your questions.
So, according to the node.js documentation
Before a module's code is executed, Node.js will wrap it with a function wrapper that looks like the following:
(function(exports, require, module, __filename, __dirname) {
// Module code actually lives in here
});
By doing this, Node.js achieves a few things:
var
, const
or let
) scoped to the module rather than the global object.module
and exports
objects that the implementor can use to export values from the module.__filename
and __dirname
, containing the module's absolute filename and directory path.Upvotes: 0
Reputation: 11676
What is doing the wrapping?
Node is. It can access the filesystem, so it caches the code from all the files that have been required, and delivers it to the namespaces that required it.
What does this final, wrapped, CommonJS module look like?
The actual code where modules are wrapped will probably be in module.js
, which is a core file in the lib
folder of Node's installation.
Is the "exports" variable in the global scope?
The exports
is a property of the module
object within a file. The module
is the global scope inside that file. The exports
property is what is returned by the module to the code that requires it.
The key thing to remember is that the CommonJS ethos is built-in to Node's core modular code. There is no magical implementation in the V8 which dictates that module.exports
is a 'thing'. This may all change when implementing ES6 modules becomes the norm.
You might find it useful reading this.
You may find it even more useful to give up on your quest to re-write require()
. :-)
Upvotes: 2