模块化
js在诞生之初,本来只是用来作为表单交互的一个脚本语言,只需要很简单的定义一些方法即可完成他的使命。所以在那个阶段,前端代码非常简洁,规模很小,逻辑关系简单。但随着js的发展,它需要处理的事情越来越多,并且随着nodejs的诞生,js不仅要处理浏览器客户端的事务,还需要去处理服务器端的数据处理逻辑,这极大的增加了代码的规模,将如此庞大的代码放在一个JS文件里面,让逻辑变得混乱不堪,难以维护。而原生的JS又不具备处理大规模代码的能力,于是开发人员为了提高开发的效率和代码的可维护性,开始在前端引入了模块化的概念。
在我看来,所谓的模块,就是一个文件,每个文件内部是一个完整的功能代码段,即每个文件实现一个相对独立的功能,而且内部使用自己的作用域,通过暴露自己的内部方法,让其它模块可以使用其内部定义的方法和变量。比如在commonJS里面,通过define定义一个模块,在模块内部使用export暴露其内部的方法和变量,在模块中通过require引入其它模块。这就和拼积木的思想是类似的,每个模块都是一块积木,我们的WEB应用就是通过将不同的模块拼接在一起形成的完整的个体。
模块化的精髓就在于,我们通过模块将代码拆分开来,实现了代码的复用,增加了可维护性,同时解除了代码的耦合,有利于团队的分工合作,提高了开发的效率。
AMD
AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义"。它是 RequireJS 在推广过程中对模块定义的规范化产出。也就是说,AMD是一种规范,是Require秉承的一种模块化的理念,我们使用RequireJS进行模块化开发,就是按AMD规定的套路在走。
AMD规范下的模块化开发有哪些特点?
1.AMD异步加载模块,适合于浏览器端的模块化开发。
所谓的异步加载,即加载模块的时候不会阻塞浏览器的运行。
2.AMD中依赖的模块,是需要预先在定义的时候就写清楚,并提前执行的。而提前执行(个人理解)指的是define定义的时候,其回调函数function(a,b){}需要等待其依赖的模块加载和执行完毕后才会执行。也就是依赖的模块在回调函数之前执行。(虽然也支持像CMD这样按需加载,但是AMD的官方是推荐在定义时确定依赖关系)
3.AMD使用define定义模块,使用require加载模块。
模块定义的一个基本形式为:
define(name,[依赖1,依赖2,依赖3...],函数)
(这里省略了模块名,会默认将文件名作为模块名)
define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
a.doSomething()
// 此处略去 100 行
b.doSomething()
...
})
如上所示,通过数组字面量的形式在定义模块的时候写明了依赖的两个模块。
模块加载的一个基本形式:
require([module], callback);
第一个参数[module],是一个数组,里面的成员就是要加载的模块;第二个参数callback,则是加载成功之后的回调函数。
require(['math'], function (math) {
math.add(2, 3);
});
这里面的['math']就是加载了math模块,后面是加载成功后的回调函数。