前端AMD和CMD是在模块化的基础上产生并且得到大幅度的引用的。
AMD 即Asynchronous Module Definition(点击链接可以查看AMD面试题)
,中文名是异步模块定义的意思。它是一个在浏览器端模块化开发的规范;
CMD 即Common Module Definition ,中文名是同步模块定义的意思,是SeaJs在推广过程中对模块规范化的定义的产出。该规范明确了模块的基本书写格式和基本交互规则
CommonJs:官方网址:http://www.commonjs.org/ CommonJs用在服务器端,AMD和CMD用在浏览器环境
这三者的主要作用是:
1.javaScript模块化加载而生的
2.便于团队的人员的协作,代码不至于很乱
3.在网络请求中的记载时间的优化
AMD使用方法:
AMDjavaScript不支持,所以出现我们经常用的requireJs,实际上AMD 是 RequireJS 在推广过程中对模块定义的规范化的产出
requireJS主要解决两个问题
- 多个js文件可能有依赖关系,被依赖的文件需要早于依赖它的文件加载到浏览器
- js加载的时候浏览器会停止页面渲染,加载文件越多,页面失去响应时间越长
具体写法如下:
1.在文件中首先要引入require.js,
2.定义一个模块
3.加载模块
1 define(function(){ 2 var keyboard = { 3 'init':function(){ 4 console.log(2); 5 } 6 } 7 return keyboard; 8 })
这是我们创建的一个文件keyboard.js;
<html> <head> <meta charset="utf-8"> <title>requireJs</title> <script src="./require.js"></script> </head> <body> <div>代码测试</div> <script> require(['./keyboard'],function(keyboard){ keyboard.init(); }) </script> </body> </html>
注意require的语法,这里引入是可以省略文件后缀.js的,后面function参数定义了这个模块的名称,函数内部直接调用就可以了。下面是编译后的代码,这里我们会看到我们引用的keyboard.js多了一个async属性,这里实现了异步加载。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
语法如下:
requireJS定义了一个函数 define,它是全局变量,用来定义模块
define(id?, dependencies?, factory);
- id:可选参数,用来定义模块的标识,如果没有提供该参数,脚本文件名(去掉拓展名)
- dependencies:是一个当前模块依赖的模块名称数组
- factory:工厂方法,模块初始化要执行的函数或对象。如果为函数,它应该只被执行一次。如果是对象,此对象应该为模块的输出值
在页面上使用require
函数加载模块
require([dependencies], function(){});
require()函数接受两个参数
- 第一个参数是一个数组,表示所依赖的模块
- 第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块
require()函数在加载依赖的函数的时候是异步加载的,这样浏览器不会失去响应,它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题
CMD使用方法:
1.引入seajs
2.定义模块文件
3.引入模块
4.seajsAPI:http://yslove.net/seajs/
代码示例如下:
<html> <head> <meta charset="utf-8"> <title>requireJs</title> <script src="./seajs.js"></script> </head> <body> <div>代码测试</div> <script> seajs.use('./keyboard',function(keyboard){ keyboard.init(); }) </script> </body> </html>
/*define(function(){ var keyboard = { 'init':function(){ console.log(2); } } return keyboard; })*/ //seajs define(function(require, exports, module) { // 模块代码 console.log(require,exports,module); module.exports ={ 'init':function(){ console.log(2); } } });
/*define(function(){ var keyboard = { 'init':function(){ console.log(2); } } return keyboard; })*/ //seajs /*define(function(require, exports, module) { // 模块代码 console.log(require,exports,module); module.exports ={ 'init':function(){ console.log(2); } } });*/ //seajs第二种定义 define(function(require, exports, module) { // 模块代码 console.log(require,exports,module); return { 'init':function(){ console.log(2); } } });
从上面可以看出,通过seajs定义模块时,需要注意写法,一种是直接return一个对象,另一种是module.exports,再看一下浏览器解析的效果
<html><head> <meta charset="utf-8"> <title>requireJs</title> <script src="./seajs.js"></script> </head> <body style=""> <div>代码测试</div> <script> seajs.use('./keyboard',function(keyboard){ keyboard.init(); }) </script> </body></html>
使用时,需要使用seajs.use(),更多用法,可以参考前面的api
CMD异步用法:
define(function(require, exports, module) { // 模块代码 console.log(require,exports,module); return { 'init':function(){ var $body = document.getElementsByTagName('body')[0]; var html = '<div>这是一个提示样式</div>'; $body.append(html); } } });
/*define(function(){ var keyboard = { 'init':function(){ console.log(2); } } return keyboard; })*/ //seajs /*define(function(require, exports, module) { // 模块代码 console.log(require,exports,module); module.exports ={ 'init':function(){ console.log(2); } } });*/ //seajs第二种定义 define(function(require, exports, module) { var loading = ''; // 模块代码 require.async('./loading',function(loading){ loading = loading.init(); }); return { 'init':function(){ console.log(2); }, 'loadingInit':function(){ console.log(loading); } } });
<html> <head> <meta charset="utf-8"> <title>requireJs</title> <script src="./seajs.js"></script> </head> <body> <div>代码测试</div> <script> seajs.use('./keyboard',function(keyboard){ keyboard.init(); keyboard.loadingInit(); }) </script> </body> </html>
在编译后的html中没有加载loading.js,keyboard.js,但是在network中会有显示,
<html><head> <meta charset="utf-8"> <title>requireJs</title> <script src="./seajs.js"></script> </head> <body style=""> <div>代码测试</div> <script> seajs.use('./keyboard',function(keyboard){ keyboard.init(); keyboard.loadingInit(); }) </script> <div>这是一个提示样式</div></body></html>
CommonJs:是主要为了JS在后端的表现制定的,他是不适合前端的,为什么这么说呢?前端主要的问题是1.带宽,2.加载时需要通过网络加载3.代码需要从一个服务器端分发到多个客户端执行
CommonJS定义的模块分为:{模块引用(require)} {模块定义(exports)} {模块标识(module)}
require()用来引入外部模块;exports对象用于导出当前模块的方法或变量,唯一的导出口;module对象就代表模块本身。
区别:
1、AMD推崇依赖前置,在定义模块的时候就要声明其依赖的模块
2、CMD推崇就近依赖,只有在用到某个模块的时候再去require
本文参考: