JavaScript模块化规范主要遵循CommonJS和AMD规范。
CommonJS规范-服务器端JavaScript规范
Node.js是一个服务器端JavaScript项目,采用了CommonJS标准实现其模块系统。
CommonJS中采用一个全局require方法来加载模块,主要由原生模块module来实现和完成,该模块在启动时已经被加载。
模块主要分为两类:原生模块,文件模块。
1.原生模块
原生模块也是Node.js中最核心的模块。原生模块在Node.js源代码编译的时候编译进了二进制执行文件,加载的速度最快。
Node.js中存在许多原生模块,例如:http,net,os,path,fs, module等等,其引用方式为var fs = require('fs');
2.文件模块
文件模块是动态加载的,加载速度比原生模块慢。但是Node.js对原生模块和文件模块都进行了缓存,在第二次require该模块时,是不会有重复开销。
文件模块可细分为3类。这三类文件模块以文件后缀来区分,Node.js会根据后缀名来决定加载方法。
.js。通过fs模块同步读取js文件并编译执行。
.node。通常为npm安装的第三方模块。
.json。读取文件,调用JSON.parse解析加载。
虽然Node.js使用require方法引入模块的方式看似简单,但内部的加载却并不简单,且其中的优先级也不一样。
AMD规范-浏览器端JavaScript规范
CommonJS中模块存放在本地,使用同步方式加载模块,其加载时间基本相当于磁盘IO时间,这不会存在问题,但是如果环境是浏览器,则文件的加载受制于网络因素,如果网络加载比较慢,则可导致浏览器处于假死状态,因此浏览器端只能采用异步加载模块的方式。
AMD:Asynchronous Module Definition(异步模块定义)。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。
AMD也采用require()语句加载模块,但是不同于CommonJS,它要求两个参数:require([module], callback);
第一个参数[module],是一个数组,里面的成员就是要加载的模块;第二个参数callback,则是加载成功之后的回调函数。目前,主要有两个Javascript库实现了AMD规范:require.js和curl.js。
require.js采用AMD规范实现模块加载,其采用define函数来定义。define函数接受两个参数,第一个参数为依赖数组,第二个参数为待定义的模块函数。如果没有依赖模块,则第一个参数也可以省略。
参考:
http://www.infoq.com/cn/articles/nodejs-module-mechanism
http://www.ruanyifeng.com/blog/2012/10/asynchronous_module_definition.html
http://nodejs.org/api/modules.html