一、为什么需要模块化?
代码量骤增 => 分治管理的刚性需求
二、模块化方案需解决什么问题?
模块化要实现两个东西:模块加载与模块封装。面临的具体问题包括:
1、如何定义模块以确保模块的作用域独立,避免命名冲突?
2、如何管理模块间的依赖关系,避免重复加载与循环引用?
3、模块化的代码如何部署,以降低HTTP请求数?
4、如何实现按需加载?
5、如何在解决上述问题之后,保证性能且不影响debug?
三、原始的解决方案有何局限?
命名空间 + 立即执行函数 + script标签
局限性:
1、全局空间污染
2、需手动管理依赖,不具备可扩展性
3、无法实现按需加载
四、新的解决方案
1、CommonJS
CommonJS 起源于一个服务端项目 SeverJS,该项目意在通过模块化的开发模式, 解决 JS 作用域的问题。后来发展成了一个致力于构建 JS 生态圈的组织。
CommonJS 提供了一套模块加载的规范,其核心语法是通过 module.exports 暴露接口,通过 require() 加载资源。
CommonJS 规范采用同步加载,适用于服务端,但并不适用于浏览器环境(网络延迟、异步特性),因此在浏览器端出现了各类模块加载器,以解决模块加载的问题。
各类模块加载器提出了各自的模块封装的规范。其中 Sea.js 提出/实现的封装规范,就是 CMD 规范;RequireJS 提出/实现的封装规范,就是 AMD 规范。
2、Sea.js
模块封装:
define (function (require, exports, module) {
var a = require('./a') // 模块加载
a.doSomething();
// ……
var b = require('./b') // 依赖可以就近书写
b.doSomething();
// 通过 exports 对外提供接口
exports.doSomething = ...
// 或者通过 module.exports 提供整个接口
module.exports = ...
})
模块加载:
var $ = require('jquery');
3、RequireJS
模块封装:
define (['./a', './b'], function(a, b) {
a.doSomething();
// 此处略去 100 行
b.doSomething();
return function () { } //返回模块的值,可以是函数,也可以是对象
})
模块加载:
require (['./a', './b'], function (a, b) {
// do sth
})
区别
RequireJS:依赖前置,提前加载
Sea.js:依赖就近,延迟加载
4、UMD
一种兼容 CommonJS 和 AMD 的语法糖。事实上 RequireJS 和 Sea.js 就是相互支持的。
来源: http://www.cnblogs.com/kidney/p/6673189.html