When you instantiate the ES6ModuleLoader
the paths of the compiler inputs are normalized against the first module root that completely
matches the beginning of the compiler input and saved in an instance variable called moduleUris
. Later, when trying to locate a
required module, if the module path is not relative, meaning it doesn't start with ./
or ../
, the ES6ModuleLoader
will try to normalize the required module path against the
module roots and if this is not successfull the ES6ModuleLoader
will just check the moduleUris
for a match.
(def first-file (SourceFile/fromFile
(clojure.java.io/file "node_modules/react/react.js")))
(def second-file (SourceFile/fromFile
(clojure.java.io/file "node_modules/react/lib/EventConstants.js")))
(def first-input (CompilerInput. first-file))
(def second-input (CompilerInput. second-file))
(ES6ModuleLoader. (list "./node_modules" "./node_modules/react") (list first-input second-input))
In the example above, the moduleUris
will be: [react/react.js react/lib/EventConstants.js]
. So trying to locate react/lib/EventConstants
will succeed, but trying to locate react
will fail since it doesn't match any of the moduleUris.
If we switch the order of the module roots when instantiating the ES6ModuleLoader, e.g. (ES6ModuleLoader. (list "./node_modules/react" "./node_modules") (list first-input second-input))
, the moduleUris
will be
[react.js lib/EventConstants.js]
, so trying to locate react
will succeed, but trying to locate react/lib/EventConstants
will fail.
Currently, I don't see a straightforward solution to this problem, since I am not sure what the right strategy should be to normalize a
compiler input against overlapping module roots. In addition to locating required modules, the ES6ModuleLoader
also determines the new
module name by normalizing the path of a module against the module roots. This means, that the logic to locate a required module needs to result in the same path as when the path of a module is normalized against the module roots. For example,
URI loadAddress = loader.locateCommonJsModule(requireName, input);
String moduleName = ES6ModuleLoader.toModuleName(loadAddress);
needs to result in the same module name as:
ES6ModuleLoader.toModuleName(loader.normalizeInputAddress(input))
Would definitely be good to get some advice on the Google Closure compiler mailing list. I think the ES6ModuleLoader
aims to implement how require works with respect to the CommonJS specification (http://wiki.commonjs.org/wiki/Modules/1.1) and not how require works in Node.js (https://nodejs.org/api/modules.html#modules_module_require_id).