Permalink
Browse files

Updated the modules specification with define() and without camelCase…

… module identifiers and without require.paths
  • Loading branch information...
kriskowal committed May 31, 2011
1 parent 0056dc7 commit 5d62837c6ccf3c65a0bd4f1617f5f7cab79a810c
Showing with 121 additions and 81 deletions.
  1. +121 −81 modules/specification.md
View
@@ -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.

0 comments on commit 5d62837

Please sign in to comment.