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

时间:2012-02-28 02:56:43

标签: javascript node.js this require apply

我试过了:

// 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?

所以我认为require()可能是这样实现的:

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

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

5 个答案:

答案 0 :(得分:48)

源代码为hereexports / require不是关键字,而是全局变量。您的主脚本wrapped位于start之前的函数中,该函数在其上下文中包含requireprocess等所有全局变量。

请注意,虽然module.js本身正在使用require(),但这是一个不同的require函数,并且在名为“node.js”的文件中为defined

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

答案 1 :(得分: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;
    }
  };
}

我最喜欢的模式是

(function (controller) {

  controller.init = function (app) {

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

  };
})(module.exports);

答案 2 :(得分:6)

var mod = require('./mod.js');

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

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

  1. 调用here中声明的Module.prototype.require函数,该函数断言路径存在并且是一个字符串

  2. 致电Module._load这是lib/module.js中通过Module._resolveFilename(request, parent, isMain)解析文件的函数,

  3. 调用Module._resolveFilename函数并检查模块是否为本机模块(本地模块由lib/module.js中定义的NativeModule函数返回, 如果是,它将返回模块,否则它会检查parh的字符数(至少必须包含2个字符)和一些字符(路径必须由 ./ ) 通过lib/internal/bootstrap_node.js
  4. 中定义的Module._resolveLookupPaths函数定义
  5. 检查包含文件的目录
  6. 如果路径包含扩展名(在我们的示例中为yes:mod.js),lib/internal/bootstrap_node.js中定义的basename函数会检查扩展名为" js &#34 ;
  7. 然后它将为参数var module = new Module(filename, parent);
  8. 中给出的文件创建一个新模块
  9. 内容将通过v8通过lib/path.js
  10. 中定义的函数NativeModule.prototype.compile进行编译
  11. lib/internal/bootstrap_node.js中定义的NativeModule.wrap获取mod.js编译的javascript内容并将其包装起来:它将其包含在其他一些使所有这些工作的代码中。 因此,您在mod.js中编写的代码将包含在函数表达式中。这意味着您在节点中编写的所有内容都在V8中运行
  12. module.exports是返回的内容

答案 3 :(得分:0)

我进一步挖掘了nodejs源代码/ 2 /,并制作了序列图1/1 /,希望这可以给您直观的概述。还有另一篇文章http://fredkschott.com/post/2014/06/require-and-the-module-system/也以一种简单的方式解释了require()机制,首先阅读本文可以帮助您快速理解该图。 enter image description here

参考:

/ 1 /图表源仓库:https://github.com/z1yuan/nodejs.git

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

答案 4 :(得分:-8)

源代码可以在下载旁边找到:http://nodejs.org/ exports / require是关键字,我认为它们不是直接用javascript编码的。 Node用C ++编写,javascript只是围绕C ++核心的脚本shell。