1 为什么要模块化?
在阮一峰的博客中已经阐述得非常清楚了
http://www.ruanyifeng.com/blog/2012/11/require_js.html
2 模块化编程
模块化也就是加载js,加载js依赖的管理和使用过程,由于js存在同步和异步加载模式相应的也就有了同步和异步加载模式,即cmd,amd同步主要用于加载时间很短,比如nodejs的本地加载,而异步加载amd则用于
很耗时间的场景中。这些都是有commonjs规范中制约着。
3 AMD的实现
requirejs,和curljs两者都实现了amd加载的方式,实际项目中requirejs使用较多
4 requirejs
其实requirejs有一个js目录的约定吧,他约定我们的js目录如下,appjs为我们的模块入口
- www/
- index.html
- js/
- app/
- sub.js
- lib/
- jquery.js
- canvas.js
- app.js
- app/
1)requirejs加载js模块
通过require.config配置的paths进行,这里有一个根目录即baseUrl,这个很好理解,即js所在的相对根目录吧。
通paths配置的都不是直接在baseUrl目录下的js文件,他们可能是在本地其他目录,页可能是在网络cdn中 如
paths : {
"jquery" : ["https://cdn.bootcss.com/jquery/2.2.3/jquery.min"],
"BMap":["http://api.map.baidu.com/api?v=2.0&ak=MR2hswnEZnwAQM2jLL6IOF5i"],
"Backbone":["https://cdn.bootcss.com/backbone.js/1.3.3/backbone-min"],
"Underscore":["https://cdn.bootcss.com/underscore.js/1.8.3/underscore-min"]
}
对于非requirejs标准模块化的比如早期的jquery,backbonejs ,underscroejs等等,通过shim方式来转换为标准的模块即
shim:{
"jbox":{
deps:["jquery"],
exports:"Jbox"
},
"BMap":{
exports:"BMap"
},
"Backbone":{
deps:["Underscore","jquery"],
exports:"Backbone"
},
"Underscore":{
exports:"_"
}
}
这里可以理解为一个js库可能依赖其他js库,比如jquery插件必定依赖juqery,那么这个模块向外暴露后的通过exports进行导出,也就是说一个模块依赖谁,然后向外暴露的命名空间是什么就可以了,所以兼容了老的js库
2)标准的模块
requirejs实现了标准模块的定义方式,即通过define函数进行如
最简单的一个
(function($){
return {aa:"xxx"};
})(jQuery)
定义一个模块的时候,模块也可能依赖其他库,通过[""]数组方式申明依赖,通过function的方式定义一个模块,至于函数有没有返回,返回的是一个对象,还是一个函数可依据需求来确定
3)循环依赖
有时候一个模块a依赖b,反过来b又依赖a,就产生了循环依赖,当然循环依赖一般来说还是应该在设计上进行解决,那么如果真的出现了循环依赖了,怎么办呢?
比如说在模块b中,define(["a"],function(a){
其实此时a为undefine,那么再次加载一次就可以了
var a =require(["a"]);
})
4)包加载
有时候js组件是以package形式提供,其中package通过json配置文件是包的元数据文件,它描述了包的属性,如名称,版本,作者,维护,地址等等
按照requirejs 的约定包中应当包含一个mainjs文件作为包的命名空间根文件即入口文件。在requirejs中通过配置的方式来引入包如
require.config({ "packages": ["cart", "store"] }); require(["cart", "store", "store/util"], function (cart, store, util) { //use the modules as usual. });
这也是官方api使用的说明
5)require插件
require插件包括了domReady,async等等,这个可以通过github中开源插件说明中找到名下载使用
5 前景
由于前端的不断发展requirejs作为commonjs规范的一种实现,在某些框架中已经直接包含,或者由于requirejs配置的复杂性使用了更好的方式解决了模块化编程
参考文档:
阮一峰:http://www.ruanyifeng.com/blog/2012/10/asynchronous_module_definition.html