This is a proposal that specifies the interface of a Module Loader. Implementations of the Module Loader interface can be made secure and provided to suspicious sandboxes: sandboxes with reduced capabilities (privileges that are exercisable only by containing a reference to a gate keeper). The module loader interface is intended to be extensible in privileged sandboxes to:
- load shared objects and dynamic libraries
- load modules from formats other that CommonJS, like ObjectiveJ, or a hand-written module factory format, like a module transport format suitable also for script injection in browsers
- load modules that have different values in scope, dependency injection, like Jakefiles and QUnit tests, or a simulated browser scope
- The "require" function provided to modules may have a "loader" property that must be a module loader object.
2. Module Loaders
- A module loader must have the "resolve(id, baseId)" function. This function must return a top-level module identifier given any other valid CommonJS module identifier. The given identifier may be relative to the base identifer or a top-level identifier itself, in which case the base identifier is ignored. If the module loader supports module identifiers outside the CommonJS module identifier domain, resolve must return some form of canonical module identifier acceptable by require(canonicalId).
- A module loader must have a "reload(topId)" property function. This function may force a module factory function to be created from the original medium. The given identifier must be a value returned by "resolve".
- A module loader must have a "load(topId)". The given identifier must be a value returned by "resolve". "load" returns a module factory function.
2.1. Module File Loaders
- A module loader may have a "find(topId)" function that must return the canonical path of the file that can be loaded.
- A module loader may implement the augmented reload interface, "reload(topId, path_opt)", that accepts a hint of where to find the path to the file corresponding to the identifier.
- A module loader may implement the augmented load interface, "load(topId, path_opt)", that accepts a hint of where to find the path to the file corresponding to the identifier.
2.2. Module Multiplexer Loaders
- A module may implement "canLoad(path)" that accepts a path and returns whether the loader can load a module at that path with "reload(id, path)" and "load(id, path)". Acceptable grounds for determining whether the module can load the module include the extension or the content of the file.
- A module may have a "loaders" property that must be an Array of module loader objects, [canLoad(path), loader] pairs, [extension, loader] pairs, or any combination thereof.
- Any module loader providing a "loaders" property must respect in-place changes to the loaders property.
- The loaders property may not be writable.
- The loaders property may not be configurable.
3. Module Factory Functions
- A module factory function accepts an object and returns nothing.
- The object accepted by a module factory function may include a "require", "exports", and "module", the values of which correspond to the free variables defined in a CommonJS module.
4. Packaged Module Loaders
- A package may provide a module loader.
- package.json may have a "loader" property that may either be a loader identifier or a prioritized order of loader identifiers from high to low priority.
- A package system may construct and provide as "require.loader" a multiplexing loader from the collected loader identifiers in all installed packages, in which case it must construct the multiplexing loader's "loader" property with loader instances corresponding to each loader identifier in each package.json in each package in package dependency order as established by a topological sort of all packages ordered from most dependent to least dependent.
- A loader instance corresponding to a module loader identifier must be constructed, without use of the "new" keyword, from the "Loader" function of the module file found by resolving resolving the module loader identifier as the path relative to the containing package.json.