a clean and simple module system for javascript.
- provides a concise syntax for the creation and use of modular code
- more functional, simpler and easier to use than requireJs
- non-modules can be made to be a module quickly without changing their code
- because only exported bindings of a module are accessible to module users, internal utility bindings can not create name conflicts in the top-level namespace (information encapsulation)
- modules are sets of variables stored in predictably named global objects
- multiple modules can be defined in a single file
- autoload for modules that are not already loaded. maps module names to url paths and uses a load path base url
- module code is not executed unless all dependencies are ready
let /srv/http
be our web server root, it could be any path.
in file /srv/http/lib/javascript/a/b/c.js
, define a module:
module.define("a.b.c", function (export) {
var myvariable = 1
export({myvariable: myvariable})
})
in another file, say /srv/http/x.js
, include the module:
module.loadPath("/lib/javascript/")
module("a.b.c", function () {
console.log("a variable from module a.b.c: ", a.b.c.myvariable)
// all "a.b.c" bindings are available in the global object a.b.c
})
define a module named "a.b.c" with dependencies on other modules named "d" and "e.f":
module.define("a.b.c", ["d", "e.f"], function (export) {
var a = 1
export({a: a})
})
include multiple modules:
module(["a.b.c", "d.e", "f"], function () {
// module bindings available in the objects a.b.c, d.e and f
})
load and wrap a plain javascript file:
module.wrap("jquery", "plain/jquery.js")
all bindings will be available as if the javascript file had been loaded separately. an empty global object "jquery" will be created.
or in case the plain javascript file is already loaded, define an empty module:
module.define("jquery")
include module.js
or module.compat.js
in the code of your web application.
for example in an html file:
<script src="module.js"></script>
<script src="yourcode.js"></script>
module.define(name, imports, body)
// module.define :: string, [string\array(string, ...)], function(function)
module.define(name, body)
module.define(name)
the last form creates an empty object for the module if an object with the name does not already exist.
unless you wrap javascript code in a module.define
with a list of exports, bindings of the plain javascript file will not be made available in a global object named like the module.
but for dependency resolution it is possible to define an empty module after the code has been loaded.
use module.define(). for example when the plain javascript file has already been loaded but should be available as a possible module dependency.
module.define(name)
this is equivalent to using module.define
and calling export
without arguments.
module.wrap(name, nonModulePath, body)
// module.wrap :: string, string, [function(function)]
module.wrap(name, nonModulePath)
nonModulePath
is a typical filesystem path with "/" and filename extension, relative to loadPath
.
the file will be evaluated as if it was included at the top-level.
module(imports, body)
// module :: string\array(string, ...), function
module.loadPath("/lib/javascript")
// module.loadPath :: string
usually relative to a web server root. the default load path is the current directory. setting the load path would usually only be necessary once.
names are strings of arbitrary length, corresponding to relative paths under load path which identify javascript files, with "/" replaced by dots and without filename extensions.
- load path: "/lib/javascript/"
- module path: "/lib/javascript/a/b/c.js"
- module name: "a.b.c"
there are two builds with equivalent functionality - one only for modern browsers, and one for modern and older browsers.
module.js
runs only on browsers supporting at least javascript 1.8, that is, all common, up to date browsers in the year 2012.module.compat.js
is likemodule.js
but includes support for older browser versions, for example microsoft internet explorer before version 9.
module.js is implemented in plain javascript, ~11 kilobits minified and gzipped, and uses ded/script.js to autoload dependencies.
- modules are never imported multiple times
- dependencies are loaded asynchronuously
- module.js part of the code: gpl3 or later versions.
module.src.js
contains easily visible comments for detailed licensing information - module.js documentation including this text: cc-by-sa
- browserify (mit license) uses modules defined like node.js modules and creates one pre-compiled file