理解requirejs的几个重要点

require 遵循 AMD 规范,对依赖模块进行异步加载,等待异步加载完成,再执行回调。
所以有如下好处:

  • 天生异步
  • 依赖容易被识别
  • 避免全局变量
  • 如果需要可以懒加载
  • 容易管理和组织代码

这里不说 AMD 和 CMD,单纯讲讲在requirejs运行的几个关键点。

  1. 怎么去匹配一个模块的呢 ?
    require( [ 'a', 'b' ], callback ) a, b 就是我们的 moduleId ;
    id 和 path 之间有对应原则, 在 require 里面用一个 Map 对象以键值对形式保存, 这样加载器就能知道需要加载的路径

  2. 拿到模块的路径,怎么加载到页面 ?
    拿到路径,就需要请求。通过 createElement('script') & appendChild 去请求。
    当然也有可能有时会通过 ajax 去请求脚本内容。(ps: 什么时候会是 ajax 请求呢)
    create 的 <script> 标签会被 append 到页面的 head 头部。
    同时会被打上两个标记: data-requiremodule & data-requirecontext .
    data-requiremodule : 用来标识模块 id
    data-requirecontext: 上下文环境

  3. 怎么定义一个模块,定义的模块怎么执行 ?
    define( id?, dependencies?, factory )
    当我们 define(factory) 多个这样的自定义匿名模块时, 被加载进页面, 怎么知道当前是当前被定义的模块呢?
    刚才说了每个模块都有一个 id , 那么怎么知道这个模块的 id ?
    通过 document.currentScript 获取当前执行的 <script>,
    从而获取到用于标识当前模块的属性 data-requiremodule .
    ps 兼容处理: 通过 script.onload

  4. 依赖解析
    require 遵循 AMD 规范, 当进入一个 define / require 时候, 先加载完依赖确保能使用后, 才去执行 factory 回调, 并产出 export 接口(define).
    那依赖是怎么解析的出来的呢 ?
    简单的就是, 加载入口文件, 通过 toString() 获得函数内容, 再用正则去匹配 moduleId, 得到子模块。
    如果子模块还有依赖, 则会递归进行解析和加载 .

原文地址:https://www.cnblogs.com/travelling-wxy/p/5351777.html