AMD 插件加载器 Loader Plugins - 文章教程

AMD 插件加载器 Loader Plugins

发布于 2021-09-09 字数 5360 浏览 1131 评论 0

插件加载器是 AMD 规范的延生,它允许使用非传统的方法加载 JavaScript 依赖。

本 API 规范将允许使用插件加载器作为一种优化手段,将那些对该插件加载器敏感的插件资源加载到文本中。 出于兼容性考虑,一个插件加载器应该设计成能够在众多 JavaScript 环境下使用. 例如 browser、Node 或者 Rhino。

术语

插件依赖(plugin dependency) 是指按照 AMD 规范的插件加载器来加载的依赖,它的格式如:

[Plugin Module ID]![resource ID]

插件模块 ID(plugin module ID) 是一个普通的 AMD 模块 ID 名,它是实现了插件加载器 API 的 JavaScript 模块,资源 ID(resource ID) 是一个特定的插件标示字符串,它的作用是让插件加载器知晓如何去解析这个资源。

插件加载器例子

下面是一个用 text 插件加载器去加载一份 HTML 模板。


  define(['text!../templates/start.html'], function (template) {
    //do something with the template text string.
  });

下面是另外一个使用更加复杂的资源 ID 结构。这是一个人为的例子.它只选择第一个匹配到索引数组的模块ID名。因此,下面的impl变量的结果是’./b’所代表的模块:


  define(function (require) {
    var impl = require('index!1:./a:./b:./c');
  });

API 使用说明

load: function (resourceId, require, load, config)

load是用来加载资源的函数。为了能够加载插件,这是一个必需要实现的API方法。我们假设资源ID不需要特别的normalization (参见 normalize() method),下面是该方法的详细描述。

  • resourceId: 字符串类型. 待加载的插件资源ID名。该ID名必须是标准化(normalized)后的。
  • require: 函数类型. 一个用来加载其他模块的本地require函数。该require函数拥有如下属性:
  • load: 函数类型.当资源可用时,该函数将会且仅会被调用一次。它将插件加载完成的信息反馈给插件加载器。
  • config: 对象类型, 可选。一个配置对象。 它给优化工具和web app提供了一种传递配置信息的方法。 如果编译插件作为优化工具的一部分时,优化工具可以通过设置编译的属性配置为真来编译插件。

下面是一个普通的js模块加载,没做其他任何事情:


  define({
    load: function (name, req, load, config) {
      //req has the same API as require().
      req([name], function (value) {
        load(value);
      });
    }
  });

normalize: function (resourceId, normalize)

一个将传入的资源ID标准化的函数。模块ID的标准化通常指转换相对路径,比如将’./some/path’ 或者 ‘../another/path’转化成不含相对路径的绝对模块ID名。这对于使用缓存和优化来说将非常有用,但是只在如下情况下需要实现:

  • 资源ID的标准化过于复杂。
  • 只在资源名不是模块名时需要。

如果插件没有哦实现 normalize,那么加载器将默认它是规则的模块ID,并且试图标准化该模块 ID。

需要标准化的参数:

  • resourceId: string 类型,待标准化的资源ID.
  • normalize: Function 类型,一个依照当前加载器的配置,使用标准的模块相对路径转化规制,将传入的字符串ID转化成标准化模块ID的函数。

例如: 假设有个 index! 加载器,它将根据给出的模块名序列加载模块。这是一个反例,仅仅又来验证假设。This is a contrived example, just to illustrate the concept,一个模块可能依赖于加载器提供的依赖,如下所示:


  define(['index!2?./a:./b:./c'], function (indexResource) {
    //indexResource will be the module that corresponds to './c'.
  });

在这个例子中,已经标准化的 IDs’./a’, ‘./b’, 以及 ‘./c’将决定是否加载这个资源. 由于加载器不知道怎样去分析’index!2?./a:./b:./c’,并将其标准化为 ‘./a’, ‘./b’, 以及 ‘./c’, 它需要插件来提供信息。这就是调用标准化函数的目的。

通过标准化的资源名称,这将使得加载器缓存值得到有效利用,并在优化器中正确地构建一个优化构建层。与此同时,加载器也可以将标准化ID传递到插件 load 方法中。

index! 插件也可以这么使用:

  (function () {

    //Helper function to parse the 'N?value:value:value'
    //format used in the resource name.
    function parse(name) {
      var parts = name.split('?'),
        index = parseInt(parts[0], 10),
        choices = parts[1].split(':'),
        choice = choices[index];

      return {
        index: index,
        choices: choices,
        choice: choice
      };
    }

    //Main module definition.
    define({
      normalize: function (name, normalize) {
        var parsed = parse(name),
          choices = parsed.choices;

        //Normalize each path choice.
        for (i = 0; i < choices.length; i++) {
          //Call the normalize() method passed in
          //to this function to normalize each
          //module ID.
          choices[i] = normalize(choices[i]);
        }

        return parsed.index + '?' + choices.join(':');
      },

      load: function (name, require, load, config) {
        require([parse(name).choice], function (value) {
          load(value);
        });
      }
    });

  }());

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

目前还没有任何评论,快来抢沙发吧!

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

2512 文章
30 评论
82706 人气
更多

推荐作者

瑾兮

文章 11 评论 2

carlo_sn

文章 0 评论 0

15867725375

文章 0 评论 0

a3576419

文章 0 评论 0

wendy

文章 0 评论 0