JS模块加载器加载原理

原理一:id即途径 准绳。

通常我们的入口是这样的: require( [ ‘a’, ‘b’ ], callback ) 。这里的 ‘a’、’b’ 都是 ModuleId。经过 id 和途径的对应准绳,加载器才干知道需求加载的 js 的途径。在这个例子里,就是 baseUrl + ‘a.js’ 和 baseUrl + ‘b.js’。

但 id 和 path 的对应关系并不是永远那么复杂,比如在 AMD 规范里就可以经过配置 Paths 来给特定的 id 指配 path。

原理二:createElement(‘script’) & appendChild

知道途径之后,就需求去央求。普通是经过 createElement(‘script’) & appendChild 去央求。这个大家都知道,不多说。有时分有的加载器也会经过 AJAX 去央求脚本内容。

普通来说,需求给 <script> 设置一个属性用来标识模块 id, 作用前面会提到。

原理三:document.currentScript

a.js 里能够是 define( id, factory ) 或许是 define( factory ),后者被称为匿名模块。那么当 define(factory) 被执行的时分,我们怎样知道以后被定义的是哪个模块呢,详细地说,这个匿名模块的实践模块 id 是什么? 答案是经过 document.currentScript 获取以后执行的<script>,然后经过下面给 script 设置的属性来失掉模块 id。

需求留意的是,低级阅读器是不支持 currentScript 的,这里需求停止阅读器兼容。在初级阅读器外面,还可以经过 script.onload 来处置这个事情。

原理四:依赖剖析

在继续讲之前,需求先复杂引见下模块的生命周期。模块在被 Define 之后并不是马上可以用了,在你执行它的 factory 方法来消费出最终的 export 之前,你需求保证它的依赖是可用的。那么首先就要先把依赖剖析出来。

复杂来说,就是经过 toString 这个方法失掉 factory 的内容,然后用正则去婚配其中的 require( ‘moduleId’ )。当然也可以不用正则。

这就是为什么 require( var ); 这种带变量的语句是不被引荐的,由于它会影响依赖剖析。假设一定要用变量,可以用 require( [ var ] ) 这种异步加载的方式。

完成一个可用的加载器自然不算复杂,但要说原理,大约就是这么几条。团体觉得,比起照着规范完成一个加载器,愈加吸引人的是 AMD 或许 CommonJS 这些规范的完善和面前的设计思绪。

提供最优质的资源集合

立即查看 了解详情