常见问题:RequireJS 高级用法

如何重命名 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 SextonTobie 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);
}
无噪 Logo
无噪文档
中文文档 · 复刻官网
查看所有 ↗