require 遵循 AMD 规范,对依赖模块进行异步加载,等待异步加载完成,再执行回调。
因此有以下好处:ajax
这里不说 AMD 和 CMD,单纯讲讲在requirejs运行的几个关键点。app
怎么去匹配一个模块的呢 ?
require( [ 'a', 'b' ], callback )
a, b 就是咱们的 moduleId ;
id 和 path 之间有对应原则, 在 require 里面用一个 Map 对象以键值对形式保存, 这样加载器就能知道须要加载的路径异步
拿到模块的路径,怎么加载到页面 ?
拿到路径,就须要请求。经过 createElement('script') & appendChild 去请求。
固然也有可能有时会经过 ajax 去请求脚本内容。(ps: 何时会是 ajax 请求呢)
create 的 <script>
标签会被 append 到页面的 head 头部。
同时会被打上两个标记: data-requiremodule
& data-requirecontext
.
data-requiremodule : 用来标识模块 id
data-requirecontext: 上下文环境函数
怎么定义一个模块,定义的模块怎么执行 ?
define( id?, dependencies?, factory )
当咱们 define(factory) 多个这样的自定义匿名模块时, 被加载进页面, 怎么知道当前是当前被定义的模块呢?
刚才说了每一个模块都有一个 id , 那么怎么知道这个模块的 id ?
经过 document.currentScript
获取当前执行的 <script>
,
从而获取到用于标识当前模块的属性 data-requiremodule
.
ps 兼容处理: 经过 script.onload
requirejs
依赖解析
require 遵循 AMD 规范, 当进入一个 define / require 时候, 先加载完依赖确保能使用后, 才去执行 factory 回调, 并产出 export 接口(define).
那依赖是怎么解析的出来的呢 ?
简单的就是, 加载入口文件, 经过 toString()
得到函数内容, 再用正则去匹配 moduleId, 获得子模块。
若是子模块还有依赖, 则会递归进行解析和加载 .ui