一、JavaScript变迁及现状
工具(浏览器兼容)--> 组件(功能模块)--> 框架(功能模块组织)--> 应用(业务模块组织)在实际应用中,JavaScript的表现能力取决于宿主环境中的API支持程度。在Web1.0时代,只有对DOM、BOM等基本的支持。随着Web2.0的推进,HTML5崭露头角,将Web网页带进Web应用的时代,在浏览器中出现了更多、更强大的API供JavaScript调用。但是,Web在发展,浏览器中出现了更多的标准API,这些过程发生在前端,后端JavaScript的规范却远远落后。对于JavaScript自身而言,它的规范依然是薄弱的,有以下缺陷:
(1)没有模块系统(2)标准库较少:ECMAScript仅定义了部分核心库,对于文件系统,I/O流等常见需求却没有标准的API。
(3)没有标准接口:在JavaScript中,几乎没有定义过如Web服务器或者数据库之类的标准统一接口。
(4)缺乏包管理系统:这导致JavaScript应用中基本没有自动加载和安装依赖的能力。
二、CommonJS出发点
CommonJS规范的提出,主要是为了弥补当前JavaScript没有标准的缺陷,已达到像Python、Ruby和Java具有开发大型应用的基础能力,而不是停留在小脚本程序阶段。
(1)服务器端JavaScript应用程序(2)命令行工具
(3)桌面图形界面应用程序
(4)混合应用
三、CommonJS的模块规范
CommonJS构建模块导出和引入机制使得用户完全不必考虑变量污染。
CommonJS对模块的定义主要分为模块引用、模块定义和模块标识3个部分。
1. 模块定义
在CommonJS规范中,使用exports对象用于导出当前模块的方法或者变量,并且它是唯一导出的出口。
在模块中,存在一个module对象,它代表模块自身,而exports是module的属性。在NodeJS中,一个文件就是一个模块,将方法挂载exports对象上作为属性即可导出。
/* math.js */
exports.add = function(){
var sum = 0, i = 0, args = argumetns, l = args.length;
while(i < l){
sum += args[i++];
}
return sum;
};
2. 模块引用
在CommonJS规范中,使用require()方法接受模块标识,以此引入一个模块的API到当前上下文。同步加载!
/* program.js */
var math = require('math');
exports.increment = function(val){
return math.add(val, 1);
};
3. 模块标识
模块标识其实就是传递给require()方法的参数,它必须是符合小驼峰命名的字符串,或者以"./"、"../"开头的相对路径,或者绝对路径。它可以没有文件名后缀.js。
四、NPM、NodeJS、CommonJS关系
NodeJS借鉴CommonJS的Modules规范实现了一套非常易用的模块系统,NPM对Packages规范的完美支持使得Node应用在开发过程中事半功倍。
Node能以一种较成熟的姿态出现,离不开CommonJS规范的影响。在服务器端,CommonJS能以一种寻常的姿态进入各个公司的项目代码中,离不开Node优异的表现。