1.AMD 异步模块定义
AMD:浏览器端模块化开发的规范。使用AMD规范快发需要用到对应的库函数RequireJs
,也即AMD
是RequireJs
在推广过程中对模块定义的规范化的产出。
RequireJs
主要解决两个问题:
- 多个js文件依赖性,也即多个有依赖性的js文件,会出现被依赖的文件需要早于依赖它的文件加载到浏览器中,但是如果当依赖关系比较复杂的时候,代码的编写和维护就变得很复杂了。
- js加载的时候,浏览器会停止网页渲染,加载文件越多,页面失去响应的时间就会越长。
RequireJs
作用:
- 管理模块之间的依赖性,便于代码的编写和维护
- 实现js文件的异步加载,避免网页失去响应
RequireJs使用
:
-
下载
-
引用
-
<script src="js/require.js"><script>;// 假定下载后的require.js文件放于js目录下
由于采用以上方式也会在加载js文件时造成网页失去响应,解决方法:
-
把其放于网页底部加载
-
为其添加async属性:该属性表明这个文件需要异步加载,避免网页失去响应
<script src="js/require.js" defer async="true"><script>;
由于IE不支持这个属性,只支持defer,也需要加上defer
-
-
-
加载自己写的js文件
<script src="js/require.js" data-main="js/main"><script>;
- data-main属性作用:指定网页的主模块,默认后缀名是js,可以不用加上js后缀。
- main.js此时会被require.js第一个加载。
-
AMD模块规范写法
-
模块必须采用特定的define()函数来定义
-
如果一个模块不依赖其他模块
-
直接将其定义在define()函数之中
// /js/test.js define(function() { var sayHello = function() { console.log('hi'); } return { sayHello: sayHello } })
-
加载
// /js/main.js require(['test'],function(test){ test.sayHello(); })
第一个参数是需要加载模块数组,采取异步加载的方式,当模块加载完成之后将模块导出对象传入第二个参数作为形参,第二个参数当模块被加载完成之后进行调用
-
-
如果一个模块依赖其他模块
-
第一个参数是所依赖的模块数组,第二个参数是当前模块所要有的逻辑实现
// /js/pra.js define(['other'],function(other) { //... code })
其中两个参数的用法与require加载模块是一样的原理
-
那如何找到模块的呢?
以require加载为例:
默认情况下,require.js假定模块与main.js在同一个目录下,文件名为test.js,然后自动加载。但是如果是其他路径下的模块呢?此时可以使用
require.config()
对模块加载行为进行自定义。require.config()
写在当前主模块main.js
头部。参数是一个对象,paths属性指定各个模块加载路径-
文件与
main.js
同一目录require.config({ paths: { 'test': 'test.js' } })
-
文件与
main.js
不同目录第一种写法:直接写路径
require.config({ paths: { 'test': '../lib/test.js';// 也可以直接写绝对路径,包括网址也可以 } })
第二种:改变基目录(baseUrl)
require.config({ baseUrl: '../lib' paths: { 'test': 'test.js' } })
-
-
-
2.CMD 通用模块定义
类似于AMD,CMD有个浏览器的实现:SeaJs,SeaJs要解决的问题和RequireJs一样,只不过模块加载时机不一样。且SeaJs推崇一个模块一个文件。
官方地址:https://www.zhangxinxu.com/sp/seajs/
语法与Require.js
类似,就不在此处再赘述了
3.AMD和CMD区别
两个最明显的区别在于模块定义时对依赖的处理不同:
- AMD推崇前置依赖,在定义模块的时候就要声明其依赖的模块
- CMD推崇就近依赖,只有在用到某个模块的时候再去require
也即AMD提前执行,CMD延迟执行