《用得上的前端知识》系列 - 你我都很忙,能用100字说清楚,绝不写万字长文
CommonJS(Node.js)
CommonJS 是服务器模块的规范,Node.js 采用了这个规范。其特点为:
- 一个文件就是一个模块,拥有单独的作用域;
- 使用 module 或 module.exports 导出模块;
- 使用 require 方法加载模块。
-
- CommonJS 加载模块时是同步加载的,只有加载完成后才能执行后面的操作;
- require 命令第一次加载模块时,执行整个脚本,在内存中生成对象;
- 多次执行 require 加载模块时,不会再执行该脚本,直接从缓存中取值。
CommonJS 不适合作为浏览器规范的原因:
- 因为 CommonJS 是同步加模块,在服务端加载模块时都是从本地硬盘中加载,读取速度很快。但是在浏览器端加载模块时,需要请求服务器端,涉及网速、代理的问题,如果使用同步加载,浏览器容易处于“假死”状态,所以,更合理的方案是使用异步加载。
// 定义模块 math.js
var basicNum = 0;
function add(a, b) {
return a + b;
}
module.exports = { //在这里写上需要向外暴露的函数、变量
add: add,
basicNum: basicNum
}
// 引用自定义的模块时,参数包含路径,可省略.js
var math = require('./math');
math.add(2, 5);
// 引用核心模块时,不需要带路径
var http = require('http');
http.createService(...).listen(3000);
AMD(RequireJS)
AMD,全称 Asynchronous Module Definition,即,异步模块定义,客户端规范。 采用异步方式加载模块,模块加载不影响它后面语句的代执行。
注:AMD 是 require.js 在推广使用过程中对模块定义规范化的产物。使用时,需引入 require.js。
AMD 规范的特定为:
- 使用 define() 定义模块;
- 使用 require 加载模块。
//规范 API
/**
* @param id 模块名称,如果为空,模块的名字默认为模块加载器请求的指定脚本名
* @param dependencies 模块依赖
* @param factory 工场函数,模块初始化执行的函数或对象
*/
define(id?, dependencies?, factory);
demo:
// moduleA.js
define(function (){
var add = function (x,y){
return x+y;
};
return {
add: add
};
});
// index.js
require(['moduleA'], function (moduleA){
console.log(moduleA)
//moduleA就是moduleA.js模块传入的函数执行后返回的对象{add:function}
});
CMD(SeaJS)
CMD,全称 Common Module Definition 通用模块定义,异步加载模块。
- 注:CMD 是 sea.js 在推广过程中对模块定义的规范化产物。使用时需引入 sea.js。
CMD 规范和 AMD 类似,都主要运行于浏览器端,写法上看起来也很类似。主要是区别在于 模块初始化时机
- AMD中只要模块作为依赖时,就会加载并初始化;
- CMD中,模块作为依赖且被引用时才会初始化,否则只会加载;
/** AMD写法 **/
define(["a", "b", "c", "d", "e", "f"], function(a, b, c, d, e, f) {
// 等于在最前面声明并初始化了要用到的所有模块
a.doSomething();
if (false) {
// 即便没用到某个模块 b,但 b 还是提前执行了
b.doSomething()
}
});
/** CMD写法 **/
define(function(require, exports, module) {
var a = require('./a'); //在需要时申明
a.doSomething();
if (false) {
var b = require('./b');
b.doSomething();
}
});
/** sea.js **/
// 定义模块 math.js
define(function(require, exports, module) {
var $ = require('jquery.js');
var add = function(a,b){
return a+b;
}
exports.add = add;
});
// 加载模块
seajs.use(['math.js'], function(math){
var sum = math.add(1+2);
});
CMD 的特点是:
- 使用 define() 定义模块,使用 require() 加载模块
UMD
UMD,即 Universal Module Definition,是AMD 和 CommonJS 的糅合,希望提供一个前后端跨平台的解决方案。原理为:
- 先判断是否支持 CommonJS(exports是否存在),支持则使用 CommonJS 方式加载模块;
- 再判断是否支持 AMD(define是否存在),存在则使用 AMD 方式加载模块;
- 前两个都不存在,则将模块公开到全局(window或global)。
ES Module
ES6 在语言标准的层面上,实现了模块功能,旨在成为浏览器和服务器通用的模块解决方案。其特点为:
- 使用 export 导出模块;
- 使用 import 导入模块。
/** 定义模块 math.js **/
var basicNum = 0;
var add = function (a, b) {
return a + b;
};
export { basicNum, add };
/** 引用模块 **/
import { basicNum, add } from './math';
function test(ele) {
ele.textContent = add(99 + basicNum);
}