wq would be an obvious name for one.)
In programming, a module is a small building block that has clearly delineated inputs and outputs. An ideal module does only one task and does it well. This separation of concerns makes each individual module easier to maintain, and also easier to reuse in other programs that require the same functionality. Most module systems have two technical characteristics that make this possible:
<script> tag order so that each bit of code would be available before the code that depended on it. In addition, the lack of a private scope meant that libraries all shared the same global namespace. To reduce the possibility for naming collisions, it became common (and still is) for libraries to define a single global object (e.g.
$) and add each piece of functionality as a subproperty (
$.ajax()). Even then, there could be conflicts between libraries if they picked the same global name.
Like module systems in other languages, Node uses a synchronous syntax for declaring and loading dependencies. This means that modules are loaded immediately when they are requested. This works great in a server environment when the necessary files are all available locally. However, this obviously does not work well in the web environment, where each file must be requested separately and potentially asynchronously.
The typical way to bring Node modules to the browser is to first combine them into a single file (typically using Browserify), complete with the minimum amount of scripting needed to resolve dependencies within the single file. While this works for many projects, it constrains the flexibility of the dynamic web and effectively rules out asynchronous module resolution (though attempts are being made to address this). In addition, the Node+Browserify module format is unique to the Node ecosystem, and there are few (if any) alternative implementations.
export, and like Python it is possible to request only certain variables from another module. The ES6 module concept incorporates the notion of asynchronous dependency loading, however the mechanics for this are yet to be worked out. In addition, it may be a while before browsers supporting ES6 modules reach widespread adoption. It is possible to write modules in ES6 and then have them transpiled into the other two module systems, though this introduces a level of complexity into the workflow. In short, ES modules aren't done yet.
A core priority of wq is compatibility with the widest possible array of technologies, to ensure that no potential contributor is left behind. Thus, we'll need to wait a bit longer before adopting ES6 modules, unfortunately.
In order to support asynchronous dependency loading while maintaining backwards compatibility with old browsers, AMD modules are defined by calling a function (
define), with the content of the module as a callback function. Needless to say, this is a bit ugly compared to the simple elegance of ES6 module imports (and, to a lesser extent, the CommonJS/Node
require()). Nevertheless, the wide cross-platform capabilities of AMD make it a compelling choice as the module system for wq.app.