Node.js 模块的加载初探

1模块加载的 Demo

  1. 模块文件 hello.js
function hello(){
    //定义一个变量
    var name;
    this.setName = function(tName){
        name = tName;
    }
    this.sayHello = function(){
        console.log("Hello " + name );
    }
};
module.exports = hello;
  1. 主加载文件main.js
var HelloModule = require("./hello.js");
var hello = new HelloModule();
hello.setName("Jason");
hello.sayHello();

由上面两个文件可以看出hello.js里面的hello函数作为模块的输出,用语法module.exports = hello; 暴露出来供其他引用者使用。 main.js 文件里面使用语法 var HelloModule = require("./hello.js") 将当前目录下的hello模块引入进来复制给变量。 如果没有指明路径node.js会以内置模块、系统模块、当前模块的顺序进行查找

2模块的加载过程.

  • require的过程
// Loads a module at the given file path. Returns that module's
// `exports` property.
Module.prototype.require = function(id) {
  //检查类型是不是string
  if (typeof id !== 'string') {
    throw new ERR_INVALID_ARG_TYPE('id', 'string', id);
  }
  //检查是不是空字符串
  if (id === '') {
    throw new ERR_INVALID_ARG_VALUE('id', id,
                                    'must be a non-empty string');
  }
  //检查通过则使用load方法加载模块
  return Module._load(id, this, /* isMain */ false);
};
  • load的实现
// Check the cache for the requested file.
// 1. If a module already exists in the cache: return its exports object.
// 2. If the module is native: call `NativeModule.require()` with the
//    filename and return the result.
// 3. Otherwise, create a new module for the file and save it to the cache.
//    Then have it load  the file contents before returning its exports
//    object.
Module._load = function(request, parent, isMain) {
  if (parent) {
    debug('Module._load REQUEST %s parent: %s', request, parent.id);
  }

  var filename = Module._resolveFilename(request, parent, isMain);

  var cachedModule = Module._cache[filename];
  if (cachedModule) {
    updateChildren(parent, cachedModule, true);
    return cachedModule.exports;
  }

  if (NativeModule.nonInternalExists(filename)) {
    debug('load native module %s', request);
    return NativeModule.require(filename);
  }

  // Don't call updateChildren(), Module constructor already does.
  var module = new Module(filename, parent);

  if (isMain) {
    process.mainModule = module;
    module.id = '.';
  }

  Module._cache[filename] = module;

  tryModuleLoad(module, filename);

  //前面的所有步骤都是将文件以匿名函数的方式将js放入一个包装函数
  //此行代码将 module.exports 作为包装函数模块的输出暴露出去 
  //所以在js代码中修改module.exports可以修改模块的暴露变量
  return module.exports;
};

猜你喜欢

转载自blog.csdn.net/xiaocajiyyd/article/details/80903713
今日推荐