In the node.js documentation regarding module caching, the following statement is made:
Multiple calls to require(‘foo’) may not cause the module code to be executed multiple times. This is an important feature. With it, “partially done” objects can be returned, thus allowing transitive dependencies to be loaded even when they would cause cycles.
I’m a bit confused about the last sentence. What is a “partially done” object? How does this relate to allowing (or avoiding) cyclical dependencies?
If you
requirea package from a file, and that causes a file in that package torequirethe file that caused the initialrequirethen you have a cyclic dependency. By default, it would just go in circles. In order to prevent this, one can keep a marker where the originalrequirestarted so that the next time that file isrequire‘d it will start from that point rather than the beginning. It’s not flawless, but in the case of loading a package you are generally only interested in the exports, and it works well in that case.I pushed a diff for node-browserify a while back for a primitive method of “partially done” exports. Basically, each time something is
require‘d it will check the amount of exports. If there are more exports, it means the package was incomplete the last time, and could still be processing. If there are no new exports (the new and old count are equal), then it means the package is done, and can be cached so that the module code is not executed multiple times. Being that it is in the browser, there’s no control over execution flow, and thus the module code would be repeated partially (in steps) until done. Whereas I’m sure Node.js has more elegant handling.