cmd规范:
- 特性:
- 一个模块就是一个单独的文件
- 由于每个模块都是属于define关键字函数的回调函数被调用,每个模块都是一个单独的作用域
- 预加载、懒执行(预加载就是预先把所有的模块全部加载完,懒执行就是需要执行哪块才执行哪块)
- 关键字
- define 定义一个模块
- require 加载一个模块
- exports 暴露一个模块
- module 模块
模块系统主要解决模块的定义、依赖和导出
伪代码如下:
替换成真正的代码:
sea.js
sea.js在互联网公司里面主要是一些现有的项目还在使用,但是从学习的角度上来说,还是可以学习的,可以让我们知道一个模块化的标准库主要有哪些API,另外我们的node.js的模块化方面的API和sea.js也是很像的。
-
用npm安装:
npm install seajs --save
-
文件夹名称含义
- dist 我们要引用的sea.js库的文件夹,其中sea.js是压缩过的,类似jquery.min.js,还有一个sea-debug.js,类似没压缩过的jQuery,方便我们debug调试的
- docs 文档
- lib 这是写了一个兼容node.js的版本,不用管
- src sea.js的源代码
- tests 测试文件
书写sea.js代码的步骤
- html文件中引入sea.js库
- 使用seajs.use加载主模块(也叫入口模块),起名一般叫main.js
- 模块的定义方法
- 在我们的sea.js当中一个模块就是一个文件
- 调用define函数定义主模块
- 用require函数加载其他第三方模块
- 用module.exports或exports来暴露当前模块的东西
- 注意点
- define(function(require,exports,module){});这里面的require,exports,module三个参数的名字是固定写法,不能简写,顺序不能错了 记忆方法:rem –> 依赖注入
- 如果define里的参数想省略,只能从后面开始省略,只要写了后面的,前面的必须要写上 –> 推荐写全,不要省
- 如果一个模块既不需要公开成员变量,也不需要依赖第三方模块,那么可以全部省略
- seajs.use(“入口模块”)可以加回调函数,形式如:seajs.use(“入口模块”,callback);
seajs的路径问题
- 在sea.js当中,js/main和./js/main的含义不是一样的
- js/main代表的是在sea.js所在的文件为基准去找,所以找到的是 –> seajs库所在的父级文件夹/js/main.js 这样的话会找不到的
- ./js/main代表的是以当前html文件去找
- seajs.use(),require(“xxx”) –> 其实这里的xxx叫模块标识,不是路径
- config的作用就是为了简化调用模块
- base 设置路径
- alias 设置模块的别名,简化调用
-
默认的base值是seajs库文件所在的父文件夹
-
注意:如果没有特殊说明,任何时候尽量用相对路径。
seajs如何把非cmd模块转换成cmd模块
不管是jQuery还是zepto,如果你想把它们改造成一个符合cmd规范的模块,必须加上一段类似上面的代码。
sea.js之module.exports与exports辨析
- 本质上用的还是module.exports这个对象,exports的值是module.exports 的引用地址,通过这种方式,我们可以少写一个”module.”
define(function(require,exports,module){
console.log(exports === module.exports); //true
})
- module.exports 指向新的对象时,exports 将会断开了与 module.exports 的引用
如何理解预加载、懒执行
预加载就是预先把所有的模块全部加载完,懒执行就是需要执行哪块才执行哪块
加载流程理解
- html文件加载主模块
- 主模块加载依赖的第三方模块
- 第三方模块如果还有其他的第三方模块依赖,则进一步加载其他第三方模块
sea.js模块加载原理分析
sea.js的require,use方法之所以能够加载js文件,本质上都是利用给script标签一个src属性地址,并且嵌入追加到DOM树中的时候,会自动去下载这个js文件并且会执行
function loadJs(path,callback){
var oHead = document.getElementsByTagName("head")[0];
var oNode = document.createElement("script");
var isSupportOnload = "onload" in oNode;
if(isSupportOnload){
oNode.onload = function(){
if(callback && typeof callback === 'function'){
callback();
}
}
}else{
oNode.onreadystatechange = function(){
if(oNode.readyState === 'loaded' || oNode.readyState === 'complete' && callback && typeof callback === 'function'){
callback();
}
}
}
oNode.setAttribute("type","text/javascript");
var reg = /\.js$/;
if(!reg.test(path)){
path += ".js";
}
oNode.setAttribute("src",path);
oHead.appendChild(oNode);
}