How does require() in node.js work?

Javascriptnode.jsThisRequireApply

Javascript Problem Overview


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!

Javascript Solutions


Solution 1 - Javascript

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

Solution 2 - Javascript

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:

  1. call Module.prototype.require function declared in lib/module.js which assert that the path exists and was a string

  2. call Module._load which is a function in lib/module.js that resolve the file through Module._resolveFilename(request, parent, isMain),

  3. 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

  4. check the directory that contains the file

  5. 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"

  6. then it will create a new module for the file given in argument var module = new Module(filename, parent);

  7. the content will be compiled via v8 through the function NativeModule.prototype.compile defined in lib/internal/bootstrap_node.js

  8. 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

  9. a module.exports is what's returned

Solution 3 - Javascript

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);

Solution 4 - Javascript

I dig a little more of nodejs source code/2/ and make a sequence diagram/1/, hope this could give you a intuitive overview. There is another article http://fredkschott.com/post/2014/06/require-and-the-module-system/ which also explain the require() mechanism in a easy way, go through this article first could help you to understand the diagram quickly. enter image description here

Ref:

/1/ diagram source repo: https://github.com/z1yuan/nodejs.git

/2/ https://github.com/nodejs/node-v0.x-archive.git

Solution 5 - Javascript

Try This.
This is a snippet of what I used to create the same functionality as Node.js

/*
FILE: require.js
*/
/*
This is the file used
*/
window.require = function(src, ret) {
  if (src === 'jsmediatags') {
    src = 'https://cdnjs.cloudflare.com/ajax/libs/jsmediatags/3.9.5/jsmediatags.js';
  };
  var d = document.createElement('script');
  d.src = src;
  document.head.appendChild(d);
  var fullURL = src.split('://');
  var neededURL = fullURL[1];
  var nameParts = neededURL.split('/');
  var nameNUM = nameParts.length - 1;
  var fileName = nameParts[nameNUM];
  var g = fileName.split('.');
  var global = g[0];
  if (ret === true) {
    return window[global]
  };
};

See if this works, and to add more files to its library, just type more in. (if (src===yourfilenamehere) { src = "path/to/your/file" }

Solution 6 - Javascript

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTrantor LiuView Question on Stackoverflow
Solution 1 - JavascriptAndrey SidorovView Answer on Stackoverflow
Solution 2 - JavascriptMohamed Ben HEndaView Answer on Stackoverflow
Solution 3 - JavascriptAndrew ChaaView Answer on Stackoverflow
Solution 4 - JavascriptZhi YuanView Answer on Stackoverflow
Solution 5 - JavascriptAnonymousView Answer on Stackoverflow
Solution 6 - JavascriptmpmView Answer on Stackoverflow