Status
January 12, 2012 ยท View on GitHub
Status
Stability: Beta
Summary
The loader is currently under active development. Production use is possible if releases are thoroughly tested prior to use. APIs may slightly change in future.
Contributors
Looking for:
- Users to use the loader and report issues
- Adapter authors for other CommonJS platforms
- Critical reviewers for specifications
- Feedback in all areas
- Contributions in any area
TODO
General
-
Support for: http://www.phantomjs.org/
-
Do not throw if package does not have "main" set and
--scriptis used -
OS distro packages for loader
-
Author: CommonJS Programs/A (strawman)
-
Author: PINF Workspace/A (strawman)
-
Enforce reserved names for mapping labels based on default modules provided by platform
-
Build and publish commands to provide versioned releases (This will be part of PINF/CLI)
-
Rename ./lib/pinf-loader-js to ./lib/pinf-loader
-
Path resolution in
config filesfiles:/from/THIS/PACKAGE/root./relative/to/CONFIG/FILEfrom/TOP/PACKAGE/rootconfig files get merged and path gets resolved from seed config file.
NodeJS
- Get
./lib/modules/pinf/protocol-handler.jsworking
Jetpack
-
warning: undeclared require(widget) called from ...
-
CLI variables and arguments
-
Package parsing to find widgets etc... for security policy stuff
-
Downloading program archives based on mappings
-
Resource path resolving for packages
-
Hook package testing into
cfx test
BravoJS Comments
-
All internal top-level module paths for packaged modules follow
@/ where '@/' is used to signify the package root. -
Expanded scope of module.load(s, f) to allow a mappings object for 's'.
-
Expanded scope of module.declare([], f) to allow labelled mapping objects for '[]'.
-
Changed module.load(id/mapping, function(id) { ... }) to return the canonical ID of the loaded module that can be used with require(id).
-
Added chained plugin system to service resolvePackageMapping(packageMapping) which must return a top-level package ID if it can resolve.
-
Added module.pkgId which is set to the ID of the containing package for a module if the module is part of a package.
-
Added module.mappings which is set to a resolved map where values are top-level package IDs for a module if the module is part of a package with mappings.
-
Map package UID as valid package ID (in addition to path-basd package ID) if package descriptor has uid property set.
-
Ability to resolve modules by
@/ if the package descriptor has the "uid" property set. e.g. require("http://registry/hostname/path/package1/@/lib/main") This is not ideal as one must know the in this case 'lib/main'. A better solution may be: require("http://registry/hostname/path/package1/@/").resolve("main"); Where '@/' is used to signify that we want to load a special object that can resolve IDs for the specified package ID. -
Relative dependency IDs for module.declare() were resolved based on bravojs.mainModuleDir whereas they should be resolved based on the path of the module.
-
The spec could use more wording as to whether functions accept relative and/or absolute module identifiers only.
-
The
modulesproperty forpackage.jsonis only partially supported and module IDs (keys) must be normalized on server prior to loading.
Specification Comments
CommonJS System
- Need
SYSTEM.os<-uname
CommonJS Modues/2.0draft8
Additions:
-
Need a property to identify the platform in order to load correct platform API modules.
- See: http://stackoverflow.com/questions/4224606/how-to-check-whether-a-script-is-running-under-node-js
- Proposed:
require.platform
-
require("./lib/platform/{platform}/main")where{platform}is replaced withrequire.platform -
Need a way to print to stdout no matter what. Especially important in browser where window.print. should not be over-written. Proposed: module.print
-
New
module.pkgIdproperty -
New
module.hashIdproperty -
New
require.pkg(<packageID>).id(<moduleId>). If no argument forid()the package ID is returned. Iftrueas second argument to.id()the ID is returned unsanitized (context delimiters stay in tact) -
There may not be any delimiters in the pathIDs given by
module.id,module.pkgId -
Need facility to get command line arguments
Changes:
-
Section 5.2.1: Environments that do not support searchable module paths must set
require.paths[0]to the mainModuleDir. -
If
trueas second argument torequire.id()the ID is returned unsanitized (context delimiters stay in tact)
CommonJS Packages/1.1
Additions:
-
uidproperty must end in/. -
uidproperty must be a non-resolving or resolving URL. -
uidmay resolve to a catalog covering the different release branches of the package. -
uidmay resolve to a registry namespace. -
nativeboolean to indicate that modules should be treated as-is (i.e. the package contains modules written for the host platform where require() provided by intermediate loaders should be bypassed at all times and modules should not be wrapper or altered in any way.) -
preloadarray to hold list of moduleIDs for modules to call when initializing package. If moduleId starts with./the ID is relative to the package root. If not it is relative todirectories.libThemain()function of each module is called passing acontextobject. Themain()function may return an object with keys mapping functions to specific hooks.
Notes:
overlayproperty with keys:pinf:{platform}
CommonJS Packages/Mappings/C
Additions:
- Mapping labels may not begin with '_' which is reserved for loaders to map special namespaces.
- Catalog URLs (and any other descriptor URLs) must end in
.jsonto be able to distinguish from<packageUID>
Verify alternate mapping locators:
locator: "/<packagePath>"
locator: "<archiveURL>"
locator: "jar:<archiveURL>!/path/to/package"
locator: {
location: "/<packagePath>"
}
locator: {
location: "<relativePath>"
}
locator: {
catalog: "<catalogURL>",
name: "<packageName>"
}
locator: {
name: "<packageName>",
version: "<packageVersion>",
pm: "<packageManager>" // e.g. "npm"
}
// `archive`-based locators are URLs that must point to a ZIP archive
locator: {
archive: "<archiveURL>"
}
locator: {
archive: "jar:<archiveURL>!/path/to/package"
}
// specifying modules
locator: {
module: "<moduleId>"
}
locator: {
module: "./<modulePathId>"
}
locator: {
module: "/<modulePathId>"
}
// indicate that a mapping (or module) is not available
// causes require() to throw
locator: {
available: false
}
Top-level ID lookup rules when deriving IDs from mapping properties:
- Check for matching
id - Check for matching
uid - Check for matching
uid+version - Check for matching
uid+revision - Check for matching
location
New: Module Mappings
package.json ~ {
"modules": {
"module3": {
"id": "github.com/pinf/loader-js/demos/MapModule/",
"module": "new-module3"
}
"/lib/module3": {},
"./lib/module3": {}
}
}
-
Before module IDs are finalized they are matched against the
modulesproperty. -
The keys are prepended with
directories.lib(if not prefixed with './' or '/') and matched against the final module IDs for the package. -
If a match is found the mapped module is used instead.
-
Resolve mapped module URLs. For example:
"code.jquery.com/": { "locator": { "location": "http://code.jquery.com/jquery-1.6.4.min.js" }, "descriptor": { "uid": "http://code.jquery.com/", "directories": false } }Where
"directories": falsespecifies thatlocator.locationpoints to a URL containing a module in plain text.
CommonJS Programs/A
-
A program is booted by calling the package listed for
boot- NOTE: Multiple
bootpackages (specified as array) are partially supported but will likely be phased out as there are too many side-effects
- NOTE: Multiple
-
All packages listed in
bootmust have matching keys inpackages -
Only packages listed in
packagesmay be loaded into the program -
Only packages listed in
boot(and associated dependencies) are loaded into the program at boot time -
Additional packages may be loaded into program if listed in
packages -
Load contexts to avoid adding already loaded modules to transport files. E.g.: "contexts": { "top": { "github.com/pinf/loader-js/demos/ACE/editor/@/main": { "include": { "github.com/ajaxorg/pilot/@/lib/pilot/index": {}, "github.com/ajaxorg/ace/@/lib/ace/defaults": {}, "github.com/ajaxorg/cockpit/@/lib/cockpit/index": {} }, "load": { "github.com/ajaxorg/ace/": {} } }, "github.com/pinf/loader-js/demos/ACE/worker/@/worker": { } } }
Top-level ID formats
/<packagePath>@/<resourcePath>
<packageUID>@/<resouecePath>
<catalogURL>/<packageName>@/<resouecePath>
Where:
<packagePath>is the UNIX path to a package root directory (no trailing slash, absolute path implied).<resourcePath>is the UNIX path to a resource in the package from the package root (no beginning slash).<packageUID>- is theuidproperty frompackage.jsonwithouthttp://prefix.- If hostname (
uidproperty is a URL) is a known registry server it is dropped as a prefix as well leaving the registry namespace as the<packageUID>.
- If hostname (
Other
require()must look to platformrequire()to resolve top-level IDs that do not resolve within the loader- Actually if a module ID does not resolve locally or via a mapping it should fail
- dependencies for native modules no longer supported
Jetpack Wishlist
- Get current working directory path
- Get environment variables
- Get command-line arguments
- Keep positioning and size of last test/run profile and apply to new profiles
Links
-
CommonJS post: New CommonJS Modules/2 (draft) loader (BravoJS) with package & mappings support
-
Design doc: PINF Fundamental Design: Namespace and Dependency System
-
Design doc: CommonJS Reference Framework