seajs学习之模块的依赖加载及模块API的导出
前言
seajs非常强大,seajs可以加载任意 javascript 模块和css模块样式,seajs会保证你在使用一个模块时,已经将所依赖的其他模块载入到脚本运行环境中。
通过参照的demo,我们结合源码分析在简单的api调用的背后,到底使用了什么技巧来实现各个模块的依赖加载以及模块api的导出。
模块类和状态类
首先定义了一个module类,对应与一个模块
module有一些属性,uri对应该模块的绝对url,在module.define
函数中会有介绍;dependencies为依赖模块数组;exports为导出的api;status为当前的状态码;_waitings对象为当前依赖该模块的其他模块哈希表,其中key为其他模块的url;_remain为计数器,记录还未加载的模块个数。
上述为状态对象,记录模块的当前状态:模块初始化状态为0,当加载该模块时,为状态fetching;模块加载完毕并且缓存在cachemods后,为状态saved;loading状态意味着正在加载该模块的其他依赖模块;loaded表示所有依赖模块加载完毕,执行该模块的回调函数,并设置依赖该模块的其他模块是否还有依赖模块未加载,若加载完毕执行回调函数;executing状态表示该模块正在执行;executed则是执行完毕,可以使用exports的api。
模块的定义
commonjs规范规定用define
函数来定义一个模块。define可以接受1,2,3个参数均可,不过对于module/wrappings规范而言,module.declare
或者define
函数只能接受一个参数,即工厂函数或者对象。不过原则上接受参数的个数并没有本质上的区别,只不过库在后台给额外添加模块名。
seajs鼓励使用define(function(require,exports,module){})
这种模块定义方式,这是典型的module/wrappings规范实现。但是在后台通过解析工厂函数的require
方法来获取依赖模块并给模块设置id和url。
模块定义的最后,通过module.save
方法,将模块保存到cachedmods缓存体中。
parsedependencies
方法比较巧妙的获取依赖模块。他通过函数的字符串表示,使用正则来获取require(“…”)
中的模块名。
异步加载模块
加载模块可以有多种方式,xhr方式可以同步加载,也可以异步加载,但是存在同源问题,因此难以在此使用。另外script tag
方式在ie和现代浏览器下可以保证并行加载和顺序执行,script element
方式也可以保证并行加载但不保证顺序执行,因此这两种方式都可以使用。
在seajs中,是采用script element
方式来并行加载js/css资源的,并针对旧版本的webkit浏览器加载css做了hack。
其中有些细节还需注意,当采用script element
方法插入script节点时,尽量作为首个子节点插入到head中,这是由于一个难以发现的bug:
globaleval works incorrectly in ie6 if the current page has <base href> tag in the head
fetch模块
初始化module对象时,状态为0,该对象对应的js文件并未加载,若要加载js文件,需要使用上节提到的request
方法,但是也不可能仅仅加载该文件,还需要设置module对象的状态及其加载module依赖的其他模块。
这些逻辑在fetch
方法中得以体现:
其中seajs.request
就是上节的request
方法。onrequest
作为回调函数,作用是加载该模块的其他依赖模块。
总结
以上就是seajs模块的依赖加载及模块api的导出的全部内容了,小编会在下一节,将介绍模块之间依赖的加载以及模块的执行。感兴趣的朋友们可以继续关注。
下一篇: javascript库是什么东西
推荐阅读
-
通过seajs实现JavaScript的模块开发及按模块加载
-
通过seajs实现JavaScript的模块开发及按模块加载
-
seajs中模块依赖的加载处理实例分析
-
seajs学习之模块的依赖加载及模块API的导出
-
seajs模块之间依赖的加载以及模块的执行
-
json转js与js转json以及练习了ajax-xhr/fetch异步通讯以及模块常识,其中Promise状态及Promise中的Fetch API部分暂时还没进行示例学习操作
-
seajs模块之间依赖的加载以及模块的执行
-
seajs模块之间依赖的加载以及模块的执行
-
seajs模块之间依赖的加载以及模块的执行
-
json转js与js转json以及练习了ajax-xhr/fetch异步通讯以及模块常识,其中Promise状态及Promise中的Fetch API部分暂时还没进行示例学习操作