纯整理,纯记录,本人菜鸟,所以不写任何个人观点,以免怡笑四方
在模块化发展的路途上,最开始时服务端需要模块化,而且服务端不需要异步加载,所以有了COMMEN.js,后来浏览器的需求量,代码量太大,必须要模块化了,然而,浏览器还必须大量的异步加载。所以,AMD就诞生了,require.js实现了AMD的规范化,
require.js的诞生,就是为了解决这两个问题:
1)实现js文件的异步加载,避免网页失去响应;
(2)管理模块之间的依赖性,便于代码的编写和维护。
加载这个文件,也可能造成网页失去响应。解决办法有两个,一个是把它放在网页底部加载,另一个是写成下面这样:
<script src="js/require.js" defer async="true" ></script>
async属性表明这个文件需要异步加载,避免网页失去响应。IE不支持这个属性,只支持defer,所以把defer也写上。
加载require.js以后,下一步就要加载我们自己的代码了。假定我们自己的代码文件是main.js,也放在js目录下面。那么,只需要写成下面这样就行了:
<script src="js/require.js" data-main="js/main"></script>写data-main,路径是主入口的main.js文件
这个文件会第一个被require.js加载。由于require.js默认的文件后缀名是js,所以可以把main.js简写成main。
require()异步加载moduleA,moduleB和moduleC,浏览器不会失去响应;它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题。
我们使用define()来包裹一个函数,define不是ECMAScript的语法,而是require.js的语法。
函数里面可以写任何语句,需要暴露的东西,写return来暴露
使用require.config()方法,我们可以对模块的加载行为进行自定义。require.config()就写在主模块(main.js)的头部。参数就是一个对象,这个对象的paths属性指定各个模块的加载路径。
注意:
-
依赖的文件名必须有引号,注入的时候没有引号的;
-
注入的时候的名字可以任取,所以require.js是通过依赖注入的顺序来产生对应关系的:
-
依赖的时候,没有拓展名,模块的默认名字就是文件名
什么叫做符合AMD规范:如果一个库在创建的时候有这么一条语句(伪代码):
if(define){
define(function(){
return {
$
}
})
}
此时就说明对require.js兼容了,此时叫做符合AMD规范。
然而jQuery是不符合AMD规范的,天生是没有对define做适配。
此时解决办法就是加shim:
require.config({
paths: {
"circle" : "yuan",
"jq" : "lib/jquery.min"
},
shim: {
'jq': {
exports : '$'
}
}
});
引入有依赖的依赖的库,此时我们要在shim中定义这层关系:
require.config({
paths: {
"circle" : "yuan",
"jq" : "lib/jquery.min",
"jqui" : "lib/jquery-ui.min"
},
shim: {
'jq': {
exports : '$'
},
'jqui': {
deps: ['jq']
}
}
});
首先我们要知道依赖注入的时候,依赖的模块们(比如下面的4个依赖)彼此之间没有加载顺序之分的。只有一个亘古不变的真理:当他们都加载完毕之后,执行回调函数。
require(['circle','fang','jq','jqui'],function(y,f,$,jqui){
alert(y.mianji(10));
alert(f.mianji(10,20));
$("#box").animate({"font-size":400},1000);
$("#box").draggable();
});
alert("我最先执行");
在回调函数外面的语句是最先执行的。
当需要加载非规范的模块
这样的模块在用require()加载之前,要先用require.config()方法,定义它们的一些特征。
设置别名来作为他们的暴漏名
举例来说,underscore和backbone这两个库,都没有采用AMD规范编写。如果要加载它们的话,必须先定义它们的特征。
shim: {//专门用来配置不兼容的模块
'jquery.scroll': {
deps: ['jquery'],//表明该模块的依赖性
exports: 'jQuery.fn.scroll'//表明这个模块外部调用时的名称
}
}
到底为什么叫做AMD规范:
- AMD规范使用依赖注入的形式,所有的依赖项是同时加载的,没有回来的先后之分,都回来了才执行回调函数。也就是说,回调函数是AMD规范的特征。
- require()里面的语句是异步语句,把依赖项都加载完毕之后才执行回调函数,此时就是“异步”的由来。
- AMD规范中,如果两个模块之间有“插件”的关系,彼此依赖,可以用shim中定义这个关系。
AMD的现状:很惨。
⦁ 只有require.js对AMD进行了实现。
⦁ Angular1使用了AMD规范,而Angular2放弃了AMD规范,转入了CMD阵营,Angular4、5都是CMD的。
看一下Angular1中的AMD特性:
<div ng-controller="MainCtrl as mainctrl">
<h1> {{mainctrl.a}} </h1>
<button no-click="mainctrl.add()">加</button>
<button no-click="mainctrl.minus()">加</button>
<button no-click="mainctrl.pf()">平方</button>
</div>
<script type="text/javascript">
var myapp = angular.module("myapp" , []);
myapp.controller("MainCtrl",["shuxue",function(shuxue){
this.a = 100;
var self = this;
this.add = function(){
self.a++;
}
this.minus = function(){
self.a--;
}
this.pf = function(){
self.a = shuxue.pingfang(self.a);
}
}]);
myapp.factory("shuxue",[function(){
function pingfang(a){
return a * a;
}
return {
pingfang
}
}]);
</script>