模块的目的
为什么需要 javascript 的模块? 目的何在?
- 定义:怎么样能够将一块 javascript 的代码封装到一个单元里,怎么将它作为一个模块发挥它的价值?
- 依赖关系:怎么引用其他的代码块?
当今的 web
(function () {
var $ = this.jQuery;
this.myExample = function () {};
}());
当今的大部分 javascript 代码就是类似上面的写法?
- 通过一个立即执行的模式来包裹一块代码
- 然后把所有的依赖统统赛扫全局的变量域中.
- 而依赖关系是非常脆弱的,开发人员需要清除他们的依赖优先级,如
Backbone
的代码是不能够在jQuery
之前加载的. - 部署的时候需要额外的工具来压缩很多的
script
tag.
小项目没事,而大项目呢? 特别是应用了很多的零碎的 js 脚本库的情况下呢?手写他们显然不靠谱, 而且这样不能够很好地任意扩展.
CommonJS
CommonJS 从一开始工作的对象是 javascript 这个语言本身,而并不是浏览器里 js 的运行环境. 如果对于浏览器的环境, 通常是计划采用一个工具将这些代码转换为浏览器可以处理的状态.
- 在服务器端处理这些 CJS 模块
- 通过 XHR 下载这些代码然后在浏览器端编译他们.
同时 CJS 只允许一个文件只能包含一个模块定义, 所以在编译处理的时候通常都是需要多个文件多次处理.
- 网络加载
- 异步性
对于web 来发来说这样的方法显然比较费力. 而且对于这样事前编译的方式 debug 通常都很难做.
AMD
define(['jquery'] , function ($) {
return function () {};
});
AMD 的设计就是看上去基于当前的 web 开发 javascript 的写法那样,可以手动显式的管理当前代码段的依赖以及依赖的优先级. 而且这些代码都可以直接在浏览器里执行. debug 起来很简单并不需要服务器的一些工作作为辅助. 它借助的Dojo
的一些经验通过 ** XHR+eval*来避免了一些弱点. 它提高了当前 web 开发中的 *全局模式**, 因为:
- 通过借鉴 CommonJS 就是的 id 来标示依赖,清理了依赖关系并且避免了冲突发生.
- 这些文件通常可以保存在多个目录. 更加方便 mock 测试.
相比 CommonJS 它又如下优点:
- 浏览器友好
- 一个文件可以定义多个模块
- 可以返回一个函数,( node 里可以
module.exports=funciton(){}
但是 CommonJS 的定义里是不允许的,它要求始终返回一个对象.)