node.js中的require()如何工作?

Tra*_*Liu 71 javascript this require apply node.js

我试过这个:

// 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?
Run Code Online (Sandbox Code Playgroud)

所以我想象require()可能是这样实现的:

var require = function (file) {
    var exports = {};
    var run = function (file) {
        // include "file" here and run
    };
    run.apply(exports, [file]);
    return exports;
}
Run Code Online (Sandbox Code Playgroud)

是对的吗?请帮我理解require(),或者在哪里可以找到源代码.谢谢!

And*_*rov 51

源代码在这里.exports/ require不是关键字,而是全局变量.你的主要脚本开始在其拥有的所有全局的功能等require,process在其上下文等.

请注意,虽然module.js本身正在使用require(),但这是一个不同的require函数,它在名为"node.js"的文件中定义.

上面的副作用:在模块中间有"return"语句(不属于任何函数),完全没问题,有效地"注释掉"其余的代码


And*_*ndy 8

Andrey展示了源代码,但是如果你也想知道如何使用它,那么简单而简单的解释就在这里(http://nodejs.org/api/modules.html).

这对我来说是两个很好的例子.

//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;
    }
  };
}
Run Code Online (Sandbox Code Playgroud)

我最喜欢的模式是

(function (controller) {

  controller.init = function (app) {

    app.get("/", function (req, res) {
        res.render("index", {});
    });

  };
})(module.exports);
Run Code Online (Sandbox Code Playgroud)


Moh*_*nda 6

var mod = require('./mod.js');
Run Code Online (Sandbox Code Playgroud)

require是一个函数,它接受一个名为path的参数,在这种情况下,路径是 ./mod.js

调用require时,会发生一系列任务:

  1. Module.prototype.requirelib/module.js中声明的调用函数,它断言路径存在并且是一个字符串

  2. call Module._loadlib/module.js中一个解析文件的函数Module._resolveFilename(request, parent, isMain),

  3. Module._resolveFilename函数被调用并检查模块是天然的(天然模块通过返回NativeModule在定义的函数LIB /内部/ bootstrap_node.js),如果是的,它会返回模块否则它检查parh的字符(必须在2数./通过lib/internal/bootstrap_node.jsModule._resolveLookupPaths中定义的函数定义的一些字符(路径必须以此开头)
  4. 检查包含该文件的目录
  5. 如果路径包含扩展名(在我们的示例中为yes:mod.js),则lib/path.js中定义的basename函数检查扩展名是否为" js "
  6. 然后它将为参数中给出的文件创建一个新模块 var module = new Module(filename, parent);
  7. 内容将通过v8通过lib/internal/bootstrap_node.js中NativeModule.prototype.compile定义的函数进行编译
  8. NativeModule.wrap中定义的lib /内部/ bootstrap_node.js需要编译的JavaScript内容mod.js并把它封装:它把它封装在其他一些代码,使所有这些工作.因此,您编写的代码mod.js包含在函数表达式中.这意味着您在节点中编写的所有内容都在V8中运行
  9. module.exports是返回的内容