模块简介
异步模块定义(AMD)的整体目标是提供模块化的JavaScript解决方案,以便开发人员使用。它诞生于使用XHR+eval的Dojo开发经验,这种格式的支持者希望能避免未来的任何解决方案受到过去解决方案缺点的影响。
AMD模块格式本身就是对定义模块的建议,其模块和依赖都可以进行异步加载。它有很多独特的优点,包括可以异步,并且本质上具有高度灵活性,消除了代码和模块之间可能惯有的紧耦合。
模块入门
AMD有两个关键概念,他们是用于模块定义的define方法和用于处理模块加载的require方法。define用于定义已命名或未命名模块:
define(module_id,[dependencies],definition function实例化模块或对象的函数)
module_id是一个可选的参数,它通常只在非AMD连接工具被使用时才需要。当遗漏这个 参数时,我们称这个模块为匿名的。
当使用匿名模块时,模块的概念是DRY,以便更容易的避免文件名和代码重复。因为代码更为轻便了,不需要修改代码本身或改变其模块ID,就可以将它很容易的移动到其他的位置。
dependencies参数表示我们定义模块所需的依赖数组。
最后一个参数时用于执行实例化模块的函数。
示例:了解AMD:define()
define(["foo","bar"],function(foo,bar){
// 模块定义函数,依赖(foo和bar)作为参数映射到函数上
var myModule = {
doStuff:function(){
console.log("Yay!Stuff");
}
};
// 返回定义模块的输出(例如:要暴露的内容)
return myModule;
});
//另外一种方式
define(["math","graph"],function(math,graph){
return {
plot:function(x,y){
return graph.drawPie(math.randomGrid(x,y));
}
}
});
require通常用于加载顶级JavaScript文件或模块的代码。
示例:动态加载依赖
define(function(require){
var isReady = false,
foolbar;
require(["foo","bar"],function(foo,bar){
isReady = true;
foolbar = foo() + bar();
});
return {
isReady: isReady,
foolbar : foolbar
};
});
AMD插件
下面介绍一下AMD插件示例:了解AMD插件
define(["./templates","text!./template.md","css!./template.css"],function(templates, template){
console.log(templates);
});
虽然上面的示例中包含了css!用于加载css依赖,但是一定要注意,这种方法会发出一些警告,例如当css完全加载时,它不一定完全有效。取决于如何处理创建过程,它也有可能会使css作为一个依赖文件而被包含在优化的文件中,因此,在将css作为加载依赖使用的情况下,一定要谨慎,(https:github.com/VIISON/RequireCSS)获取RequireJS的css插件。
具有延迟依赖的模块代码:
define(["lib/Deferred"],function(Deferred){
var defer = new Deferred();
require(["lib/templates/?index.html"],function(template){
defer.resolve({template:template});
});
return defer.promise();
})
为何使用AMD是模块化JavaScript的更好选择
- 对于如何完成灵活的定义提供了明确的建议
- 比很多人依赖现有全局命名空间和<script>标签解决方案都更加简洁,有一种简洁的方式可以声明可能的独立模块和依赖。
- 封装模块定义,帮助我们避免全局命名空间被污染
- 没有跨域、本地或调试的问题,也不依赖服务器端工具
- 提供一个"transport·"方法,将多个模块包括在单个文件中
- 可以延迟加载脚本