JavaScript模块化解决的问题:
1.如何安全的包装一个模块的代码(不污染模块化的任何代码)
2.如何唯一标识一个模块(避免命名冲突)
3.如何优雅的把模块的API暴露出去
4.如何方便的使用所依赖的模块
一、2009年,nodejs横空出世,制定了第一个模块化规范CommonJS,用于服务器端
包括内容:1.定义模块:一个单独的文件就是一个模块,文件中的作用域各自独立
2.输出:只有module.exports一个出口,将需要输出的内容放在其中
3.通过require加载,例如:var module = require('./module.js');
该module的值即对应文件内部的module.exports
对象, 然后就可以通过module名称去引用模块中的变量和函数了。
二、AMD(Asynchronous Module Definition)异部模块定义,用于浏览器端
库函数RequireJs,它解决了两个问题:
1.所依赖模块关系处理
2.加载js时页面会停止渲染(因为JavaScript是单线程语言),如果加载的js过多,页面渲染的时候会越长,等待时间就会越长
包括内容:
1.用全局变量define来定义模块,用法define(id,dependencies,factory)
id:定义模块标识,默认使用文件名(不带扩展名.js)
dependencies:标识该模块所依赖的模块名称,是一个数组;如果不写默认为['require','exports','module'],factory也会默认传入require、exports、module
factory:有函数function(){}和对象两种,
如果为函数,对外暴露的API有三种:return返回值、exports.xxx = xxx、module.exports = xxx
如果为对象,该对象就是模块的返回值
e.g.
//a.js
define(function(){
console.log('a.js');
function hello(){
console.log("hello,a.js")
}
return{
hello:hello
}
});
//加载模块
require(['a'],function(){
console.log('main.js');
a.hello();
})
执行结果:a.js
main.js
hello,a.js
发现问题:加载的模块被预先执行,如果加载的模块过多的话,不管这些模块是不是马上就被用到,对性能消耗是非常大的。
三、CMD(Common Module Define)通用模块定义
库函数Sea.js
//a.js
define(function(require,exports,module){
console.log('a.js');
function hello(){
console.log("hello,a.js")
}
return{
hello:hello
}
});
//加载模块
define(function(require,exports,module){
console.log('main.js');
var a=require('a');
a.hello();
})
执行结果:main.js
a.js
hello,a.js
解决了AMD预先执行的诟病,同时CMD对外暴露API的方式结合了CommonJS和AMD两种,有三种:return返回值、exports.xxx = xxx、module.exports = xxx
参考:http://www.reqianduan.com/3305.html
http://blog.youkuaiyun.com/gccll/article/details/52785685