AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义"。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。
AMD也采用require()语句加载模块,它要求两个参数require([module], callback);
列: require(['math'], function (math) {
math.add(2, 3);
});
AMD与CDM的区别:
(1)对于于依赖的模块,AMD 是提前执行(好像现在也可以延迟执行了),CMD 是延迟执行。
(2)AMD 推崇依赖前置,CMD 推崇依赖就近。
(3)AMD 推崇复用接口,CMD 推崇单用接口。
(4)书写规范的差异。
- // CMD
- define(function(require, exports, module) {
- var a = require('./a')
- a.doSomething()
- // 此处略去 100 行
- var b = require('./b') // 依赖可以就近书写
- b.doSomething()
- // ...
- })
-
- // AMD 默认推荐的是
- define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
- a.doSomething()
- // 此处略去 100 行
- b.doSomething()
- // ...
- })
UMD: 通用模块规范
既然CommonJs和AMD风格一样流行,似乎缺少一个统一的规范。所以人们产生了这样的需求,希望有支持两种风格的“通用”模式,于是通用模块规范(UMD)诞生了。
不得不承认,这个模式略难看,但是它兼容了AMD和CommonJS,同时还支持老式的“全局”变量规范
模块规范主要进行模块加载。
微信项目中我使用的是ES6规范(很好用加载模块,一个单独的文件也算是一个模块,一个模块就是和一个单独作用域(不会污染全局作用域),可以是说都是private(在CommonJS里面如果用共享变量必须定义global对象的属性))
提到ES6规范,前不久使用webpack用了一些CommonJS规范由此做一个对比。然后在后续在谈论AMD,CMD的使用性
1.ES6Module和CommonJS
(1)ES6Module
通过import 命令来加载其它模块提供的功能。
eg. import ReactDOM from 'react-dom';
通过export命令用于规定模块的对外接口。
eg.export default class parseTools extends ParseTools, export default class InputComponent extends React.Component
(2)CommonJS
(只在运行时加载意味着只在第一次加载时运行一次,然后结果缓存,后面在读取只读缓存,要让模块在运行,必须清除缓存)
(模块加载运行,就是代码出出现位置的顺序[0][1].....)
require :加载模块文件,然后返回模块的exports对象
eg:require('./example.js');
module.exports 对象,定义对外接口,其他文件加载这模块,就是读取module.exports变量。
eg:module.exports.x = (读取变量)
和明显就是用import替换require 用export取代module.exports
区别
ES6 在编译时就能确定模块的依赖关系 而CommonJS只能在运行时确定模块的依赖关系。
运行时加载:CommonJS模块就是对象;先加载整个模块,然后直接生成对象,然后再从这个整体的对象上读取方法,这种称为“运行时加载”;
编译时加载:ES6模块不是这样,采用的静态命令的形式。即在输入时可以指定加载摸个输出值的形式。而不是加载整个模块。
如果要加载整个模块: import * as DateComponents from './DateComponents.js';
2.如上所以CommonJS是先把整个模块加载完形成一个对象,在执行后面的操作,这意味着整个过程是一个同步事件,如果应用在服务器上,模块文件都存于本地硬盘加载比较快就不用考虑非同步加载的方式,所以CommonJS规范还是比较适用的。但是如果从浏览器环境,可能要从服务器端进行模块的加载 (可能导致性能上,可用性,调试和跨域访问等问题),这时就可能必须要使用非同步模式,所以就有了AMD规范。
AMD使用define方法定义模块,同时AMD允许输出的模块兼容CommonJS规范
define(['package/lib'],function(lib)){
function foo(){
Console.log("AMD");
}
return{};
}
同样能够使用require()来加载模块,不同于CommonJS,它要求两个参数:
require([module],callback); 第一个加载模块数组,第二个加载成功后的回调函数
Require就是实现AMD规范的,实现js文件的异步加载,管理模块的依赖性便于代码的维护。(后续再深入了解补充内容)