Modules

  • Revision slug: CommonJS/Modules
  • Revision title: Modules
  • Revision id: 93362
  • Created:
  • Creator: Petermichaux
  • Is current revision? No
  • Comment 455 words added, 1 words removed

Revision Content

To date, client side JavaScript has generally been able to get away with something as simple as the <script> tag and no standard way to do namespaces. On the server, it's a bit different because you're more likely to use more libraries and you can potentially load up a lot of code. Having a basic system for loading code and encouraging the use of namespaces to avoid unintentional interference will underlie everything else.

Prior Art

  • Spidermonkey and Rhino offer a load function, but does not have any specific pattern for namespacing.
  • Dojo has a complete incremental loading facility in the form of dojo.require and a standard mechanism for declaring modules. dojo.require ensures that the module is loaded only once.
  • The Jack project implements a simple "require" system.
  • Persevere uses "require" (similar to Jack) for module loading.
  • Helma NG implements a module system with per-module scopes and import, include and require functions.

Proposed API

 

P1) simple file loading

The following is a simple system based on loading files by filename. This is quite Ruby-like.

 
//
// Evaluate the content of the fully specified file
// in the global scope.
//
load('/usr/local/lib/js/File.js')

//
// If no file extension is included '.js' is assumed
//
load('/usr/local/lib/js/File')

//
// Searching through the library path.
// Suppose the path is
// /home/peter/js:/usr/local/lib/js:/usr/lib/js
//
load('File')

//
// Use 'load' above only if this file has never been
// loaded before.
//
load.once('File')

//
// Load a file relative to the current file's path.
// '__DIR__' is a macro expanded to the file's absolute path
// before the code is evaluated. It may be that __DIR__ is
// expanded to be something like
//
// /home/peter/src/foo-project
//
// This allows for one file to load many others distributed
// in the same package.
//
// web-framework.js
// web-framework/
// routing.js
// templates.js
// orm.js
//
// This does not cross over to the browser as the browser does
// not have macros.
//
load(__DIR__+'subdir/foo');

P2) simple object loading

A system similar to the simple file loading as file content is still evaluated in the global scope; however, this system depends on a naming convention between file and object names. This makes it a bit more Java-like and is more heavily dependent on the library path. It removes the need to think about a file system and makes it possible to use the same system in the browser.

 
//
// Searching through the library path.
// Suppose the path is
// /home/peter/js:/usr/local/lib/js:/usr/lib/js
// Then if can evaluate the content of the file
// /usr/local/lib/js/io/File.js in the global scope
// with
load('io.File')

//
// Use 'load' above only if this file has never been
// loaded before.
//
load.once('io.File')

Related discussions

 

Revision Source

<p>To date, client side JavaScript has generally been able to get away with something as simple as the &lt;script&gt; tag and no standard way to do namespaces. On the server, it's a bit different because you're more likely to use more libraries and you can potentially load up a lot of code. Having a basic system for loading code and encouraging the use of namespaces to avoid unintentional interference will underlie everything else.</p>
<h3>Prior Art</h3>
<ul> <li>Spidermonkey and Rhino offer a <a class="external" href="/En/SpiderMonkey/Introduction_to_the_JavaScript_shell" title="https://developer.mozilla.org/editor/fckeditor/core/editor/en/Introduction_to_the_JavaScript_shell">load</a> function, but does not have any specific pattern for namespacing.</li> <li>Dojo has a complete incremental loading facility in the form of <a class="external" href="http://dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-dojo/functions-used-everywhere/dojo-require" title="http://dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-dojo/functions-used-everywhere/dojo-require">dojo.require</a> and a standard mechanism for declaring modules. dojo.require ensures that the module is loaded only once.</li> <li>The Jack project <a class="external" href="http://github.com/tlrobinson/jack/blob/54a28398425287bddd9466955d5e8ea616eb8d47/core.js" title="http://github.com/tlrobinson/jack/blob/54a28398425287bddd9466955d5e8ea616eb8d47/core.js">implements a simple "require" system</a>.</li> <li><a class="external" href="http://docs.persvr.org/documentation/server-side-js" title="http://docs.persvr.org/documentation/server-side-js">Persevere uses "require"</a> (similar to Jack) for module loading.</li> <li>Helma NG implements a <a class="external" href="http://dev.helma.org/ng/Modules+and+Scopes/" title="http://dev.helma.org/ng/Modules+and+Scopes/">module system</a> with per-module scopes and import, include and require functions.</li>
</ul>
<h3>Proposed API</h3>
<p> </p>
<h4>P1) simple file loading</h4>
<p>The following is a simple system based on loading files by filename. This is quite Ruby-like.</p>
<pre><code> <br>//<br>// Evaluate the content of the fully specified file <br>// in the global scope. <br>// <br>load('/usr/local/lib/js/File.js')  <br><br>// <br>// If no file extension is included '.js' is assumed <br>// <br>load('/usr/local/lib/js/File')  <br><br>// <br>// Searching through the library path.  <br>// Suppose the path is <br>// /home/peter/js:/usr/local/lib/js:/usr/lib/js <br>//  <br>load('File')  <br><br>// <br>// Use 'load' above only if this file has never been <br>// loaded before. <br>// <br>load.once('File')  <br><br>//  <br>// Load a file relative to the current file's path. <br>// '__DIR__' is a macro expanded to the file's absolute path <br>// before the code is evaluated. It may be that __DIR__ is <br>// expanded to be something like <br>// <br>//    /home/peter/src/foo-project  <br>// <br>// This allows for one file to load many others distributed <br>// in the same package. <br>// <br>//    web-framework.js <br>//    web-framework/ <br>//      routing.js <br>//      templates.js <br>//      orm.js <br>// <br>// This does not cross over to the browser as the browser does <br>// not have macros. <br>//<br>load(__DIR__+'subdir/foo'); </code></pre>
<h3>P2) simple object loading</h3>
<p>A system similar to the simple file loading as file content is still evaluated in the global scope; however, this system depends on a naming convention between file and object names. This makes it a bit more Java-like and is more heavily dependent on the library path. It removes the need to think about a file system and makes it possible to use the same system in the browser.</p>
<pre><code> <br> // <br> // Searching through the library path.  <br> // Suppose the path is <br> // /home/peter/js:/usr/local/lib/js:/usr/lib/js <br> // Then if can evaluate the content of the file <br> // /usr/local/lib/js/io/File.js in the global scope <br> // with<br> load('io.File')  <br> <br> // <br> // Use 'load' above only if this file has never been <br> // loaded before. <br> // <br> load.once('io.File')  <br> <br> </code></pre>
<h3>Related discussions</h3>
<ul> <li><a class="external" href="http://groups.google.com/group/serverjs/browse_thread/thread/d761996c25769e6c" title="http://groups.google.com/group/serverjs/browse_thread/thread/d761996c25769e6c">"a module system (difficult to agree)"<br> </a> </li>
</ul>
<p> </p>
Revert to this revision