Helma Logo
main list history

Version 6 by Kris Kowal on 06. September 2008, 22:57

3discussion at http://groups.google.com/group/helma-ng/browse_thread/thread/6d002cb42a47ae42
4

Version 5 by Kris Kowal on 06. September 2008, 20:26

37* All objects in the transitive closure of accessible through <tt>global</tt> on item selection MAY be frozen.
38* The <tt>global</tt> object MAY contain more values properties than specified.

Version 4 by Kris Kowal on 06. September 2008, 20:13

5* map one file to one module (while leaving room and reserve names for implementation-specific multi-module bundling for website performance)performance,
6* cache memoize singleton module objects before executing the corresponding module file,
11
13The specification is intended to narrow the domain in which JavaScript modules can universally depend to maximize portability.
15The specification encourages modules is intended to adhere to describe a strict subset of the JavaScript environment in which execution context that conformant JavaScript modules can depend upon such that they may be loadedused with all conformant module loadersIn spirit, this is This execution context could inform a theoretical version of the JavaScript language that provides the intersection of behaviors provided by Class-A browsers "lint" implementation to verify conformance and server-side runtimes including Rhinopermit additional variable renaming options for source code compressors like Packer, plus this system for loading modulesShrinkSafe, and YUICompressor.
20The singleton <tt>module</tt> object MUST be declared and cached memoized BEFORE the correpsonding module file is executed.  The module file MUST only be executed ONCE for the duration of a page-view or JavaScript program.
25* <tt>builtins</tt>
26* <tt>moduleScope</tt><tt>global</tt>
27* <tt>local</tt>
29== <tt>builtins</tt> ==
31== <tt>global</tt> ==
32
33* The <tt>builtins</tt> object MAY be frozen.
34* All objects in the transitive closure of <tt>builtins</tt> on item selection The <tt>global</tt> object MAY be frozen.
35* The <tt>builtins</tt> object All objects in the transitive closure of <tt>global</tt> on item selection MAY contain more values than specifiedbe frozen.
36* The <tt>builtins</tt> <tt>global</tt> object MUST include:MAY contain more values than specified.
37* The <tt>global</tt> object MUST include:
48* All objects in <tt>builtins</tt> <tt>global</tt> MUST conform to the JavaScript subset described in the introduction: one that consists of the intersection of behaviors of the respective objects in all Grade-A browsers and server-side JavaScript environments.
51* Modules MUST NOT write items to the <tt>builtins</tt> object.
52* Modules MUST NOT modify any object in the transitive closure through references on the <tt>builtins</tt> object.
53* Modules MUST NOT access any items in the <tt>builtins</tt> object not herein specified.
54* Modules MUST NOT use non-standard features provided by <tt>builtins</tt>.
53* Modules MUST NOT modify the <tt>global</tt> object.
54* Modules MUST NOT modify any object accessible through references from <tt>global</tt>.
55* Modules MUST NOT access any properties in the <tt>global</tt> object not herein specified.
56* Modules MUST NOT use non-standard features provided by objects accessible from <tt>global</tt>.
55== <tt>moduleScope</tt> ==
57The <tt>moduleScope</tt> is a module's private namespace for module loader functions and imported values.== <tt>local</tt> ==
59The <tt>moduleScope</tt> MUST provide:<tt>local</tt> object is a module's private namespace for module loader functions and imported values.
61* <tt>builtins</tt>The <tt>local</tt> object MUST provide:
62
63* <tt>global</tt>
70The <tt>moduleScope</tt> <tt>local</tt> object MAY provide:provide the following functions for web-site implementations that need to support multi-module bundling.  These functions would permit module constructor functions for more than one module file to be collected in a single file.
75Modules MAY augment the <tt>moduleScope</tt> <tt>local</tt> object with additional items.
77Modules MUST NOT overwrite the items replace properties specified here.
85The <tt>require</tt> function returns an object with items properties copied from a foreign module.  The required module is referenced with URL refers to a URLfile that could be executed to construct the module object.  By default, all items properties from the foreign module are copied into the returned object.  The returned object MAY be frozen.  Modules MUST NOT modify the returned object.  If a <tt>structure</tt> is provided, a subset of the items from the foreign module will be returned, the result of <tt>destructure(</tt><i>&lt;module&gt;</i><tt>, </tt><i>&lt;structure&gt;</i><tt>)</tt>.  If a function in the foreign module was declared with the <tt>foreignModuleBind</tt> decorator, the corresponding item in the returned object is the result of <tt>bind(</tt><i>&lt;function&gt;</i><tt>, <tt><i>&lt;foreignModule&gt;</i><tt>)</tt>.
87The returned object MAY be frozen.
88
89Modules MUST NOT modify the returned object.
90
91If a <tt>structure</tt> is provided, a subset of the items from the foreign module will be returned, the result of <tt>destructure(</tt><i>&lt;module&gt;</i><tt>, </tt><i>&lt;structure&gt;</i><tt>)</tt>.  If a function in the foreign module was declared with the <tt>foreignModuleBind</tt> decorator, the corresponding item in the returned object is the result of <tt>bind(</tt><i>&lt;function&gt;</i><tt>, <tt><i>&lt;foreignModule&gt;</i><tt>)</tt>.
92
92* Directory components names and file names in modules MUST be in <tt>camelCase</tt>.
113      log("foo called from: " + this.moduleScopelocal.moduleUrl);
119For the purpose of this specification, the "destructure" function has the following semantics.  If the structure is an <tt>Array</tt>, the returned <tt>Object</tt> contains the items properties from the given <i>&lt;object&gt;</i> corresponding to the keys provided in the given <tt>Array</tt> structure.  If the structure is an <tt>Object</tt>, the returned object contains items properties where each key corresponds to a value in the structure, and the value is a value from the object corresponding to the key in the structure.  For example:
127The <tt>module</tt> object is a module's public interface.  Adding items to the <tt>module</tt> object makes them available for export to other module <tt>local</tt> scopes.  To that end, the <tt>module</tt> object is mutable.  The <tt>module</tt> object MUST provide a <tt>moduleScope</tt><tt>local</tt> object.  Modules MAY augment the module object.
140== <tt>log(</tt><i>&lt;message&gt;</i><tt><tt>print(</tt><i>&lt;message&gt;</i><tt>, </tt><i>[&lt;label&gt;]</i>)</tt> ==
142<tt>log</tt> <tt>print</tt> is a simple console logging function.
144The module loader MAY ignore calls to <tt>log</tt><tt>print</tt>.  The module loader MAY ignore the label argument.
147
159This specification outlines the process of requiring modules from within other modules.  However, in a browser's global execution context, JavaScript execution blocks are not modules.  To that end, this specification does not require that the module loader be invoked in any particluar fashion.  A particular implementation might hook an initial module to be loaded from within a script tag.  Another implementation might scan the DOM for script tags with an alternate language attribute and execute them as modules with the current page's URL as their module URL.  This specification only exists to maximize the portability of module files.
164A future version of the ECMAScript standard might specify new syntax and semantics for importing modules.  Current discussions about this feature trend toward having new syntax that "desugars" to native JavaScript.  To that end, I propose the following syntax and desugaring transformations in the context of this specification:specification.  The top line of each pair is akin to Python's import syntax and stands in for whatever syntax the next version of JavaScript divines.  The second line is an equivalent, desugared version using the module system specified here.

Version 3 by Kris Kowal on 06. September 2008, 07:24

65
76
90The <tt>require</tt> function returns an object with items from a foreign module.  The required module is referenced with a URL.  By default, all items from the foreign module are copied into the returned object.  The returned object MAY be frozen.  Modules MUST NOT modify the returned object.  If a <tt>structure</tt> is provided, a subset of the items from the foreign module will be returned, the result of <tt>destructure(</tt><i>&lt;module&gt;</i><tt>, </tt><i>&lt;structure&gt;</i><tt>)</tt>.  If a function in the foreign module was declared with the <tt>foreignModuleBind</tt> decorator, the corresponding item in the returned object is the result of <i>&lt;foreignModule&gt;</i><tt>.moduleScope.moduleBind(</tt><i>&lt;name&gt;</i><tt><tt>bind(</tt><i>&lt;function&gt;</i><tt>, </tt><i>&lt;value&gt;</i><tt>)</tt><tt><i>&lt;foreignModule&gt;</i><tt>)</tt>.
95
135
140
145

Version 2 by Kris Kowal on 04. September 2008, 20:46

1= JavaScript Module Standard (Proposal) =
2
19== Module Execution Context ==
31=== <tt>builtins</tt> ===
61=== <tt>moduleScope</tt> ===
84== Module Loading ==
87=== <tt>require(</tt><i>&lt;moduleUrl&gt;</i><tt>, </tt><i>[&lt;structure&gt;]</i><tt>)</tt> ===
103=== <tt>include(</tt><i>&lt;moduleUrl&gt;</i><tt>, </tt><i>[&lt;structure&gt;]</i><tt>)</tt> ===
108=== <tt>foreignModuleBind(</tt><i>&lt;function&gt;</i><tt>)</tt> ===
119=== <tt>destructure(</tt><i>&lt;object&gt;</i><tt>, </tt><i>&lt;structure&gt;</i><tt>)</tt> ===
127=== <tt>module</tt> ===
132=== <tt>moduleRootUrl</tt> ===
136=== <tt>moduleUrl</tt> ===
140=== <tt>log(</tt><i>&lt;message&gt;</i><tt>, </tt><i>[&lt;label&gt;]</i>)</tt> ===
155== Afterword: Browser Implementations ==
160== Afterword: ECMAScript <tt>import</tt> semantics. ==

Version 1 by Kris Kowal on 04. September 2008, 20:37

1= JavaScript Module Standard (Proposal) =
2
3from http://modulesjs.com/standard-proposal.html
4
5The purpose of this document is to propose a contract between a collection of JavaScript module loaders and modules.  The specification describes the environment that module loader implementations provide, and the environment that modules may depend upon.  In particular, compliant module systems:
6
7* map one file to one module (while leaving room for implementation-specific multi-module bundling for website performance),
8* cache singleton module objects before executing the corresponding module file,
9* execute modules with a featureful context,
10* resolve module URLs relative to a module path, and
11* conform to a domain-name-based site-package naming convention and leave a name-space for a centrally managed standard library.
12
13The specification is intended to be suitable for client- and server-side JavaScript module loader implementations.
14The specification is intended to provide insights and an easy migration path to future versions of JavaScript.
15The specification is intended to narrow the domain in which JavaScript modules can universally depend to maximize portability.
16
17The specification encourages modules to adhere to a strict subset of the JavaScript environment in which they may be loaded.  In spirit, this is a theoretical version of the JavaScript language that provides the intersection of behaviors provided by Class-A browsers and server-side runtimes including Rhino, plus this system for loading modules.
18
19
20== Module Execution Context ==
21
22The singleton <tt>module</tt> object MUST be declared and cached BEFORE the correpsonding module file is executed.  The module file MUST only be executed ONCE for the duration of a page-view or JavaScript program.
23
24In a module file's execution context, the context object, represented by <tt>this</tt>, MUST be the <tt>module</tt> object.
25
26The scope chain, from global to local, of a module file's execution context MUST consist of:
27* <tt>builtins</tt>
28* <tt>moduleScope</tt>
29* <tt>module</tt>
30* <i>&lt;anonymous&gt;</i>
31
32=== <tt>builtins</tt> ===
33
34Rules for module systems:
35* The <tt>builtins</tt> object MAY be frozen.
36* All objects in the transitive closure of <tt>builtins</tt> on item selection MAY be frozen.
37* The <tt>builtins</tt> object MAY contain more values than specified.
38* The <tt>builtins</tt> object MUST include:
39** <tt>String</tt>
40** <tt>Number</tt>
41** <tt>Boolean</tt>
42** <tt>Object</tt>
43** <tt>Array</tt>
44** <tt>Date</tt>
45** <tt>RegExp</tt>
46** <tt>Error</tt>
47** <tt>EvalError</tt>
48** <tt>RangeError</tt>
49** <tt>ReferenceError</tt>
50** <tt>SyntaxError</tt>
51** <tt>TypeError</tt>
52* The module loader MAY enforce these invariants at any time.  In some environments, verifying these invariants will not be possible or pragmatic.
53* All objects in <tt>builtins</tt> MUST conform to the JavaScript subset described in the introduction: one that consists of the intersection of behaviors of the respective objects in all Grade-A browsers and server-side JavaScript environments.
54
55Rules for modules:
56* Modules MUST NOT write items to the <tt>builtins</tt> object.
57* Modules MUST NOT modify any object in the transitive closure through references on the <tt>builtins</tt> object.
58* Modules MUST NOT access any items in the <tt>builtins</tt> object not herein specified.
59* Modules MUST NOT use non-standard features provided by <tt>builtins</tt>.
60
61
62=== <tt>moduleScope</tt> ===
63
64The <tt>moduleScope</tt> is a module's private namespace for module loader functions and imported values.
65
66The <tt>moduleScope</tt> MUST provide:
67* <tt>builtins</tt>
68* <tt>module</tt>
69* <tt>moduleUrl</tt>
70* <tt>moduleRootUrl</tt>
71* <tt>require</tt>
72* <tt>include</tt>
73* <tt>foreignModuleBind</tt>
74* <tt>log</tt>
75
76The <tt>moduleScope</tt> MAY provide:
77* <tt>register</tt>
78* <tt>publish</tt>
79
80Modules MAY augment the <tt>moduleScope</tt> with additional items.
81
82Modules MUST NOT overwrite the items specified here.
83
84
85== Module Loading ==
86
87
88=== <tt>require(</tt><i>&lt;moduleUrl&gt;</i><tt>, </tt><i>[&lt;structure&gt;]</i><tt>)</tt> ===
89
90The <tt>require</tt> function returns an object with items from a foreign module.  The required module is referenced with a URL.  By default, all items from the foreign module are copied into the returned object.  The returned object MAY be frozen.  Modules MUST NOT modify the returned object.  If a <tt>structure</tt> is provided, a subset of the items from the foreign module will be returned, the result of <tt>destructure(</tt><i>&lt;module&gt;</i><tt>, </tt><i>&lt;structure&gt;</i><tt>)</tt>.  If a function in the foreign module was declared with the <tt>foreignModuleBind</tt> decorator, the corresponding item in the returned object is the result of <i>&lt;foreignModule&gt;</i><tt>.moduleScope.moduleBind(</tt><i>&lt;name&gt;</i><tt>, </tt><i>&lt;value&gt;</i><tt>)</tt>.
91
92If the URL begins with a dot, ("."), the fully qualified URL for the requested module is resolved relative to the fully qualified URL of the current module.  This would be the result of <tt>urlJoin(moduleRootUrl, moduleUrl, foreignModuleUrl)</tt>.  Otherwise the fully qualified URL is <tt>urlJoin(moduleRootUrl, foreignModuleUrl)</tt>.
93
94Regarding module file names:
95* Directory components and file names in modules MUST be in <tt>camelCase</tt>.
96* Modules MUST have a ".js" extension if they are provided by files.
97* Modules MUST not have an extension if they are provided by the module loader but are not backed by real files.  This might include a "window" module in a particular browser implementation.
98* The module root is reserved for a cross-browser JavaScript standard library.
99* Modules provided by entities other than the standard library MUST exist in a subdirectory of the module root corresponding to a domain name controlled by the author, or a subdirectory thereof.
100
101Module authors are encouraged to use module relative URLs to increase the mobility of entire directory trees of modules.
102
103
104=== <tt>include(</tt><i>&lt;moduleUrl&gt;</i><tt>, </tt><i>[&lt;structure&gt;]</i><tt>)</tt> ===
105
106The <tt>include</tt> function defers to <tt>require</tt>, both its arguments and its return value.  However, <tt>include</tt> also copies all of the items from the object returned by <tt>require</tt> to the <tt>moduleScope</tt> object.
107
108
109=== <tt>foreignModuleBind(</tt><i>&lt;function&gt;</i><tt>)</tt> ===
110
111A function decorator that denotes that the module loader will guarantees that, when the decorated function is called, it will receive the <tt>module</tt> object for the module file in which it was called as its context object: <tt>this</tt>.  <tt>foreignModuleBind</tt> MAY return the same <tt>Function</tt> it was passed.  The returned function MUST be usable in the module in which it was declared as if it were the function passed to <tt>foreingModuleBind</tt>.  <tt>foreignModuleBind</tt> MAY modify properties of the given <tt>Function</tt>.
112
113For example:
114
115  this.foo = foreignModuleBind(function () {
116      log("foo called from: " + this.moduleScope.moduleUrl);
117  });
118
119
120=== <tt>destructure(</tt><i>&lt;object&gt;</i><tt>, </tt><i>&lt;structure&gt;</i><tt>)</tt> ===
121
122For the purpose of this specification, the "destructure" function has the following semantics.  If the structure is an <tt>Array</tt>, the returned <tt>Object</tt> contains the items from the given <i>&lt;object&gt;</i> corresponding to the keys provided in the given <tt>Array</tt> structure.  If the structure is an <tt>Object</tt>, the returned object contains items where each key corresponds to a value in the structure, and the value is a value from the object corresponding to the key in the structure.  For example:
123
124* <tt>destructure({"a": 10, "b": 20}, ["a"]) == {"a": 10}</tt>
125* <tt>destructure({"a": 10, "b": 20}, {"a": "A"}) == {"A": 10}</tt>
126
127
128=== <tt>module</tt> ===
129
130The <tt>module</tt> object is a module's public interface.  Adding items to the <tt>module</tt> object makes them available for export to other module scopes.  To that end, the <tt>module</tt> object is mutable.  The <tt>module</tt> object MUST provide a <tt>moduleScope</tt>.  Modules MAY augment the module object.
131
132
133=== <tt>moduleRootUrl</tt> ===
134<tt>moduleRootUrl</tt> is the fully qualified URL of the JavaScript site-packages directory: the module root.
135
136
137=== <tt>moduleUrl</tt> ===
138<tt>moduleUrl</tt> is the relative URL of the current module file relative to <tt>moduleRootUrl</tt>.
139
140
141=== <tt>log(</tt><i>&lt;message&gt;</i><tt>, </tt><i>[&lt;label&gt;]</i>)</tt> ===
142<tt>log</tt> is a simple console logging function.
143
144The module loader MAY ignore calls to <tt>log</tt>.  The module loader MAY ignore the label argument.
145
146The optional label MAY be any string, and MUST be suitable for use as a CSS class-name (preferably lower-case delimited by hyphens) of which the following MAY be significant:
147* info
148* warn
149* error
150* module
151* help
152* pass
153* fail
154
155
156== Afterword: Browser Implementations ==
157
158This specification outlines the process of requiring modules from within other modules.  However, in a browser's global context, JavaScript execution blocks are not modules.  To that end, this specification does not require that the module loader be invoked in any particluar fashion.  A particular implementation might hook an initial module to be loaded from within a script tag.  Another implementation might scan the DOM for script tags with an alternate language attribute and execute them as modules with the current page's URL as their module URL.
159
160
161== Afterword: ECMAScript <tt>import</tt> semantics. ==
162
163A future version of the ECMAScript standard might specify new syntax and semantics for importing modules.  Current discussions about this feature trend toward having new syntax that "desugars" to native JavaScript.  To that end, I propose the following syntax and desugaring transformations in the context of this specification:
164
165* <tt>import "</tt><i>&lt;moduleUrl&gt;</i><tt>" as </tt><i>&lt;moduleName&gt;</i>;</tt>
166* <tt>module.</tt><i>&lt;moduleName&gt;</i><tt> = require("</tt><i>&lt;moduleUrl&gt;</i><tt>");</tt>
167
168* <tt>from "</tt><i>&lt;moduleUrl&gt;</i><tt>" import *;</tt>
169* <tt>include("</tt><i>&lt;moduleUrl&gt;</i><tt>");</tt>
170
171* <tt>from "</tt><i>&lt;moduleUrl&gt;</i><tt>" import </tt><i>&lt;a&gt;</i><tt>;</tt>
172* <tt>include("</tt><i>&lt;moduleUrl&gt;</i><tt>", ["</tt><i>&lt;a&gt;</i><tt>"]);</tt>
173
174* <tt>from "</tt><i>&lt;moduleUrl&gt;</i><tt>" import </tt><i>&lt;a&gt;</i><tt> as </tt><i>&lt;a&apos;&gt;</i><tt>;</tt>
175* <tt>include("</tt><i>&lt;moduleUrl&gt;</i><tt>", {"</tt><i>&lt;a&gt;</i><tt>": "</tt><i>&lt;a&apos;&gt;</i><tt>"});</tt>
176
177