zoukankan      html  css  js  c++  java
  • nodejs js模块加载

    本文地址:http://www.cnblogs.com/jasonxuli/p/4381747.html

    nodejs的非核心模块(core module)加载主要使用的就是module.js。

    项目主模块(index.js/main.js等)加载使用的应该是module.js中的runMain(),其他js模块加载流程基本上是:

    1,获取js文件信息;

    2,new Module();

    3,读取js文件内容,封装到一个function中,同时注入module本身,module.exports,包装过的require函数等变量;

    4,在某个上下文环境中执行这个封装后的function;

    5,返回module.exports;

    下面是摘出的主要代码

    module.js:

    // Loads a module at the given file path. Returns that module's
    //
    `exports` property. Module.prototype.require = function(path) { assert(path, 'missing path'); assert(util.isString(path), 'path must be a string'); return Module._load(path, this); }; // 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(filename, this){ If(fileName in Module._cache) Return Module._cache[filename];
      
    var module = new Module(filename, parent);   Module._cache[filename] = module;   Module.load(filename);
      // 先把模块放到缓存然后再去加载内容,可以解决循环依赖的问题。
      // 参见https://nodejs.org/api/modules.html的Cycles部分。

      
    return module.exports; } Module.prototype.load(filename){ var extension = path.extname(filename) || ‘.js’;
    Module._extensions[extension](
    this, filename){ var content = fs.readFileSync(filename, ‘utf-8’); module._compile(content, filename);   } } // Run the file contents in the correct scope or sandbox. Expose // the correct helper variables (require, module, exports) to // the file. // Returns exception, if any. Module.prototype._compile = function(content, filename) { function require(path) { return self.require(path);   }   require.main = process.mainModule;   // Enable support to add extra extension types   require.extensions = Module._extensions;   require.cache = Module._cache;   // TODO: 每个模块加载到自己的context中会有什么不同?   // Set the environ variable NODE_MODULE_CONTEXTS=1 to make node load all modules in their own context.   // Module._contextLoad = (+process.env['NODE_MODULE_CONTEXTS'] > 0);   // if (Module._contextLoad) { .... }   // create wrapper function   var wrapper = NativeModule.wrap(content);   // wrapper = '(function (exports, require, module, __filename, __dirname) { ' + content + ' });'   // runInThisContext()可以认为是在某个上下文环境中执行的eval()。   // compiledWrapper相当于eval(‘(function(){....})’)的结果,也就是真正的Function。   var compiledWrapper = runInThisContext(wrapper, { filename: filename });   // module.exports 和 exports 的区别:   // 这里只传递了exports的引用;而上面Module._load()返回的是module.exports,因此给module.exports赋值后,   // exports仍然指向之前的module.exports。   var args = [self.exports, require, self, filename, dirname];   // 真正执行compiledWrapper这个function,也就是执行了filename.js的内容。   return compiledWrapper.apply(self.exports, args); }


    runInThisContext()就是vm.js里的runInThisContext(),vm.runInThisContext()调用了src/node_contextify.cc中的RunInThisContext()。

    https://github.com/joyent/node/blob/master/lib/vm.js

    https://github.com/joyent/node/blob/master/src/node_contextify.cc

     扩展:

    https://github.com/brianmcd/contextify

    The main difference between Contextify and Node's vm methods is that Contextify allows asynchronous functions to continue executing in the Contextified object's context.

    博客地址:http://www.cnblogs.com/jasonxuli/
  • 相关阅读:
    SCCM 2007 部署软件更新
    WPF开发工具
    体验Windows Live Writer写Blog
    图像的灰度和黑白处理算法
    很有用的Sql总结转载
    WPF 体验导航窗口
    WPF 一周练
    WPF 图表
    也说Linq 分组
    WPF 体验对话框调用
  • 原文地址:https://www.cnblogs.com/jasonxuli/p/4381747.html
Copyright © 2011-2022 走看看