CommonJS是什么
CommonJS是一个标准库,或者说是一组规范。因为官方并没有给出真正的代码实现,而是给出一些代码组织规范、常用模块的api、包(Package)的命名规范和具体格式。
CommonJS的官方网站是http://www.commonjs.org/
wiki地址http://wiki.commonjs.org/wiki/CommonJS
Modules
模块的规范,其实就是require方法,定义了如何在当前的代码中使用已有的api。具体的规范(Modules/1.1.1)见http://wiki.commonjs.org/wiki/Modules/1.1.1
约定
Require
-
require是一个函数,接受一个外部模块名称的参数
- 该方法返回对应外部模块返回的api
- 如果引入外部模块出错,需要抛出异常
- require函数可能有一个
main
属性,只读 - require函数可能有一个
paths
属性,一个字符串数组,定义了查找引入模块的优先级。
-
模块上下文
- 一个模块中,有一个变量
require
- 一个模块中,有一个对象
exports
,包含这个模块对外的api - 一个模块中,还必须有一个变量
module
,是一个对象,可能包含id
和uri
属性。
- 一个模块中,有一个变量
-
模块名
- 模块名是由斜杠连接的1个或多个
term
组成的字符串 term
必须驼峰命名,也可能是.
..
- 模块名可以没有后缀名
.js
- 模块名可以是相对路径或默认"顶级"的,如果是相对路径必须在前面加上'.'或'..'
- 模块名是由斜杠连接的1个或多个
使用示例
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 module.id == "program";
实现
- 一般由底层框架实现require方法,当然js也可以实现,但对于模块中缺少var而生成的全局变量就不好处理了。
- 使用exports而不用this来返回api,一方面this需要根据上下文才能知道具体指什么,而exports则更好理解些。
已有的解决方案
- 推荐一个比较完善的asp方法:https://github.com/smith/commonjscript/blob/master/require.js
- 其中大部分项目都按照CommonJS规范实现了require方法:http://wiki.commonjs.org/wiki/CommonJS
- 其他已有的api:http://wiki.commonjs.org/wiki/Existing_APIs