转载自: http://wifeng.cn/?r=blog&a=view&id=90
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实现的require方法:
//by wifeng.cn //2011/9/15 15:47 //只是实现了“顶级”模块加载,相对的并没有处理 (function(){ var loaded = {}; var global = global || {}; require = function(name){ var fso = require.fso || (require.fso = new ActiveXObject('Scripting.FileSystemObject')); var path, paths = require.paths, found = false; for(var i=0; i<paths.length; i++){ path = Server.MapPath(paths[i] + '/' + name + '.js'); if(fso.FileExists(path)){ found = true; break; } } if(!found){ error('module not found'); } if(path in loaded){ return loaded[path]; } loaded[path] = {}; var content = fso.OpenTextFile(path, 1).ReadAll(); var fn = new Function('require', 'exports', content); try{ fn.call(global, require, loaded[path]); }catch(e){ error('runtime error.', e); } return loaded[path]; function error(msg, ex){ throw new Error(msg); }; }; require.paths = ['bin/lib', '.']; require.loaded = loaded; })()
推荐一个比较完善的asp方法:https://github.com/smith/commonjscript/blob/master/require.js
已有的解决方案
其中大部分项目都按照CommonJS规范实现了require方法:http://wiki.commonjs.org/wiki/CommonJS