为什么要使用模块化?
1.解决命名冲突
2.依赖管理
3.提高代码可读性
4.代码解耦,提高复用性
CMD、AMD、CommonJS 规范分别指什么?有哪些应用
CMD规范
CMD(Common Module Definition)即通用模块定义,用于浏览器端的规范, 在 CMD 规范中,一个模块就是一个文件.代码的书写格式如下:
define
define(id?,d?,factory)
因为CMD推崇一个文件一个模块,所以经常就用文件名作为模块id,CMD推崇依赖就近,所以一般不在define的参数中写依赖,factory 为函数时,表示是模块的构造方法。执行该构造方法,可以得到模块向外提供的接口。
factory 方法在执行时,默认会传入三个参数require、exports 和 module.
function(require,exports,module)
require 是一个方法,用来获取其他模块提供的接口
exports 是一个对象,用来向外提供模块接口
module 是一个对象,上面存储了与当前模块相关联的一些属性和方法
例如:
// math.js
define(function(require, exports, module) {
exports.add = function() { //向外提供add的接口
var sum = 0, i = 0, args = arguments, l = args.length;
while (i < l) {
sum += args[i++];
}
return sum;
};
});
//increment.js
define(function(require, exports, module) {
var add = require('math').add; //按需加载依赖math模块
exports.increment = function(val) { //向外提供increment的接口
return add(val, 1);
};
});
//program.js
define(function(require, exports, module) {
var inc = require('increment').increment;
var a = 1;
inc(a); // 2
module.id == "program";
});
例2:
// 定义模块 myModule.js
define(function(require,exports,module) {
var $ = require('jquery.js')
$('div').addClass('active');
});
// 加载模块
seajs.use(['myModule.js'],function(my){
code
});
对于CMD的应用,最有代表性的就是SeaJS了。
AMD规范
AMD(Asynchronous Module Definition)即异步模块定义规范,它是依赖前置 (依赖一开始就写好) ,所有的require都被提前执行,AMD可以解决两个问题:
1.多个js文件可能有依赖关系,被依赖的文件需要早于依赖它的文件加载到浏览器。
2.js加载的时候浏览器会停止页面渲染,加载文件越多,页面失去响应时间越长。
AMD定义模块的规则使模块和模块的依赖可以被异步加载,这和浏览器的异步加载模块的环境刚好适应。
它的模块定义如下:
define(id?, dependencies?, factory);
参数说明:
id
指定义中模块的名称,可选。如果没有提供该参数,模块的名称应该默认为模块加载器请求的指定脚本的名称。如果提供了该参数,模块名必须是“顶级”的和绝对的(不允许相对名称)。
dependencies
包含一组当前模块依赖的,已被模块定义的模块标识。依赖参数是可选的,如果忽略此参数,它应该默认为["require", "exports", "module"]。然而,如果工厂方法的长度属性小于3,加载器会选择以函数的长度属性指定的参数个数调用工厂方法。
factory(工厂方法)
模块初始化要执行的函数或对象。如果为函数,它应该只被执行一次。如果是对象,此对象应该为模块的输出值。
示例1:
define('modal', ['jQuery', 'dialog'], function($, Dialog){
$('.modal').show();
Dialog.open();
});
示例2:
AMD
引入了require.js,然后使用data-main属性指定入口文件scripts/main(这里省略后缀.js)。
在index.html同级下创建一个文件夹scripts,创建三个js文件:a.js、b.js、mian.js.
scripts
//a.js
define('a', function(require, exports, module) {
exports.getTime = function() {
return new Date();
}
});
//b,js
define('b', ['require', 'exports', 'a'], function(require, exports,a) {
exports.test = function() {
return {
now: a.getTime()
};
}
});
main.js
require(['b'], function(b) {
console.log(b.test());
});
AMD的应用有RequireJS 、curl 、Dojo 等。
CommonJS 规范
CommonJS是服务器端模块的规范,CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。Node.js采用了这个规范。Node.JS首先采用了js模块化的概念。
CommonJS规范规定,每个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。
CommonJS模块的特点如下:
所有代码都运行在模块作用域,不会污染全局作用域。
模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
模块加载的顺序,按照其在代码中出现的顺序。
CommonJS定义的模块分为:模块引用(require)/ 模块定义(exports)/模块标识(module)。
示例:
//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
使用 requirejs 完善入门任务15,包括如下功能:
1. 首屏大图为全屏轮播
2. 有回到顶部功能
3. 图片区使用瀑布流布局(图片高度不一),下部有加载更多按钮,点击加载更多会加载更多数据(数据在后端 mock)
4. 使用 r.js 打包应用
代码
被build.js和main.js里的baseURL搞得心力交瘁,/(ㄒoㄒ)/~~,还是不太明白那几个路径的关系,只能用gitbash一个一个调。
参考
CMD 规范
AMD 规范
CommonJS 规范
详解 JavaScript 模块化开发