如何使用AMD规范对多个JavaScript框架进行整合
1个回答
2016-02-22
展开全部
目前很多主流框架都开始采用 AMD 规范来进行模块加载,本文将以 Dojo 与 jQuery 的整合为例,介绍如何使用 AMD 规范对多个 JavaScript 框架进行整合,从闹羡而提高开发效率,降低开发成本。
AMD 是 Asynchronous Module Definition 的简称,即异步模块加载机制。该规范是由 CommonJS 提出的一种异步动态液雹拍加载 JavaScript 代码的 API 规范。AMD 以简洁优雅的运行方式得到了很多主流 JavaScript 框架的青睐,主流 JavaScript 开源框架逐渐开始用 AMD 规范来实现对其代码模块的动态加载。在 AMD 日益流行的情况下,开发过程中的 JavaScript 框架迁移变得更加方便,同时,在一个应用中引入多个具有不同优势和功能特点的 JavaScript 框架也变得刚加容易。
AMD 工作原理
AMD 的 API 规范非常简洁,仅包含一个名为 define 的函数:
define([module-name?], [array-of-dependencies?], [module-factory-or-object]);
其中:
module-name:模块标识,可以省略。
array-of-dependencies:所依赖的模块,可以省略。
module-factory-or-object:模块的具体实现,或者一个 JavaScript 对象。
第一个参数 module-name 指的是模块名称标识,该参数在 AMD 加载中没有实际性作用,只做为一个名称标识。如果第一个参数被省略,那么这个模块就成为了一个匿名模块。
匿名模块最大的优势就是可以降低代码本身和所属模块的耦合程度。这类模块符合 DRY (Don't repeat yourself) 原则,即模块文件可以放置在任何位置而不需要修改文件内容本身。如比较熟悉的 Java 类,它的类名和包名必须符合一定的格式,文件名和类名需要一致,文件也必须放置在相应的包路径下。而在 AMD 加载的 dojo 中,如果一个模块为匿名模块,那么该模块的文件名就是模块标识。
AMD 的优势
匿名模块的优势
下面来对比一下传统模块加载方式和 AMD 方式,看看匿名模块有什么样的优势:
在 dojo 的早期版本中,建立一个 dog 类,该类继承自 animal 类。文件结构如下图所示:
图 1
在基类 animal 中有如下声明:
清单 1
dojo.provide("animal"); // 用于初始化该 js 文件,使之成为 dojo 的模块
在非 AMD 情况下文件名和 provide 中参数必须保持一致性 ( 即文件名与模块标识最后小数点右边部分保持一致 ),肆神否则 dojo.require 就无法正确初始化调用该模块。
此时,继续引入子类,如 cat 类、tiger 类,为了区别基类与之类,将 animal 基类移到一个独立的文件夹,如下图:
图 2
这时,问题出现了,一旦 animal.js 移入 animalBase 目录下,文件中的 dojo.provide("animal") 必须修改为 dojo.provide("animalBase.animal") 才可以使之成为成为一个正确的 dojo 模块。
由此案例所示,使用非 AMD 模式来载入 dojo 资源时,如果需要改动文件路径和重用某部分基本类库时必须修改文件本身代码,这种模式会造成代码结构变换时许多问题。那么再来看看使用 AMD 匿名模块的灵活性。
在 AMD 模式下,定义一个名为 animal.js 文件,结构如下:
清单 2
define(function(){
run:function(){
…
}
});
使用 AMD 规范加载的 animal.js 在移动位置后仍然可以直接使用。在 AMD 匿名定义下,文件名即是模块标识,如 animal 从根目录下移动到 animalBase 目录下,只需要将它的子类中 require(["animal"])改为 require("animalBase/animal") 即可,不用去修改 animal.js 本身 , 这样就实现 DRY 原则,方便了类的移植。AMD 能让你沿着正确的路线开发松耦合的模块,让应用更加容易理解和维护。而 Dojo 正在不断的完善着细节,帮助设计出更好的应用架构。
性能优势
传统的 dojo 对依赖性加载是通过 dojo.require 同步完成的,与传统的 dojo.require 相比,AMD 对于依赖性进行了异步加载机制,这样就不容易对浏览器造成阻塞。为什么这里笔者使用的是不容易阻塞而不是不会阻塞来描述 AMD 加载呢?其实浏览器对资源的异步加载还要受到浏览器默认连接数的限制。AMD 的性能优势会随着浏览器的发展而进一步彰显。
Dojo 中的 AMD
Dojo 是一个强大的企业级开源 Javascript 工具包,在版本 1.6 中首次引入了 AMD 的加载方式,并且在随后的 1.7 和 1.8 版本中进行了不断的完善,使得 dojo 在架构上进行了一次全新的升级。这些变化给 dojo 带来了更大的灵活性和更好的性能。
jQuery 中 AMD
jQuery 作为一款优秀的轻量级框架受到到很多前端工程师的青睐,其压缩之后的尺寸只有 30 K 左右,同时 jQuery 提供的 API 非常简洁,适合轻便快速的前端开发。使用 jQuery,用户不需要冗长的 JavaScript 代码中挣扎,只需要短短的几个符号就可以完成很多操作。
jQuery 从 1.7 版本开始支持了 AMD 对其类库的加载,开发者同样可以通过 require 方法来异步加载 jQuery 的源代码。
Dojo 和 JQuery 整合
如今许多大型项目都会引入不同的 JavaScript 框架,而过多的资源加载会降低应用的性能,AMD 加载器就可以很好的解决这个问题,可以对资源进行按需加载。下面以 Dojo 与 jQuery 为例,示范 AMD 对不同框架的整合能力。
首先把 jquery.js 放入示例工程中:
图 3
然后 index.html 页面中加入如下代码引入 jQuery 库 :
清单 3
require(["jquery"]) ;
这样就可以在页面中同时使用 dojo 和 jQuery:
清单 4
<html>
<body>
<script src="dojo/dojo.js"></script>
<script>
require(["jquery"]);
</script>
<div id="testNode">
Hello Dojo and JQuery!
</div>
<script>
console.log(dojo.byId("testNode"));//node
console.log($("#testNode"));//node
</script>
</body>
</html>
不过笔者认为这样粗暴的用法并不是最佳实践,而是应该按照开发者需求加载。如某熟悉 jQuery 程序员使用 dojo 在写一个后台用 XHR 去取数据并渲染到一个 dialog 里的 widget。如果他刚刚接触 dojo,并且对 dojo 的 XHR 一无所知,那么他可以果断的选择在这个 widget 的 AMD 声明中加入 jQuery 来帮助实现 XHR 方法,myDialog.js 代码如下:
清单 5
define("myDialog",["dijit/Dialog","jquery"], function(dialog,jq){
return dojo.declare("myDialog",[dijit.Dialog],{
postCreate: function(){
this.inherited(arguments);
this.getXHRDataContentByJq();// 使用 JQuery xhr 获取数据
},
getXHRDataContentByJq: function(){
var _this = this;
$.get("data.json",function(data){
_this.callback(data);
});
},
callback: function(data){
var obj = dojo.fromJson(data);
this.containerNode.innerHTML=obj.content;
}
});
});
上例中没有使用 dojo.xhr 来获取,而是选择轻量级的 jQuery 结合 dojo 来完成 Ajax 调用的过程。由此可见, AMD 的支持大大降低多个 JavaScript 框架整合复杂程度,极大提高了开发效率。
结束语
本文介绍了 AMD 规范及其优势,该规范在 Dojo 与 jQuery 框架中的应用;并提供实际用例展示如何基于 AMD 整合两种框架。这种基于 AMD 的整合模式给多种前端框架并存提供了新的解决方案和思路。
AMD 是 Asynchronous Module Definition 的简称,即异步模块加载机制。该规范是由 CommonJS 提出的一种异步动态液雹拍加载 JavaScript 代码的 API 规范。AMD 以简洁优雅的运行方式得到了很多主流 JavaScript 框架的青睐,主流 JavaScript 开源框架逐渐开始用 AMD 规范来实现对其代码模块的动态加载。在 AMD 日益流行的情况下,开发过程中的 JavaScript 框架迁移变得更加方便,同时,在一个应用中引入多个具有不同优势和功能特点的 JavaScript 框架也变得刚加容易。
AMD 工作原理
AMD 的 API 规范非常简洁,仅包含一个名为 define 的函数:
define([module-name?], [array-of-dependencies?], [module-factory-or-object]);
其中:
module-name:模块标识,可以省略。
array-of-dependencies:所依赖的模块,可以省略。
module-factory-or-object:模块的具体实现,或者一个 JavaScript 对象。
第一个参数 module-name 指的是模块名称标识,该参数在 AMD 加载中没有实际性作用,只做为一个名称标识。如果第一个参数被省略,那么这个模块就成为了一个匿名模块。
匿名模块最大的优势就是可以降低代码本身和所属模块的耦合程度。这类模块符合 DRY (Don't repeat yourself) 原则,即模块文件可以放置在任何位置而不需要修改文件内容本身。如比较熟悉的 Java 类,它的类名和包名必须符合一定的格式,文件名和类名需要一致,文件也必须放置在相应的包路径下。而在 AMD 加载的 dojo 中,如果一个模块为匿名模块,那么该模块的文件名就是模块标识。
AMD 的优势
匿名模块的优势
下面来对比一下传统模块加载方式和 AMD 方式,看看匿名模块有什么样的优势:
在 dojo 的早期版本中,建立一个 dog 类,该类继承自 animal 类。文件结构如下图所示:
图 1
在基类 animal 中有如下声明:
清单 1
dojo.provide("animal"); // 用于初始化该 js 文件,使之成为 dojo 的模块
在非 AMD 情况下文件名和 provide 中参数必须保持一致性 ( 即文件名与模块标识最后小数点右边部分保持一致 ),肆神否则 dojo.require 就无法正确初始化调用该模块。
此时,继续引入子类,如 cat 类、tiger 类,为了区别基类与之类,将 animal 基类移到一个独立的文件夹,如下图:
图 2
这时,问题出现了,一旦 animal.js 移入 animalBase 目录下,文件中的 dojo.provide("animal") 必须修改为 dojo.provide("animalBase.animal") 才可以使之成为成为一个正确的 dojo 模块。
由此案例所示,使用非 AMD 模式来载入 dojo 资源时,如果需要改动文件路径和重用某部分基本类库时必须修改文件本身代码,这种模式会造成代码结构变换时许多问题。那么再来看看使用 AMD 匿名模块的灵活性。
在 AMD 模式下,定义一个名为 animal.js 文件,结构如下:
清单 2
define(function(){
run:function(){
…
}
});
使用 AMD 规范加载的 animal.js 在移动位置后仍然可以直接使用。在 AMD 匿名定义下,文件名即是模块标识,如 animal 从根目录下移动到 animalBase 目录下,只需要将它的子类中 require(["animal"])改为 require("animalBase/animal") 即可,不用去修改 animal.js 本身 , 这样就实现 DRY 原则,方便了类的移植。AMD 能让你沿着正确的路线开发松耦合的模块,让应用更加容易理解和维护。而 Dojo 正在不断的完善着细节,帮助设计出更好的应用架构。
性能优势
传统的 dojo 对依赖性加载是通过 dojo.require 同步完成的,与传统的 dojo.require 相比,AMD 对于依赖性进行了异步加载机制,这样就不容易对浏览器造成阻塞。为什么这里笔者使用的是不容易阻塞而不是不会阻塞来描述 AMD 加载呢?其实浏览器对资源的异步加载还要受到浏览器默认连接数的限制。AMD 的性能优势会随着浏览器的发展而进一步彰显。
Dojo 中的 AMD
Dojo 是一个强大的企业级开源 Javascript 工具包,在版本 1.6 中首次引入了 AMD 的加载方式,并且在随后的 1.7 和 1.8 版本中进行了不断的完善,使得 dojo 在架构上进行了一次全新的升级。这些变化给 dojo 带来了更大的灵活性和更好的性能。
jQuery 中 AMD
jQuery 作为一款优秀的轻量级框架受到到很多前端工程师的青睐,其压缩之后的尺寸只有 30 K 左右,同时 jQuery 提供的 API 非常简洁,适合轻便快速的前端开发。使用 jQuery,用户不需要冗长的 JavaScript 代码中挣扎,只需要短短的几个符号就可以完成很多操作。
jQuery 从 1.7 版本开始支持了 AMD 对其类库的加载,开发者同样可以通过 require 方法来异步加载 jQuery 的源代码。
Dojo 和 JQuery 整合
如今许多大型项目都会引入不同的 JavaScript 框架,而过多的资源加载会降低应用的性能,AMD 加载器就可以很好的解决这个问题,可以对资源进行按需加载。下面以 Dojo 与 jQuery 为例,示范 AMD 对不同框架的整合能力。
首先把 jquery.js 放入示例工程中:
图 3
然后 index.html 页面中加入如下代码引入 jQuery 库 :
清单 3
require(["jquery"]) ;
这样就可以在页面中同时使用 dojo 和 jQuery:
清单 4
<html>
<body>
<script src="dojo/dojo.js"></script>
<script>
require(["jquery"]);
</script>
<div id="testNode">
Hello Dojo and JQuery!
</div>
<script>
console.log(dojo.byId("testNode"));//node
console.log($("#testNode"));//node
</script>
</body>
</html>
不过笔者认为这样粗暴的用法并不是最佳实践,而是应该按照开发者需求加载。如某熟悉 jQuery 程序员使用 dojo 在写一个后台用 XHR 去取数据并渲染到一个 dialog 里的 widget。如果他刚刚接触 dojo,并且对 dojo 的 XHR 一无所知,那么他可以果断的选择在这个 widget 的 AMD 声明中加入 jQuery 来帮助实现 XHR 方法,myDialog.js 代码如下:
清单 5
define("myDialog",["dijit/Dialog","jquery"], function(dialog,jq){
return dojo.declare("myDialog",[dijit.Dialog],{
postCreate: function(){
this.inherited(arguments);
this.getXHRDataContentByJq();// 使用 JQuery xhr 获取数据
},
getXHRDataContentByJq: function(){
var _this = this;
$.get("data.json",function(data){
_this.callback(data);
});
},
callback: function(data){
var obj = dojo.fromJson(data);
this.containerNode.innerHTML=obj.content;
}
});
});
上例中没有使用 dojo.xhr 来获取,而是选择轻量级的 jQuery 结合 dojo 来完成 Ajax 调用的过程。由此可见, AMD 的支持大大降低多个 JavaScript 框架整合复杂程度,极大提高了开发效率。
结束语
本文介绍了 AMD 规范及其优势,该规范在 Dojo 与 jQuery 框架中的应用;并提供实际用例展示如何基于 AMD 整合两种框架。这种基于 AMD 的整合模式给多种前端框架并存提供了新的解决方案和思路。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询