-
Notifications
You must be signed in to change notification settings - Fork 499
Loader Plugins(中文版)
插件加载器是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');
});
load是用来加载资源的函数。为了能够加载插件,这是一个必需要实现的API方法。我们假设资源ID不需要特别的normalization (参见normalize() method),下面是该方法的详细描述。
- resourceId: 字符串类型. 待加载的插件资源ID名。该ID名必须是标准化(normalized)后的。
-
require: 函数类型. 一个用来加载其他模块的本地require函数。该require函数拥有如下属性:
- require.toUrl("moduleId+extension"). 更多信息,请参见require.toUrl API notes。
- 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);
});
}
});
一个将传入的资源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);
});
}
});
}());