为什么我们要使用模块?
因为有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块。在解决一个复杂问题时,自顶向下逐层把系统划分成若干部分,有多种属性,分别反映其内部特性。
要实现模块化,就必须有一个前提,那就是统一标准。CommonJS、CMD 和 AMD 便应运而生了。
CommonJS
CommonJS API定义很多普通应用程序(主要指非浏览器的应用)使用的API,从而填补了 JavaScript 只能构建于浏览器之上这个空白。它的终极目标是提供一个类似Python,Ruby和Java标准库。这样的话,开发者可以使用CommonJS API编写应用程序,然后这些应用可以运行在不同的 JavaScript 解释器和不同的主机环境中。
CommonJS 定义的模块分为:{模块引用(require)} {模块定义(exports)}{模块标识(module)}
require()用来引入外部模块;exports对象用于导出当前模块的方法或变量,唯一的导出口;module对象就代表模块本身。
Node.JS 便是 CommonJS 标准的一种实现,将 JavaScript 语言用于服务器端编程。浏览器并不兼容 CommonJS 的根本原因,在缺少四个 Node.js 环境的变量:module、eports、require、global。只要能提供这四个变量,浏览器就能加载 CommonJS 模块。下面是一个简单的示例:
1 | var module = { |
上面代码向一个立即执行函数提供 module 和 exports 两个外部变量,模块就放在这个立即执行函数里面。模块的输出值放在 module.exports 之中,这样就实现了模块的加载。
AMD
CommonJS 规范虽然解决了 JavaScript “模块化”问题,但由于一个重大局限,使得它并不适合用于浏览器环境。如果在浏览器中运行,会有一个很大的问题,那就是require 是同步的。require 的阻塞加载会导致浏览器“假死”。在浏览器中只能想办法采用异步加载,AMD 便出现了。
它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。
1 | require(['math'], function (math) { |
它比 CommonJS 多了一个参数 callback ,既加载成功之后的回调函数。
目前,主要有两个 JavaScript 库实现了AMD规范:require.js 和 curl.js。
CMD
CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。
AMD 与 CMD 的区别
1.对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible。
2.CMD 推崇依赖就近,AMD 推崇依赖前置。
1 | // CMD |
3.AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。比如 AMD 里,require 分全局 require 和局部 require,都叫 require。CMD 里,没有全局 require,而是根据模块系统的完备性,提供 seajs.use 来实现模块系统的加载启动。CMD 里,每个 API 都简单纯粹。
最后更新: 2018年09月09日 22:43