There's this huge misconception that because "require" synchronously returns the module object it must use synchronous IO to load the modules as well, which is not true. The root module and it's transitive dependencies can be loaded asynchronously before any execution of the code (and thus require calls) takes place.
To do that the dependency module IDs must be extracted from the module text via static analysis, but that's fairly easy since module IDs are specified to be string literals. A simple regex is usually good enough, but using one of the many JavaScript parsers is safer. For cases where the module ID needs to be computed or loaded based on a runtime decision, an asynchronous form of require should be used.
The expectation is ECMAScripts modules will map pretty cleanly to CommonJS modules, but with real syntax rather than function calls. In the meantime CommonJS modules are a pretty good compromise I think. Simple implementations can do the loading using synchronous IO as "require" is called, while more advanced loaders (especially for browsers) can implement a slightly more complicated system to do the loading up front before excution.
> To do that the dependency module IDs must be extracted from the module text via static analysis, but that's fairly easy since module IDs are specified to be string literals. A simple regex is usually good enough, but using one of the many JavaScript parsers is safer.
I did exactly this for browserify, yet another node-based browser-side require() bundling system. Another benefit of this approach is that you can use modules made for node just by require()ing them in your browser-side javascript, so long as your static analysis bundling is recursive and the modules can be `require.resolve()`'d by node.
To do that the dependency module IDs must be extracted from the module text via static analysis, but that's fairly easy since module IDs are specified to be string literals. A simple regex is usually good enough, but using one of the many JavaScript parsers is safer. For cases where the module ID needs to be computed or loaded based on a runtime decision, an asynchronous form of require should be used.
The expectation is ECMAScripts modules will map pretty cleanly to CommonJS modules, but with real syntax rather than function calls. In the meantime CommonJS modules are a pretty good compromise I think. Simple implementations can do the loading using synchronous IO as "require" is called, while more advanced loaders (especially for browsers) can implement a slightly more complicated system to do the loading up front before excution.