将js代码分割成不同功能的小块进行模块化的概念是在一些三方规范中流行起来的,比如CommonJS、AMD和CMD。接下来我们看一下这几种规范。
模块化规范
CommonJs是使用在服务器端,是同步加载的,NodeJs是对此规范的实践。
AMD,CMD是使用在浏览器端的,是异步加载的,require.js与sea.js是依赖此规范实现。
1.1 CommonJs规范实例
CommonJs对模块的定义十分简单,主要分为模块定义 、模块引用、模块标识。
根据此规范,一个js文件就是一个模块,有自己的作用域,不会污染全局作用域。在一个文件里面定义的变量、函数、类都是私有的,对其他文件不可见。
在模块中,存在一个module对象,她代表模块自身。其中exports是module的属性,该属性是一个对象,用于挂载当前模块的方法或者变量,也是当前模块的唯一导出的出口。以供其他模块使用。
addTwo.js
=======================
export.add = function(a,b){
return a+b;
}
//导出模块
在模块中,存在require()方法,这个方法接受模块标示,用来引入一个模块。
main.js
-----------------------------------------
var a = 5;
var b = 4;
var addTwo = require("./addTwo");//此参数为模块标示
console.log(addTwo.add(a,b));//9
CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD规范则是非同步加载模块,允许指定回调函数。由于Node.js主要用于服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,不用考虑非同步加载的方式,所以CommonJS规范比较适用。
1.2 AMD规范实例
AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义"。
AMD设计出一个简洁的写模块API:
define([id], [dependencies], factory);
第一个参数 id 为字符串类型,表示了模块标识,为可选参数。若不存在则模块标识应该默认定义为在加载器中被请求脚本的标识。如果存在,那么模块标识必须为顶层的或者一个绝对的标识。
第二个参数,dependencies ,是一个当前模块依赖的,已被模块定义的模块标识的数组字面量。
第三个参数,factory,是一个需要进行实例化的函数或者一个对象。
index.html
---------------
<!DOCTYPE html>
<html>
<head>
<title></title>
<!-- 引入require.js -->
<script type="text/javascript" src="http://cdn.bootcss.com/require.js/2.3.3/require.js"></script> </head>
<body>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
myName.js
---------------
// 定义模块
define('myName',[],function () {
return 'My name is toTo_li.'
})
yourName.js
---------------
// 定义模块
define('yourName',[],function () {
return 'Your name is boke.'
})
加载模块:AMD模块化规范中使用全局或局部的require函数实现加载一个或多个模块,所有模块加载完成之后的回调函数。
require([module], callback):
[module]:是一个数组,里面的成员就是要加载的模块;
callback:是模块加载完成之后的回调函数。
main.js
---------------
// 调用模块
require(['myName','yourName'],function (myName,yourName) {
console.log(myName)
console.log(yourName)
})
CMD规范实例
CMD是SeaJS 在推广过程中对模块定义的规范化产出
-
对于依赖的模块AMD是提前执行,CMD是延迟执行。不过RequireJS从2.0开始,也改成可以延迟执行(根据写法不同,处理方式不通过)。
-
CMD推崇依赖就近,AMD推崇依赖前置。
//AMD
define(['./a','./b'], function (a, b) {
//依赖一开始就写好
a.test();
b.test();
});
//CMD
define(function (requie, exports, module) {
//依赖可以就近书写
var a = require('./a');
a.test();
...
//软依赖
if (status) {
var b = requie('./b');
b.test();
}
});
AMD/CommonJS/Nodejs模块定义的方法:
//AMD定义方式
define(['./a','./b'],function(a,b){
return a+b
})
//CommonJS定义方式
var a = require('./a');
var b = require('./b');
module.exports = {
c:a+b
}
//es定义方式
import a from'./aaa';
import b from './bbb';
var c = a + b;
export {c}