I tried this:
// mod.js
var a = 1;
this.b = 2;
exports.c = 3;
// test.js
var mod = require('./mod.js');
console.log(mod.a); // undefined
console.log(mod.b); // 2
console.log(mod.c); // 3, so this === exports?
So I image that require() may be implement like this:
var require = function (file) {
var exports = {};
var run = function (file) {
// include "file" here and run
};
run.apply(exports, [file]);
return exports;
}
Is that right? Please help me to understand require(), or where can I find the source code. Thanks!
Source code is here. exports
/require
are not keywords, but global variables. Your main script is wrapped before start in a function which has all the globals like require
, process
etc in its context.
Note that while module.js itself is using require()
, that's a different require function, and it is defined in the file called "node.js"
Side effect of above: it's perfectly fine to have "return" statement in the middle of your module (not belonging to any function), effectively "commenting out" rest of the code
Andrey showed the source code, but if you also wonder how to use it, the easy and simple explanation is here (http://nodejs.org/api/modules.html).
These were two good examples for me.
//foo.js, multiple methods
var circle = require('./circle.js');
console.log( 'The area of a circle of radius 4 is ' + circle.area(4));
//circle.js
var PI = Math.PI;
exports.area = function (r) {
return PI * r * r;
};
exports.circumference = function (r) {
return 2 * PI * r;
};
//bar.js
var square = require('./square.js');
var mySquare = square(2);
console.log('The area of my square is ' + mySquare.area());
//square.js, single method
module.exports = function(width) {
return {
area: function() {
return width * width;
}
};
}
My favourite pattern is
(function (controller) {
controller.init = function (app) {
app.get("/", function (req, res) {
res.render("index", {});
});
};
})(module.exports);
var mod = require('./mod.js');
The require is a function that takes one argument called path, in this case the path is ./mod.js
when the require is invoked, a sequences of tasks are happened:
call Module.prototype.require
function declared in lib/module.js which assert that the path exists and was a string
call Module._load
which is a function in lib/module.js that resolve the file through Module._resolveFilename(request, parent, isMain)
,
- the
Module._resolveFilename
function is called and checks if the module is native (The native modules are returned by NativeModule
function defined in lib/internal/bootstrap_node.js),
if yes it will return the module else it checks the number of characters of the parh (Must 2 character at least) and some characters (the path must started by ./
)
via Module._resolveLookupPaths
function defined in defined in lib/internal/bootstrap_node.js
- check the directory that contains the file
- If the path contains an extension (in our example yes: mod.js), the basename function defined in lib/path.js checks that the extension is "js"
- then it will create a new module for the file given in argument
var module = new Module(filename, parent);
- the content will be compiled via v8 through the function
NativeModule.prototype.compile
defined in lib/internal/bootstrap_node.js
- the
NativeModule.wrap
defined in lib/internal/bootstrap_node.js takes the javascript content compiled of mod.js
and wraps it : It wraps it in some other code that makes all this work.
So the code you've written in mod.js
is wrapped in a function expression. that means everything you write in node is run in V8
- a module.exports is what's returned
The source is available here next to the downloads : http://nodejs.org/ exports/require are keywords, I don't think they are coded in javascript directly. Node is coded in C++ , javascript is just a scripting shell around the C++ core.