forked from kriskowal/uncommonjs
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updated the modules specification with define() and without camelCase…
… module identifiers and without require.paths
- Loading branch information
Showing
1 changed file
with
121 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,99 +1,139 @@ | ||
|
||
This specification addresses how modules should be written in order to | ||
be interoperable among a class of module systems that can be both client | ||
and server side, secure or insecure, implemented today or supported by | ||
future systems with syntax extensions. These modules are offered | ||
privacy of their top scope, facility for importing singleton objects | ||
from other modules, and exporting their own API. By implication, this | ||
specification defines the minimum features that a module system must | ||
provide in order to support interoperable modules. | ||
|
||
|
||
Require | ||
------- | ||
|
||
1. ``require`` is a Function | ||
1. The ``require`` function accepts a module identifier. | ||
1. ``require`` returns the exported API of the foreign module. | ||
1. If there is a dependency cycle, the foreign module may not have | ||
finished executing at the time it is required by one of its | ||
transitive dependencies; in this case, the object returned by | ||
``require`` must contain at least the exports that the foreign | ||
module has prepared before the call to require that led to the | ||
current module's execution. | ||
1. If the requested module cannot be returned, ``require`` must | ||
throw an error. | ||
1. The ``require`` function may have a ``main`` property. | ||
1. This attribute, when feasible, should be read-only, don't | ||
delete. | ||
1. The ``main`` property must either be undefined or be identical | ||
to the ``module`` object in the context of one loaded module. | ||
1. The ``require`` function may have a ``paths`` attribute, that is | ||
a prioritized Array of path Strings, from high to low, of paths | ||
to top-level module directories. | ||
1. The ``paths`` property must not exist in "sandbox" (a | ||
secured module system). | ||
1. The ``paths`` attribute must be referentially identical in all | ||
modules. | ||
1. Replacing the ``paths`` object with an alternate object may | ||
have no effect. | ||
1. If the ``paths`` attribute exists, in-place modification of | ||
the contents of ``paths`` must be reflected by corresponding | ||
module search behavior. | ||
1. If the ``paths`` attribute exists, it may not be an | ||
exhaustive list of search paths, as the loader may | ||
internally look in other locations before or after the | ||
mentioned paths. | ||
1. If the ``paths`` attribute exists, it is the loader's | ||
prorogative to resolve, normalize, or canonicalize the paths | ||
provided. | ||
|
||
Module Context | ||
-------------- | ||
|
||
1. In a module, there is a free variable ``require``, which conforms to | ||
the above definiton. | ||
1. In a module, there is a free variable called ``exports``, that is an | ||
object that the module may add its API to as it executes. | ||
1. modules must use the ``exports`` object as the only means of | ||
exporting. | ||
1. In a module, there must be a free variable ``module``, that is | ||
an Object. | ||
1. The ``module`` object must have a ``id`` property that is the | ||
top-level ``id`` of the module. The ``id`` property must be | ||
such that ``require(module.id)`` will return the exports object | ||
from which the ``module.id`` originated. (That is to say | ||
module.id can be passed to another module, and requiring that | ||
must return the original module). When feasible this property | ||
should be read-only, don't delete. | ||
1. The ``module`` object may have a ``uri`` String that is the | ||
fully-qualified URI to the resource from which the module was | ||
created. The ``uri`` property must not exist in a sandbox. | ||
This specification establishes a convention for creating a style of | ||
reusable JavaScript modules and systems that will load and link those | ||
modules. | ||
|
||
* Modules are singletons. | ||
* Modules have an implicitly isolated lexical scope. | ||
* Loading may be eager in asynchronous loaders. | ||
* Execution must be lazy. | ||
* With some care, modules may have cyclic dependencies. | ||
* Systems of modules may be isolated but still share the same context. | ||
* Modules may be used both in browsers and servers. | ||
|
||
|
||
Guarantees Made by Module Writers | ||
================================= | ||
|
||
1. A module must only read and write variables in its lexical scope. | ||
1. A module must only assume that its lexical scope contains the free | ||
variables ``require``, ``module``, ``exports``, and ``define`` | ||
beyond those defined by JavaScript. *What constitutes JavaScript is | ||
beyond the scope of this specification and may vary with practical | ||
limits on a module's portability.* | ||
1. A module must only depend on specified behavior of the values | ||
provided to its lexical scope. | ||
1. All calls to ``require`` must be by name from lexical scope. | ||
1. All calls to ``require`` must be given a single string literal as | ||
the argument. | ||
1. For interoperability with loaders that support the following cases, | ||
modules must call ``define`` in their first and only module scope | ||
statement. | ||
* When modules must be **debugged when deployed** on a different | ||
domain than the origin page (perhaps a CDN) in browsers that do | ||
not support cross-origin HTTP request headers (CORS) or the | ||
developer cannot configure the deployment server to provide CORS | ||
headers. JavaScript that is deployed in a debuggable form will | ||
suffer performance penalties since it would preclude | ||
minification and bundling. | ||
* modules must be debugged in browsers that do not support | ||
``//@sourceURL`` comments **and** (a module build step **or** | ||
module server that add ``define`` calls are not acceptable). | ||
1. Within a ``define`` ``callback``, the variables ``require``, | ||
``exports``, and ``module`` must use the corresponding values | ||
provided as arguments to the callback instead of those received from | ||
lexical scope. | ||
1. The first argument, ``require``, to a ``define`` ``callback`` must | ||
be named ``require``. | ||
|
||
|
||
Guarantees Made by Module Interpreters | ||
====================================== | ||
|
||
1. The top scope of a module must not be shared with any other module. | ||
1. A ``require`` function must exist in a function's lexical scope. | ||
1. The ``require`` function must accept a module identifier as its | ||
first and only argument. | ||
1. ``require`` must return the same value as ``module.exports`` in | ||
the identified module, or must throw an exception while trying. | ||
1. ``require`` may have a ``main`` property. | ||
1. The ``require.main`` property may be read-only and | ||
non-configurable. | ||
1. The ``require.main`` property must be the same value as | ||
``module`` in the lexical scope of the first module that | ||
began executing in the current system of modules. | ||
1. The ``require.main`` property must be the same value in | ||
every module. | ||
1. an ``exports`` object must exist in a function's lexical scope. | ||
1. the ``exports`` object must initially be the same value as | ||
``module.exports``. | ||
1. A ``module`` object must exist in a function's lexical scope. | ||
1. The ``module`` object must have an ``id`` property. | ||
1. The ``module.id`` property must be a module identifier such | ||
that ``require(module.id)`` must return the | ||
``module.exports`` value when called in this or any module | ||
in the same system of modules. | ||
1. The ``module.id`` property may be read-only and | ||
non-configurable. | ||
1. The ``module`` object must have an ``exports`` property. | ||
1. The ``module.exports`` property must initially be an empty | ||
object. | ||
1. The ``module.exports`` property must be writable and | ||
configurable. | ||
1. The ``module`` object may have a ``path`` URL relative to | ||
``file:///`` | ||
1. The ``module`` object may have a ``directory`` URL relative to | ||
``file:///`` | ||
1. The directory must be the directory containing the ``path``. | ||
1. a ``define`` function must exist in a function's lexical scope. | ||
1. ``define`` accepts a function ("callback") as its last argument. | ||
1. ``callback`` accepts ``require``, ``exports``, and ``module``. | ||
1. ``callback`` must be called with the corresponding values from | ||
the module's lexical scope. | ||
1. If ``callback`` returns a value other than ``undefined``, the | ||
return value must be assigned to ``module.exports``. | ||
|
||
|
||
Module Identifiers | ||
------------------ | ||
================== | ||
|
||
1. A module identifier is a String of "terms" delimited by forward | ||
1. A module identifier is a string of "terms" delimited by forward | ||
slashes. | ||
1. A term must be a camelCase identifier, ``.``, or ``..``. | ||
1. Module identifiers may not have file-name extensions like ``.js``. | ||
1. Module identifiers may be "relative" or "top-level". A module | ||
1. A term is either: | ||
1. any combination of lower-case letters, numbers, and hyphens, | ||
1. ``.``, or | ||
1. ``..`` | ||
1. Module identifiers should not have file-name extensions like | ||
``.js``. | ||
1. Module identifiers may be "relative" or "resolved". A module | ||
identifier is "relative" if the first term is ``.`` or ``..``. | ||
1. Top-level identifiers are resolved off the conceptual module name | ||
space root. | ||
1. Relative identifiers are resolved relative to the identifier of the | ||
module in which ``require`` is written and called. | ||
1. Top-level identifiers are resolved relative to ``""``. | ||
1. The ``require`` function in each module resolves relative | ||
identifiers from the corresponding ``module.id``. | ||
1. To resolve a module identifier, | ||
1. an array of terms must be initialized to an empty array. | ||
1. For each ordered term in some ordered module identifiers, from | ||
left to right, | ||
1. no action is taken for ``"."`` terms, | ||
1. a term is popped off the end of the array for ``".."`` | ||
terms, and | ||
1. the term is pushed on the end of the array for all other | ||
terms. | ||
1. The array of terms must be joined with forward slashes, ``"/"`` | ||
to construct the resulting "resolved" identifier. | ||
|
||
|
||
|
||
Unspecified | ||
----------- | ||
=========== | ||
|
||
This specification leaves the following important points of | ||
interoperability unspecified: | ||
|
||
1. Whether modules are stored with a database, file system, or factory | ||
functions, or are interchangeable with link libraries. | ||
1. Whether a PATH is supported by the module loader for resolving | ||
1. Whether a path is supported by the module loader for resolving | ||
module identifiers. | ||
1. Whether other arguments may be provided to ``define`` and how they | ||
are interpreted. | ||
|