本规范致力于描述一类可以同时适用于客户端和服务器端的模块系统。该系统中的模块拥有自己的作用域,可以从其他模块导入单例对象,或者对外提供 API。
Require
require 是一个函数对象。
- require 函数接受一个称为模块标识符的参数。
- require 函数返回外部模块提供的 API。
- 当发生循环依赖时,一个外部模块被其依赖模块导入时,它可能未被完全执行。在此种情况下,当前模块调用 require 函数所返回的对象必须包含该外部模块已经准备好的输出物。
- 如果不能返回所请求的模块,则 require 函数应该抛出异常。
-
require 函数可以有一个 main 属性。
- 当属性 main 存在,它应该是只读的且不能删除。
- main 属性应该是 undefined,或是已加载模块的 module 对象。
-
require 函数可以有一个 paths 属性,该属性是一个具有优先秩序的路径数组,优先级从高到低, 路径一直回溯到顶级模块目录 。
- paths 属性不应存在于沙盒中。
- 所有模块中的 paths 属性应该一致 。
- 使用另一个对象替换 paths 对象是无效的。
- 如果 paths 属性存在,修改 paths 内容会对模块搜索行为产生影响。
- 如果 paths 属性存在,它所包含的路径可能不是全部的搜索路径。因为加载器可以能会在搜索 paths 提供的路径之前或之后去检查其它的路径。
- 如果 paths 属性存在, 加载器责任去解析、标准化、规范化路径 。
模块上下文
- 一个模块中只有一个自由变量 require,该变量符合以上对 require 函数的定义。
-
一个模块中只有一个自由变量 exports,当模块被执行时,该模块对外提供的 API 被添加到该 exports 对象上。
- 模块必须使用 exports 对象作为唯一的输出手段。
-
一个模块中应该包含一个自由变量 module,该变量是一个 Object 对象。
- module 对象应该拥有一个 id 属性,它是模块的 顶级属性 。当执行 require(module.id) 时,返回 module.id 所属模块的输出对象。如果该属性被实现,则它应该是一个只读属性,不能删除。
- module 对象可以有一个 uri 属性,该属性指向模块源文件。uri 属性不应存在于沙盒中。
模块标识符
- 模块标识符是一个由多个词汇组成的字符串,不同词汇之间使用正斜杠分隔。
- 单个词汇应该是驼峰标识符,
.
或 ..
。 - 模块标识符不能包含文件后缀名,例如
.js
。 - 模块标识符可以是相对的,也可以是顶级的。如果标识符首个单词是
.
或 ..
,那么该标识符就是相对的。 - 顶级标识符是相对于所谓根命名空间而言。
- 相对标识符是相对于 require 函数所处的模块而言。
未说明
本规范有以下重要点未说明:
- 模块是否存储于数据库、文件系统或工厂函数中, 又或者可以和链接库进行互换 。
- 模块加载器是否支持使用 PATH 环境变量来解析模块标识符。
PS:本规范从 CommonJS 官方英文版本转译而来,斜体部分表示译文存在商榷。
Ref.:
(CommonJS Module 1.1.1)[ http://wiki.commonjs.org/wiki/Modules/1.1.1 ]