1. 背景
JS的强大已经不用解释了,从Web RIA到Node服务器,到处都是JS的身影。然而由于出身的缘故,JS本身在大规模应用上存在着很多问题,比如模块化编程。本文以浏览器端模块化编程为内容,重点介绍AMD规范和CMD规范。在服务器端,NodeJS遵守的Common规范我们这里暂不讨论。
对于计算机语言,模块化编程是必不可少的,对架构设计、代码复用起到至关重要的作用,工程中引入别人写好的库和模块能大大缩减开发周期。C/C++中,我们可以用include;Java中我们可以用import。可是在JS中,这些是不存在的,取而代之的是script标签。
在浏览器端,我们可以通过script标签引入需要的库,然后加载自己的脚本,最后运行脚本。这样做似乎与include和import没什么区别,然而有几个重要的因素必须要考虑:JS是解释型语言,边加载边运行,后续脚本运行时,这些脚本所依赖的一切必须已经加载完毕;JS脚本加载时会阻塞浏览器,如果加载的JS很多很大,浏览器会卡住,带来很差的用户体验;通过调整script标签顺序可以修改JS模块之间的依赖,然而当模块很多时,这种做法就不可用了。
鉴于以上,JS模块化编程规范应运而生,并出现了大量实现。这些实现,简单讲就是一个超底层的JS库,这个库的作用有两个:一是完成JS脚本的异步加载与执行;二是确保JS脚本按照用户设计的依赖关系加载,即一段脚本执行时,它的所有依赖已经加载完毕了。不同的规范,只是写法用法不同而已,最终目的都是一样的。另外,模块化编程与异步加载不分家,会让JS按需加载,大大提高页面响应速度;模块加载提供命名空间的效果,有效防止作用域污染,并有一定的容错能力。
AMD规范和CMD规范是目前最为流行的两种模块化编程模式,符合AMD规范的库有RequireJS,符合CMD规范的库有SeaJS。
2. AMD(Asynchronous ModuleDefinition)规范
AMD翻译过来叫“异步的模块定义”,接口非常简单,只有一个define,完整格式如下:
define(‘module-name’, [‘lib1’, ‘lib2’], function (lib1, lib2) {
// todo