什么是模块化开发?
一个模块就是实现特定功能的文件,有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块。模块开发需要遵循一定的规范,否则就都乱套了。
在模块化开发思想下,所有单独存在的某一个文件都是一个模块。
CommonJS
CommonJS是服务器端模块的规范,Node.js采用了这个规范。Node.JS首先采用了js模块化的概念。
根据CommonJS规范,一个单独的文件就是一个模块。
输出模块:module.exports
输入模块:module.imports
AMD
AMD是一个在浏览器端模块化开发的规范。模块将被异步加载,模块加载不影响后面语句的运行。所有依赖某些模块的语句均放置在回调函数中。
优点:异步并行加载,在AMD的规范下,同时异步加载是不会产生错误的。
目前,实现AMD的库有RequireJS 、curl 、Dojo 、Nodules 等。
定义模块:
AMD规范只定义了一个函数 define,它是全局变量。函数的描述为:
define(id?, dependencies?, factory);
id:指定义中模块的名字,可选;
dependencies:依赖参数,可选的,如果忽略,它默认为["require", "exports", "module"]。
Factory:模块初始化要执行的函数或对象。如果为函数,它应该只被执行一次。如果是对象,此对象应该为模块的输出值。
例(config.js):
require.config({
baseUrl:'js/',
paths:{
'jquery':'jquery-3.1.1',
'index':'index'
}
});
(index.js)
function show() {
console.log("hello");
}
引用模块:
引入require.js文件
require.js中文网:http://www.requirejs.cn/docs/download.html
<script src="js/require.js" data-main="js/config"></script>
data-main:引入定义的模块
在引入require.js后使用模块:
<script>
require(['index'],function () {
show();
})
</script>
运行在浏览器上,会打印出hello
required.js就是为了解决这两个问题而诞生的:
1.实现js文件的异步加载,避免网页失去响应;
2.管理模块之间的依赖性,便于代码的编写和维护。
CMD
CMD(Common Module Definition)通用模块定义。该规范是在国内发展出来的。
在 CMD 规范中,一个模块就是一个文件。代码的书写格式如下:
define(factory);
factory 为函数时,表示是模块的构造方法。执行该构造方法,可以得到模块向外提供的接口。factory 方法在执行时,默认会传入三个参数:require、exports 和 module:
define(function(require, exports, module) {
// 模块代码
});
导出模块:export
导入模块:require
CMD规范地址:https://github.com/seajs/seajs/issues/242
Common.js,AMD,CMD的对比
RequireJS和common.js的三大区别:
1.Required.Js运行在浏览器上(客户端),CommonJS设计的时候没有考虑浏览器,所以它不适合浏览器环境,运行在服务器上
2.执行顺序不一样,common自动生成依赖关系,RequireJS手动执行依赖关系
3.Require.js主要提供define和require两个方法来进行模块化编程
commonJs通过module.imports, module.exports来进行模块化编程
AMD和CMD的区别:
1.AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。
CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。
2.对于依赖的模块
AMD:提前执行(异步加载:依赖先执行)+延迟执行
CMD:延迟执行(运行到需加载,根据顺序执行)
3.CMD 推崇依赖就近,AMD 推崇依赖前置。看如下代码:
// CMD
define(function(require, exports, module) {
var a = require('./a')
a.doSomething()
// 此处略去 n 行
var b = require('./b') // 依赖可以就近书写
b.doSomething()
// ...
})
// AMD 默认推荐的是
define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
a.doSomething()
// 此处略去 n 行
b.doSomething()
...
})
4. AMD:API根据使用范围有区别,但使用同一个api接口
CMD:每个API的职责单一
SeaJS与RequireJS的区别:
SeaJS对模块的态度是懒执行, 而RequireJS对模块的态度是预执行