CommonJS / RequireJS

我想问一下commonjs / requirejs循环模块依赖关系解析背后的机制是什么。

让我举一个例子。 让我们假设我们有以下模块结构

 modulea
     index.js
     submodulea_a.js
     submodulea_b.js

moduleb
     index.js
     submoduleb_a.js
     submoduleb_b.js

其中modulea / index.js和moduleb / index.js只是重新导出子模块的有趣功能。 即:

 var aa_class = require("./submodulea_a").aaclass;
 var ab_class = require("./submodulea_b").abclass;

 module.exports aa_class;
 module.exports ab_class;

另外,让我们假设在一个子模块中,我会这样做:

 var ba_class = require("moduleb").ba_class;

对B同样有效,但可以说在子模块b中我会这样做:

var aa_class = require("modulea").aa_class;

正如你所看到的,模块之间不存在一个类对另一个类的直接循环依赖性,但是由于模块a需要模块b和模块b需要模块a(更好地说,从子模块重新导出某些东西),所以存在循环模块依赖性。

如何通过节点commonjs或requirejs解决这个问题以避免堆栈溢出? 有没有像“后期绑定”或其他? 据我所知,我会说不,因为commonjs是同步的。

谢谢

编辑:

所以我做了一些关于模块结构的研究,看起来和下面的过程类似:

  • 解析模块名称(package.json,node_modules,相对路径...)
  • 加载模块代码(.js文件)
  • 标记它正在被初始化的当前模块(已解决)
  • 准备“空”({})导出并将其发布到当前模块(其他模块将在需求期间将其用于导入,即使它是空的)
  • 进程加载模块(执行它),如果找到require,则以与当前模块相同的方式解析模块
  • 模块执行完成后,将其标记为初始化(已解决)
  • 如果已经被初始化或初始化的模块需要被再次加载,则使用其导出的缓存版本。

    无法解决的问题:

    当循环模块即将被加载时,似乎没有办法如何解决:

    var aa_class = require("modulea").aa_class;
    

    作为模块A的aa_class的模块B的内部在需要时不可用,因为模块A的初始化在从模块A导出aa_class之前将执行移交给模块B.因此,只有模块可用的一件事B是来自模块A的空导出对象。我看不出有什么办法解决这个问题,因为如果我想扩展bb_module中的aa_class,我就会迷路了。


    有没有像“后期绑定”或其他?

    有RequireJS是的。 你可以称之为“后期绑定”或“延迟加载”。

    有关循环依赖关系的文档使用此示例。

    //Inside b.js:
    define(["require", "a"],
        function(require, a) {
            //"a" in this case will be null if "a" also asked for "b",
            //a circular dependency.
            return function(title) {
                return require("a").doSomething();
            }
        }
    );
    
    链接地址: http://www.djcxy.com/p/96615.html

    上一篇: CommonJS / RequireJS

    下一篇: iOS CommonJS module returns "undefined is not a constructor" error