STATUS: SUPERSEDED BY 1.1
状态: 被Modules/1.1取代
Implementations:
Flusspferd, GLUEscript, GPSEE, JSBuild, Narwhal (0.1), Persevere, RingoJS, SproutCore 1.1/Tiki, node.js, TeaJS (formerly v8cgi), CouchDB, Smart Platform, Yabble, Wakanda, XULJet
实现实例:
Flusspferd, GLUEscript, GPSEE, JSBuild, Narwhal (0.1), Persevere, RingoJS, SproutCore 1.1/Tiki, node.js, TeaJS (formerly v8cgi), CouchDB, Smart Platform, Yabble, Wakanda, XULJet
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 features that a module system must provide in order to support interoperable modules.
本文提出如何写出可以交互的模块,这类模块组成的系统将可以在客户端和服务器端运行,可以是安全的或不安全的,可以是已经实现,抑或者需要在未来的语言扩展后的系统中才能支持。这些模块将保证高度的封装,其他模块通过单例的对象保证引入的灵巧性,以及模块API的输出。本文定义了用以模块间交互的模块系统所必有的功能。
Module Context
- In a module, there is a free variable "require", that is a function. 1.1 The "require" function accepts a module identifier.
- 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.
- modules must use the "exports" object as the only means of exporting.
1.2 "require" returns the exported API of the foreign module.
1.3 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.4 If the requested module cannot be returned, “require” must throw an error.
模块内容
- 在一个模块中,有一个“require”的自由变量,“require”是一个如下的方法。 1.1 “require”方法接受模块定义。
- 一个模块中,需要含有一个自由变量“exports”,模块会将它的API作为对象加入到“exports”中执行。
- 模块将使用“exports”对象作为唯一的输出。
1.2 “require”返回外部模块输出地API。
1.3 如果含有依赖循环,外部模块可能在没有执行完的时候需要引入其他的需要引入一个它需要的依赖;在这种情况,“require”返回的对象必须至少含有输出,这些输出是由外部模块提供,而且必须在当前模块需要执行前被引入。
1.4 如果被请求的模块没有返回值,则“require”必须抛出一个错误。
Module Identifiers
- A module identifier is a String of “terms” delimited by forward slashes.
- A term must be a camelCase identifier, “.”, or “..”.
- Module identifiers may not have file-name extensions like “.js”.
- Module identifiers may be “relative” or “top-level”. A module identifier is “relative” if the first term is “.” or “..”.
- Top-level identifiers are resolved off the conceptual module name space root.
- Relative identifiers are resolved relative to the identifier of the module in which “require” is written and called.
模块定义
- 一个模块的定义,是指一串“term”组成的字符串,而这些“term”是被斜杠分割开来的。
- 一个term必须是驼峰写法(camelCase)的定义,“.”或“..”。
- 模块定义可以不必含有类似于“.js”的扩展名。
- 模块定义可以是“相对的”或“顶层的”(应该是指相对路径和绝对路径)。模块定义如果第一个term是“.”或者“..”,则其必是“相对的”。
- 顶层模块的定义由概念模块中命名空间的根所解决。
- 相对模块的定义是相对于定义的模块require被调用时位置决定的。
Unspecified
This specification leaves the following important points of interoperability unspecified:
Whether modules are stored with a database, file system, or factory functions, or are interchangeable with link libraries.
Whether a PATH is supported by the module loader for resolving module Identifirers.
未指定
本文对于以下几点很重要的交互性操作并未说明:
模块的存储方式:是数据库,是文件系统,是工厂方法,还是可交互的链接库。
用于解决模块定义的加载器是否支持路径。
代码例子:
math.js
exports.add = function() { var sum = 0, i = 0, args = arguments, l = args.length; while (i < l) { sum += args[i++]; } return sum; };
increment.js
var add = require('math').add; exports.increment = function(val) { return add(val, 1); };
program.js
var inc = require('increment').increment; var a = 1; inc(a); // 2