常见问题:RequireJS 高级用法
- 如何重命名 require?§ 1
- 加载 CSS 怎么办?§ 2
如何重命名 require/define/requirejs?§ 1
要实现此功能,RequireJS 及其优化工具版本需为 0.26.0 或更高。
为什么需要这么做?你可能有非常严格的全局命名空间要求,或者正在使用的代码已经定义了 require/define,并且你想避免冲突。
关于这个功能的一些说明:
- 确保使用的是 require.js 的源码版本,而不是压缩版本。
- 确保将 require.js 的版本包含在优化过程中,因为 require.js 文件内容会被修改以实现命名空间功能。
- 按照常规方式使用 require/define 编写模块代码,然后执行构建以对这些值进行命名空间化。不要直接在模块中使用已命名空间化的 require/define。这会使你的代码可移植性和可用性降低。
- 此转换/优化仅能进行一次。请勿将此次优化的输出作为另一个优化/构建阶段的输入。
下面的示例优化配置基于该示例页面上的目录结构优化页面。此配置将 require.js 和 main.js 合并成一个新的foo.js文件。define() 将被重命名为foo.define()并且 require() 将被重命名为foo.require():
{
appDir: "../",
baseUrl: "scripts",
dir: "../../appdirectory-build",
//Put in a mapping so that 'requireLib' in the
//modules section below will refer to the require.js
//contents.
paths: {
requireLib: 'require'
},
//Indicates the namespace to use for require/requirejs/define.
namespace: "foo",
modules: [
{
name: "foo",
include: ["requireLib", "main"],
//True tells the optimizer it is OK to create
//a new file foo.js. Normally the optimizer
//wants foo.js to exist in the source directory.
create: true
}
]
}
完成此次优化后,原本引用 require.js 的 HTML 页面需要修改为引用 foo.js。
感谢Ryan Florence对命名空间设计提供的帮助。
另一种重命名的方法,如果你希望更直接地控制内容,并且愿意提交经过修改的源代码。这种方法不应与上述“命名空间”优化一起使用。
1) 修改 require.js 的源码
需要将 require.js 代码包裹在一个封装体中,以便你可以将 require 函数设置为你选择的名称:
var myGlobalRequire = (function () {
//Define a require object here that has any
//default configuration you want for RequireJS. If
//you do not have any config options you want to set,
//just use an simple object literal, {}. You may need
//to at least set baseUrl.
var require = {
baseUrl: '..'
};
//INSERT require.js CONTENTS HERE
return require;
}());
2) 修改加载的文件
对于任何使用此新函数加载的文件,如果这些文件以任何方式引用了 require,则需要将它们包装在一个匿名函数中,以将 require 的值设置为你在步骤 1 中设定的新函数名:
(function (require) {
//Regular require references now work correctly in here.
}(myGlobalRequire));
按照上述步骤操作后,你就能够使用优化工具有效地合并脚本。如果你想在优化后的脚本中包含重命名过的 require 定义,请在include优化选项中直接引用你修改后的 require.js,或者如果你希望直接优化该文件,则使用name选项。
感谢Alex Sexton和Tobie Langel提出了此解决方案的部分建议。
加载 CSS 怎么办?§ 2
理想情况下 RequireJS 可以将 CSS 文件作为依赖项来加载。然而,在 Gecko/Firefox 中从其他域加载文件时,很难判断 CSS 文件何时加载完成。可以在这个 Dojo 工单.
中找到一些背景信息。知道文件何时加载完毕是很重要的,因为你可能只希望在样式表加载完成后才获取某个 DOM 元素的尺寸。
有些人实现了这样的方法:通过查找特定 HTML 元素上是否应用了一个众所周知的样式来判断样式表是否已加载。由于该方案具有高度特异性,因此不太适合集成到 RequireJS 中。能得知 link 元素何时完成其引用文件的加载将是更为稳健的解决方案。
由于无法可靠地判断文件何时加载完成,在 RequireJS 中显式支持加载 CSS 文件并没有太大意义,因为这会导致因浏览器行为而引发 bug 报告。如果你并不关心文件何时加载完成,可以轻松编写自己的函数来按需加载 CSS,具体做法如下:
function loadCss(url) {
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = url;
document.getElementsByTagName("head")[0].appendChild(link);
}