CommonJS / RequireJS

I would like to ask what is the mechanism behind the commonjs/requirejs circular module dependency resovling.

Let me give you an example. Lets assume we have following module structure

 modulea
     index.js
     submodulea_a.js
     submodulea_b.js

moduleb
     index.js
     submoduleb_a.js
     submoduleb_b.js

where modulea/index.js and moduleb/index.js just reexports interesting functionality of sub modules. ie:

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

 module.exports aa_class;
 module.exports ab_class;

also, lets assume that in aa submodule i'll do:

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

the same is valid for B but lets say that in submodule b I will do:

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

As you can see, there is no direct circular dependency of one class on another across modules but there is circular module dependency as modulea requires moduleb and moduleb requires modulea (better said, re-exports of something from submodules).

How this is resolved by the node commonjs or requirejs in order to avoid stack overflow? Is there something like "late binding" or whatever? I would say no as commonjs is synchronous as far as I know.

Thanks

EDIT:

So I did some research with module structure described and it seems it works similarly to the following process:

  • Resolve module name (package.json, node_modules, relative paths...)
  • Load the module code (.js file)
  • Mark the current module it is being initialized (resolved)
  • Prepare "empty" ( {} ) exports and publish it for the current module (other modules will use it for imports during require even if it is empty)
  • Process loaded module (execute it) and if require is found, resolve the module in the same way as the current one
  • Once the module execution is done, mark it as it is initialized (resolved)
  • if the module being initialized or initialized already is required to be loaded again, the cached version of its exports is used.

    the problems which can't be resolved:

    When circular module is about to be loaded it seems there is no way how to resolve:

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

    inside of the module B as aa_class of the module A is not available at the time when it was required as initialization of module A handed over the execution to module B before the aa_class was exported from module A. So only the one thing available to module B is empty exports object from the module A. And I can't see any way to solve this what is bad because if I would like to extend the aa_class in bb_module I am lost.


    Is there something like "late binding" or whatever?

    With RequireJS yes there is. You could call it "late binding" or "lazy loading".

    The documentation on Circular Dependencies uses this example.

    //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/96616.html

    上一篇: “出口”在PhantomJS中定义在哪里?

    下一篇: CommonJS / RequireJS