模块化开发概念
把JS文件划分开,避免全部冗余在一起
为什么需要模块化开发?
- 使文件更加清晰
- 模块之间的可以互相引用
- html中引入JS更加方便快捷
AMD、CMD、CommonJS规范介绍
-
AMD是RequireJS在推广过程中对模块定义的规范化产出
Asynchomous Module Definition(异步模块定义)
CMD是Sea.JS在推广过程中对模块定义的规范化产出
-
CommonJS是NodeJS使用的一种模块化方式
RequireJS
require.js是一个JavaScript文件和模块载入器
实现了JS文件的异步加载,避免网页失去响应
-
管理模块之间的依赖性,便于代码的编写与维护
RequireJS流程简述
- 使用requirejs时,会把所有的js都交给requirejs来管理,把data-main指向main.js
- 通过在main.js里面定义的require方法或者define方法,requirejs会把这些依赖和回调方法用一个数据结构保存起来
- 当页面加载时,requirejs会根据这些依赖预先把需要的js通过document.createElement的方法引入到DOM中
- 由于依赖的JS也是按照requirejs的规范来写的,所以他们也会有define或者require方法,同意类似的第二步这样循环向上查找依赖,同样进行保存
- 当js里需要用到依赖所返回的结果时(通常是一个键值对对象),requirejs便会把之前那个保存回调方法的数据结构里面的方法拿出来并且运行,然后把结果给需要依赖的方法
特殊说明:本身依赖的模块会比本身先加载
RequireJS基本使用
异步加载
异步加载requirejs
文件
async="true"
属性表明需要异步加载当前文件,由于IE不支持这个属性,需要添加defer
<script src="js/requirejs-2.2.0.js" async="true" defer charset="utf-8"></script>
同步加载,时间固定,按照代码的位置来。如果是异步加载,加载的时间不固定。
配置主模块
使用data-main
属性设置主模块
require.js
默认文件名后缀为js
,所以不需要添加后缀
<script src="js/requirejs-2.2.0.js" data-main="app" charset="utf-8"></script>
app.js
变量名 require
和 requirejs
完全一致
-
baseUrl
:配置公共路径 -
paths
:路径和名称的映射关系 -
shim
:解决模块不支持requirejs
和前置依赖等其它问题
requirejs.config({
baseUrl: './js', // 公共路径
paths: { // 给路径起名
jquery: 'jquery-2.2.3',
baiduTemplate: 'baiduTemplate',
zepto: 'zepto/zepto',
'zepto.event': 'zepto/src/event',
'zepto.ajax': 'zepto/src/ajax',
},
shim: { // 对模块的特殊处理
baiduTemplate: { // baiduTemplate默认不支持requirejs,需要配置
exports: 'baidu.template' // 导出对应的对象
},
zepto: { // zepto默认不支持requirejs,需要配置
exports: '$' // 导出$对象,方便外部使用
},
'zepto.event': { // event模块为
deps: ['zepto']
},
'zepto.ajax': {
deps: ['zepto']
}
}
});
引入模块
requirejs(['baiduTemplate', 'zepto'], function (baiduTemplate, $) {
$('h2').css('color', 'red');
$('h2').on('click', function () {
console.log('单击事件');
});
$.get('http://www.vrserver.applinzi.com/aixianfeng/apihome.php', function (data) {
// 使用模板生成数据,并拼接到页面中
var html = baiduTemplate('menu', {menu: data.data.menu})
$('header').html(html);
}, 'json');
});
定义模块
define(['jquery'], function ($) {
return {
changeColor: function () {
$('header').css('color', 'pink');
}
}
});
模块名称的问题
命名模块 | 匿名模块
jQuery源码,Line:9806
if ( typeof define === "function" && define.amd ) {
define( "jquery", [], function() {
return jQuery;
} );
}
使用RequireJS定义模块的时候,define()
函数有三个参数:
- 参数一,字符串,代表模块的名称,如果填写了,则必须使用
- 参数二,当前模块所依赖的其它模块
- 参数三,回调函数,参数为依赖的模块对应的映射