用法 § 1

加载JavaScript文件 § 1.1

与传统的<script>标记相比,RequireJS采用了不同的方法来加载脚本。尽管它还可以快速运行并优化得很好,但主要目标是鼓励使用模块化代码。作为其一部分,它鼓励使用模块ID代替脚本标记的URL。

RequireJS加载相对于baseUrl的所有代码。通常,将baseUrl设置为与data-main属性中使用的脚本相同的目录,以使顶级脚本加载页面。该数据主要属性是一个特殊的属性,require.js将检查启动脚本加载。本示例将以脚本的baseUrl结尾:

<!--This sets the baseUrl to the "scripts"directory, and
    loads a script that will have a module ID of 'main'-->
<script data-main="scripts/main.js"src="scripts/require.js"></script>

或者,可以通过RequireJS config手动设置baseUrl。如果没有显式配置并且未使用data-main,则默认的baseUrl是包含运行RequireJS的HTML页面的目录。

默认情况下,RequireJS还假定所有依赖项都是脚本,因此它不希望在模块ID上看到尾随的".js"后缀。在将模块ID转换为路径时,RequireJS将自动添加它。使用path config,您可以设置一组脚本的位置。与传统的 <script>标记相比,所有这些函数都允许您为脚本使用较小的字符串。

有时您确实希望直接引用脚本,而又不遵循"baseUrl +路径"规则来查找脚本。如果模块ID具有以下特征之一,则该ID将不会通过"baseUrl +路径"配置传递,而只会被视为与文档相关的常规URL:

  • 以".js"结尾。
  • 以"/"开头。
  • 包含URL协议,例如"http:"或"https:"。

通常,最好使用baseUrl和"paths"配置来设置模块ID的路径。这样,您可以在重命名和配置指向不同位置的路径以进行优化构建时更加灵活。

同样,为避免进行大量配置,最好避免对脚本使用较深的文件夹层次结构,而是将所有脚本都保留在baseUrl中,或者如果要从应用程序代码中分离库/供应商提供的代码,请使用目录布局如下:

  • www/
    • index.html
    • js/
      • app/
        • sub.js
      • lib/
        • jquery.js
        • canvas.js
      • app.js
      • require.js

在index.html中:

<script data-main="js/app.js"src="js/require.js"></script>

并在app.js中:

requirejs.config({
    //By default load any module IDs from js/lib
    baseUrl: 'js/lib',
    //except, if the module ID starts with "app",
    //load it from the js/app directory. paths
    //config is relative to the baseUrl, and
    //never includes a ".js"extension since
    //the paths config could be for a directory.
    paths: {
        app: '../app'
    }
});

// Start the main app logic.
requirejs(['jquery', 'canvas', 'app/sub'],
function   ($,        canvas,   sub) {
    //jQuery, canvas and the app/sub module are all
    //loaded and can be used here now.
});

请注意,作为该示例的一部分,像jQuery这样的供应商库在文件名中没有其版本号。如果要跟踪版本信息,建议将其存储在单独的文本文件中,或者如果使用诸如volo之类的工具,它将在package.json中标记版本信息,但将文件保留在磁盘上为"jquery"。 js"。这使您可以进行非常小的配置,而不必在每个库的"路径"配置中放置一个条目。例如,将"jquery"配置为"jquery-1.7.2"。

理想情况下,您加载的脚本将是通过调用define()定义的模块。但是,您可能需要使用某些传统/旧版的"浏览器全局变量"脚本,这些脚本无法通过define()表达它们的依赖性。对于那些,您可以使用shim config。正确表达其依赖性。

如果不表达依赖关系,则由于RequireJS异步加载脚本且速度不佳,可能会导致加载错误。

data-main 数据主入口点 § 1.2

data-main属性是require.js将检查以开始加载脚本的特殊属性:

<!--when require.js loads it will inject another script tag
    (with async attribute) for scripts/main.js-->
<script data-main="scripts/main"src="scripts/require.js"></script>

通常,您将使用数据主脚本来设置配置选项,然后加载第一个应用程序模块。注意:为您的数据主模块生成的脚本标签require.js包含async属性。这意味着您不能假定数据主脚本的加载和执行将在同一页面稍后引用的其他脚本之前完成。

例如,当在稍后需要require()之前未设置'foo'模块的require.config路径时,此安排将随机失败:

<script data-main="scripts/main"src="scripts/require.js"></script>
<script src="scripts/other.js"></script>
// contents of main.js:
require.config({
    paths: {
        foo: 'libs/foo-1.1.3'
    }
});
// contents of other.js:

// This code might be called before the require.config() in main.js
// has executed. When that happens, require.js will attempt to
// load 'scripts/foo.js' instead of 'scripts/libs/foo-1.1.3.js'
require(['foo'], function(foo) {

});

如果要require()在HTML页面中进行调用,则最好不要使用data-main。data-main仅在页面只有一个主要入口点data-main脚本时使用。对于要进行内联require()调用的页面,最好将其嵌套require()在配置调用中:

<script src="scripts/require.js"></script>
<script>
require(['scripts/config'], function() {
    // Configuration loaded now, safe to do other require calls
    // that depend on that config.
    require(['foo'], function(foo) {

    });
});
</script>

定义模块 § 1.3

模块与传统脚本文件的不同之处在于,它定义了一个范围广泛的对象,可避免污染全局名称空间。它可以显式列出其依赖关系,并在不需要引用全局对象的情况下获取这些依赖关系的句柄,而是将依赖关系作为定义模块的函数的参数来接收。RequireJS中的模块是Module Pattern的扩展,其优点是不需要全局变量来引用其他模块。

模块的RequireJS语法允许它们以尽可能快的速度加载,即使不按顺序加载,但以正确的依赖关系顺序进行评估,并且由于未创建全局变量,因此可以在页面中加载模块的多个版本。

(如果您熟悉或正在使用CommonJS模块,那么也请参阅CommonJS Notes以获取有关RequireJS模块格式如何映射到CommonJS模块的信息)。

磁盘上每个文件应该只有一个模块定义。可以通过优化工具将模块分组为优化的包。

简单名称/值对 § 1.3.1

如果模块没有任何依赖关系,而只是名称/值对的集合,则只需将对象文字传递给define():

//Inside file my/shirt.js:
define({
    color: "black",
    size: "unisize"
});

定义函数 § 1.3.2

如果模块没有依赖项,但是需要使用函数来完成一些设置工作,则定义自己,然后将函数传递给define():

//my/shirt.js now does setup work
//before returning its module definition.
define(function () {
    //Do setup work here

    return {
        color: "black",
        size: "unisize"
    }
});

具有依赖关系的定义函数§ 1.3.3

如果模块具有依赖项,则第一个参数应为依赖项名称数组,第二个参数应为定义函数。加载所有依赖项后,将调用该函数以定义模块。该函数应返回定义模块的对象。依赖项将作为函数参数传递给定义函数,列出的顺序与依赖项数组中的顺序相同:

//my/shirt.js now has some dependencies, a cart and inventory
//module in the same directory as shirt.js
define(["./cart", "./inventory"], function(cart, inventory) {
        //return an object to define the "my/shirt"module.
        return {
            color: "blue",
            size: "large",
            addToCart: function() {
                inventory.decrement(this);
                cart.add(this);
            }
        }
    }
);

在此示例中,创建了我/衬衫模块。这取决于我/购物车和我/库存。在磁盘上,文件的结构如下:

  • my/cart.js
  • my/inventory.js
  • my/shirt.js

上面的函数调用指定了两个参数:"购物车"和"库存"。这些是由"./cart"和"./inventory"模块名称表示的模块。

在加载了my/cart和my/inventory模块之后,该函数才被调用,并且该函数将这些模块作为"cart"和"inventory"参数接收。

明确建议不要使用定义全局变量的模块,以便一次在一个页面中可以存在一个模块的多个版本(请参阅高级用法)。此外,函数参数的顺序应与依赖项的顺序匹配。

函数调用的返回对象定义"我/衬衫"模块。通过以这种方式定义模块,"my/shirt"就不会作为全局对象存在。

将模块定义为函数§ 1.3.4

模块不必返回对象。允许从函数返回任何有效的返回值。这是一个返回函数作为其模块定义的模块:

//A module definition inside foo/title.js. It uses
//my/cart and my/inventory modules from before,
//but since foo/title.js is in a different directory than
//the "my"modules, it uses the "my"in the module dependency
//name to find them. The "my"part of the name can be mapped
//to any directory, but by default, it is assumed to be a
//sibling to the "foo"directory.
define(["my/cart", "my/inventory"],
    function(cart, inventory) {
        //return a function to define "foo/title".
        //It gets or sets the window title.
        return function(title) {
            return title ? (window.title = title) :
                   inventory.storeName + ' ' + cart.name;
        }
    }
);

定义与简体CommonJS的包装一个模块§ 1.3.5

如果您希望重用以传统CommonJS模块格式编写的某些代码,则可能难以对上面使用的依赖项数组进行重新处理,并且您可能更希望将依赖项名称直接与用于此的本地变量对齐依赖性。在以下情况下,可以使用简化的CommonJS包装器:

define(function(require, exports, module) {
        var a = require('a'),
            b = require('b');

        //Return the module value
        return function () {};
    }
);

该包装器依赖于Function.prototype.toString()给出函数内容的有用字符串值。这在某些设备(例如PS3和某些较旧的Opera移动浏览器)上不起作用。使用优化器以数组格式提取依赖项,以在这些设备上使用。

有关更多信息,请参见CommonJS页面,以及"为什么选择AMD"页面的"糖"部分。

定义一个具有名称的模块§ 1.3.6

您可能会遇到一些define()调用,其中包含模块的名称作为define()的第一个参数:

    //Explicitly defines the "foo/title"module:
    define("foo/title",
        ["my/cart", "my/inventory"],
        function(cart, inventory) {
            //Define foo/title object in here.
       }
    );

这些通常是由优化工具生成的。您可以自己显式命名模块,但这会使模块的可移植性降低-如果将文件移动到另一个目录,则需要更改名称。通常最好避免为模块的名称编码,而让优化工具以模块名称的形式进行刻录。优化工具需要添加名称,以便一个文件中可以捆绑多个模块,以允许在浏览器中更快地加载。

其他模块说明§ 1.3.7

每个文件一个模块注意:鉴于模块名称到文件路径查找算法的性质,每个JavaScript文件只能定义一个模块。您仅应使用优化工具将多个模块分组为优化文件。

define()中的相对模块名称: 对于在define()函数调用中可能发生的require("./ relative/name")调用,请务必要求"require"作为依赖项,以便解析相对名称正确地:

define(["require", "./relative/name"], function(require) {
    var mod = require("./relative/name");
});

或更妙的是,使用可用于翻译CommonJS模块的缩短的语法:

define(function(require) {
    var mod = require("./relative/name");
});

这种形式将使用Function.prototype.toString()查找require()调用,并将它们与"require"一起添加到依赖项数组中,因此代码可以在相对路径下正常工作。

如果要在目录中创建一些模块,则相对路径非常有用,这样您就可以与其他人或其他项目共享目录,并且希望能够获得该目录中同级模块的句柄而不必知道目录的名称。

相对模块名称相对于其他名称,而不是路径: 加载程序按模块名称而不是内部路径存储模块。因此,对于相对名称引用,相对于引用的模块名称进行解析,然后如果需要加载,则将该模块名称或ID转换为路径。其中具有"main"和"extras"模块的"compute"包的示例代码:

* lib/
    * compute/
        * main.js
        * extras.js

main.js模块如下所示:

define(["./extras"], function(extras) {
    //Uses extras in here.
});

如果这是路径配置:

require.config({
    baseUrl: 'lib',
    paths: {
      'compute': 'compute/main'
    }
});

并且require(['compute'])做了,那么LIB /计算/ main.js将有"计算"的模块名称。当它要求"./extras"时,相对于"compute"可以解决,因此"compute /./ extras"将其标准化为"extras"。由于没有用于该模块名称的路径配置,因此生成的路径将用于"lib/extras.js",这是不正确的。

在这种情况下,packages config是一个更好的选择,因为它允许将主模块设置为"compute",但是在内部加载程序将以ID"compute/main"存储该模块,以便"./演员的作品。

另一个选择是在lib/compute.js处构建一个模块just define(['./compute/main'], function(m) { return m; });,那么就不需要路径或程序包配置了。

或者,不要设置路径或程序包配置,并且不要在顶层要求调用as require(['compute/main'])。

生成相对于模块的URL: 您可能需要生成相对于模块的URL。为此,要求"require"作为依赖项,然后使用require.toUrl()生成URL:

define(["require"], function(require) {
    var cssUrl = require.toUrl("./style.css");
});

控制台调试: 如果需要使用已经通过require(["module/name"], function(){})JavaScript控制台中的调用加载的模块,则可以使用require()表单,该表单仅使用模块的字符串名称来获取它:

require("module/name").callSomeFunction()

请注意,这仅在先前通过require:的异步版本加载"模块/名称"时有效require(["module/name"])。如果使用相对路径,例如"./module/name",则这些仅在内部定义

循环依赖§ 1.3.8

如果定义循环依赖关系("a"需要"b","b"需要"a"),则在这种情况下,当调用"b"的模块函数时,它将获得"a"的未定义值。在使用require()方法定义模块之后,"b"可以稍后获取"a"(请确保将require指定为依赖项,以便使用正确的上下文查找"a"):

//Inside b.js:
define(["require", "a"],
    function(require, a) {
        //"a"in this case will be null if "a"also asked for "b",
        //a circular dependency.
        return function(title) {
            return require("a").doSomething();
        }
    }
);

通常,您不需要使用require()来获取模块,而是依靠将模块作为参数传递给函数。循环依赖很少见,通常是您可能需要重新考虑设计的信号。但是,有时需要它们,在这种情况下,请使用上面指定的require()。

如果您熟悉CommonJS模块,则可以使用导出为该模块创建一个空对象,该空对象可立即供其他模块引用。通过在循环依赖关系的两侧执行此操作,然后可以安全地保留另一个模块。仅当每个模块都为模块值而不是函数导出对象时,此方法才有效:

//Inside b.js:
define(function(require, exports, module) {
    //If "a"has used exports, then we have a real
    //object reference here. However, we cannot use
    //any of "a"'s properties until after "b"returns a value.
    var a = require("a");

    exports.foo = function () {
        return a.bar();
    };
});

或者,如果您使用的是依赖项数组方法,则要求特殊的 "导出"依赖项:

//Inside b.js:
define(['a', 'exports'], function(a, exports) {
    //If "a"has used exports, then we have a real
    //object reference here. However, we cannot use
    //any of "a"'s properties until after "b"returns a value.

    exports.foo = function () {
        return a.bar();
    };
});

指定JSONP服务依赖性§ 1.3.9

JSONP是使用JavaScript调用某些服务的一种方式。它跨域工作,并且是一种仅通过脚本标签仅需要HTTP GET即可调用服务的既定方法。

要在RequireJS中使用JSONP服务,请指定"define"作为回调参数的值。这意味着您可以获得JSONP URL的值,就好像它是模块定义一样。

这是一个调用JSONP API端点的示例。在此示例中,JSONP回调参数称为"callback",因此"callback = define"告诉API将JSON响应包装在"define()"包装器中:

require(["http://example.com/api/data.json?callback=define"],
    function (data) {
        //The data object will be the API response for the
        //JSONP data call.
        console.log(data);
    }
);

JSONP的这种使用应限于初始应用程序设置的JSONP服务。如果JSONP服务超时,则意味着可能无法执行通过define()定义的其他模块,因此错误处理不可靠。

仅支持作为JSON对象的JSONP返回值.数组,字符串或数字的JSONP响应将不起作用。

此函数不应用于长轮询JSONP连接-用于处理实时流的API。这类API在收到每个响应后应该执行更多的脚本清理工作,并且RequireJS仅会提取一次JSONP URL-随后将相同的URL作为require()或define()调用中的依赖项使用,将获得一个缓存的值。

加载JSONP服务的错误通常会通过该服务的超时而浮出水面,因为脚本标记加载不会为网络问题提供太多详细信息。要检测错误,可以重写requirejs.onError()以获取错误。在"处理错误"部分中有更多信息。

取消定义模块§ 1.3.10

有一个全局函数requirejs.undef(),它允许取消定义模块。它将重置加载程序的内部状态,以忽略模块的先前定义。

但是,它将不会从其他已定义的模块中删除该模块,并且在执行时会将该模块作为依赖项获得该模块的句柄。因此,只有在没有其他模块都无法处理该模块值的错误情况下使用它,或者作为将来可能使用该模块的模块加载的一部分,它才真正有用。有关示例,请参见errback部分。

如果要进行更复杂的依赖关系图分析以进行未定义的工作,则半私有的 onResourceLoad API可能会有所帮助。

力学 § 2

RequireJS使用head.appendChild()将每个依赖项作为脚本标签加载。

RequireJS等待所有依赖项加载,找出正确的顺序来调用定义模块的函数,然后在调用这些函数的依赖项后调用模块定义函数。请注意,由于给定模块定义函数的子依赖关系和网络负载顺序,可以按任何顺序调用它们的依赖关系。

在具有同步加载的服务器端JavaScript环境中使用RequireJS就像重新定义require.load()一样容易。构建系统会执行此操作,可以在build/jslib/requirePatch.js中找到该环境的require.load方法。

将来,此代码可能作为可选模块被拉入require /目录,您可以在环境中加载该模块以根据主机环境获得正确的加载行为。

配置选项 § 3

在顶层HTML页面(或未定义模块的顶层脚本文件)中使用require()时,可以将配置对象作为第一个选项传递:

<script src="scripts/require.js"></script>
<script>
  require.config({
    baseUrl: "/another/path",
    paths: {
        "some": "some/v1.0"
    },
    waitSeconds: 15
  });
  require( ["some/module", "my/module", "a.js", "b.js"],
    function(someModule,    myModule) {
        //This function will be called when all the dependencies
        //listed above are loaded. Note that this function could
        //be called before the page is loaded.
        //This callback is optional.
    }
  );
</script>

您也可以从数据主入口点调用require.config ,但是请注意,数据主脚本是异步加载的。避免使用其他入口点脚本,这些脚本错误地假定data-main及其require.config将始终在脚本加载之前执行。

另外,可以require 在加载require.js 之前将config对象定义为全局变量,并自动应用值。此示例指定了一些要在require.js定义require()时加载的依赖项:

<script>
    var require = {
        deps: ["some/module1", "my/module2", "a.js", "b.js"],
        callback: function(module1, module2) {
            //This function will be called when all the dependencies
            //listed above in deps are loaded. Note that this
            //function could be called before the page is loaded.
            //This callback is optional.
        }
    };
</script>
<script src="scripts/require.js"></script>

注意: 最好使用var require = {}并且不要使用 window.require = {},它将在IE中无法正确运行。

支持的配置选项:

baseUrl: 用于所有模块查找的根路径。因此,在上面的示例中,"my/module"的脚本标签将具有src ="/another/path/my/module.js"。是的baseUrl不装入普通.js文件时使用的(由一个依赖字符串指示开始以斜线,具有协议,或在端部的.js),这些字符串被原样使用,所以a.js和b.js将从与包含上述代码段的HTML页面相同的目录中加载。

如果在配置中未显式设置baseUrl,则默认值将是加载require.js的HTML页面的位置。如果使用data-main属性,则该路径将成为baseUrl。

baseUrl可以是与将加载require.js的页面不同的域上的URL。RequireJS脚本加载跨域工作。唯一的限制是文本加载的文本内容!插件:至少在开发过程中,这些路径应与页面位于同一域。优化工具将内联文本!插件资源,因此在使用优化工具后,您可以使用引用文本的资源!来自另一个域的插件资源。

paths: 在baseUrl的正下方找不到模块名称的路径映射。除非路径设置以"/"开头或其中包含URL协议(例如"http:"),否则假定该路径设置相对于baseUrl。使用上面的示例配置,"some/module"的脚本标签将为src ="/another/path/some/v1.0/module.js"。

被用于模块名称应该路径不包括扩展名,因为路径映射可能是一个目录。当将模块名称映射到路径时,路径映射代码将自动添加.js扩展名。如果使用了require.toUrl(),它将添加适当的扩展名(如果用于文本模板)。

在浏览器中运行时,可以指定路径回退,以允许尝试从CDN位置进行加载,但是如果CDN位置无法加载,则回退到本地位置。

bundles: 在RequireJS 2.1.10中引入:允许配置多个模块ID,这些ID在另一个脚本中找到。例:

requirejs.config({
    bundles: {
        'primary': ['main', 'util', 'text', 'text!template.html'],
        'secondary': ['text!secondary.html']
    }
});

require(['util', 'text'], function(util, text) {
    //The script for module ID 'primary' was loaded,
    //and that script included the define()'d
    //modules for 'util' and 'text'
});

该配置指出:模块"main","util","text"和"text!template.html"将通过加载模块ID"primary"来找到。可以通过加载模块ID"secondary"来找到模块​​"text!secondary.html"。

这仅设置了在脚本中包含多个define()模块的模块中查找模块的位置。它不会自动将那些模块绑定到捆绑软件的模块ID。捆绑软件的模块ID仅用于查找模块集。

使用path config可能会发生类似的事情,但是它要复杂得多,并且path config路由不允许在其配置中使用加载程序插件资源ID,因为path config的值是路径段而不是ID。

如果执行构建并且该构建目标不是现有的模块ID,或者如果已构建的JS文件中包含不应由加载程序插件加载的加载程序插件资源,则bundles config很有用。请注意,键和值是模块ID,而不是路径段。它们是绝对模块ID,而不是像path config或map config这样的模块ID前缀。另外,bundle config与map config的不同之处在于map config是一对一的模块ID关系,其中bundle config用于将多个模块ID指向bundle的模块ID。

从RequireJS 2.2.0开始,优化器可以生成bundle config并将其插入到顶层requirejs.config()调用中。有关更多详细信息,请参见bundlesConfigOutFile构建配置选项。

shim:为不使用define()声明依赖关系和设置模块值的较旧的传统"浏览器全局变量"脚本配置依赖关系,导出和自定义初始化。

这是一个例子。它需要RequireJS 2.1.0+,并假定在baseUrl目录中已安装了ribs.js,underscore.js和jquery.js。如果没有,那么您可能需要为它们设置路径配置:

requirejs.config({
    //Remember: only use shim config for non-AMD scripts,
    //scripts that do not already call define(). The shim
    //config will not work correctly if used on AMD scripts,
    //in particular, the exports and init config will not
    //be triggered, and the deps config will be confusing
    //for those cases.
    shim: {
        'backbone': {
            //These script dependencies should be loaded before loading
            //backbone.js
            deps: ['underscore', 'jquery'],
            //Once loaded, use the global 'Backbone' as the
            //module value.
            exports: 'Backbone'
        },
        'underscore': {
            exports: '_'
        },
        'foo': {
            deps: ['bar'],
            exports: 'Foo',
            init: function (bar) {
                //Using a function allows you to call noConflict for
                //libraries that support it, and do other cleanup.
                //However, plugins for those libraries may still want
                //a global. "this"for the function will be the global
                //object. The dependencies will be passed in as
                //function arguments. If this function returns a value,
                //then that value is used as the module export value
                //instead of the object found via the 'exports' string.
                //Note: jQuery registers as an AMD module via define(),
                //so this will not work for jQuery. See notes section
                //below for an approach for jQuery.
                return this.Foo.noConflict();
            }
        }
    }
});

//Then, later in a separate file, call it 'MyModel.js', a module is
//defined, specifying 'backbone' as a dependency. RequireJS will use
//the shim config to properly load 'backbone' and give a local
//reference to this module. The global Backbone will still exist on
//the page too.
define(['backbone'], function (Backbone) {
  return Backbone.Model.extend({});
});

在RequireJS 2.0。*中,shim配置中的"exports"属性可能是函数而不是字符串。在这种情况下,它的函数与上述"init"属性相同。"init"模式在RequireJS 2.1.0+中使用,因此exports可以将字符串值用于 forceDefine,但是一旦已知已加载库,就可以进行函数工作。

对于只是jQuery或Backbone插件的"模块",不需要导出任何模块值,shim配置可以只是一个依赖项数组:

requirejs.config({
    shim: {
        'jquery.colorize': ['jquery'],
        'jquery.scroll': ['jquery'],
        'backbone.layoutmanager': ['backbone']
    }
});

但是请注意,如果要在IE中进行404负载检测,以便可以使用路径回退或errbacks,则应提供字符串输出值,以便加载程序可以检查脚本是否实际加载(init的返回不用于enforceDefine检查):

requirejs.config({
    shim: {
        'jquery.colorize': {
            deps: ['jquery'],
            exports: 'jQuery.fn.colorize'
        },
        'jquery.scroll': {
            deps: ['jquery'],
            exports: 'jQuery.fn.scroll'
        },
        'backbone.layoutmanager': {
            deps: ['backbone']
            exports: 'Backbone.LayoutManager'
        }
    }
});

"shim"配置的重要说明:

  • 填充程序配置仅设置代码关系。要加载属于shim config或使用shim config的模块,需要一个正常的require/define调用。本身设置填充程序不会触发代码加载。
  • 仅将其他"填充程序"模块用作填充脚本的依赖性,或者将不具有依赖性的AMD库也创建全局变量(如jQuery或lodash)后调用define()。否则,如果您将AMD模块用作垫片配置模块的依赖项,则在构建之后,可能要等到构建中的填充代码执行后,才能评估该AMD模块,否则会发生错误。最终的解决方法是将所有填充的代码升级为具有可选的AMD define()调用。
  • 从RequireJS 2.1.11开始,如果无法升级填充代码以使用AMD define()调用,则优化器具有 wrapShim构建选项,该选项将尝试自动将填充代码包装在define()中以进行构建。这会更改填充的依赖项的范围,因此不能保证始终起作用,但是,例如,对于依赖于AMD版本的Backbone的填充的依赖项,它可能会有所帮助。
  • 对于AMD模块,不会调用init函数。例如,您不能使用shim init函数来调用jQuery的noConflict。请参阅映射模块以将noConflict 用于jQuery的替代方法。
  • 通过RequireJS在Node中运行AMD模块时,不支持Shim config(尽管它可用于优化程序)。取决于要填充的模块,它可能在Node中失败,因为Node与浏览器没有相同的全局环境。从RequireJS 2.1.7开始,它将在控制台中警告您不支持shim config,并且它可能会或可能不会起作用。如果您希望隐藏该消息,则可以通过requirejs.config({ suppress: { nodeShim: true }});。

"shim"配置的重要优化器说明:

  • 您应该使用mainConfigFile构建选项来指定可在其中找到垫片配置的文件。否则,优化程序将不了解填充程序配置。另一个选项是在构建配置文件中复制填充程序配置。
  • 不要在构建中将CDN加载与shim config混合使用。示例方案:从CDN加载jQuery,但使用shim配置加载类似于jQuery的Backbone的普通版本。在执行构建时,请确保在内建文件中内联jQuery,并且不要从CDN加载它。否则,Backbone将内联到生成的文件中,并在CDN加载的jQuery加载之前执行。这是因为shim config只是延迟文件的加载,直到加载依赖项为止,但不对define进行任何自动包装。构建后,依赖关系已经内联,shim配置无法将non-define()代码的执行推迟到以后。限定()' d模块在构建后确实可以处理CDN加载的代码,因为它们将其源代码正确包装在define factory函数中,只有在加载依赖项后才能执行。因此,课程:shim config是非模块化代码,传统代码的权宜之计。define()的模块更好。
  • 对于本地的多文件构建,上述CDN建议也适用。对于任何匀场脚本,必须在匀场脚本执行之前加载其依赖项。这意味着要么直接在包含填充脚本的buid层中构建其依赖项,要么通过require([], function (){})调用加载其依赖项,然后require([])对具有填充脚本的构建层进行嵌套调用。
  • 如果您使用uglifyjs缩小代码,请不要将uglify选项设置toplevel为true,或者如果使用命令 行不通过-mt。该选项会破坏shim用于查找出口的全局名称。

map: 对于给定的模块前缀,而不是使用给定的ID加载模块,而是使用其他模块ID。

这种函数对于大型项目而言非常重要,因为大型项目可能有两组模块需要使用两个不同的'foo'版本,但是它们仍然需要彼此合作。

使用上下文支持的多版本支持是不可能的。另外,路径配置仅用于设置模块ID的根路径,而不用于将一个模块ID映射到另一个模块。

map 示例:

requirejs.config({
    map: {
        'some/newmodule': {
            'foo': 'foo1.2'
        },
        'some/oldmodule': {
            'foo': 'foo1.0'
        }
    }
});

如果模块按如下方式布置在磁盘上:

  • foo1.0.js
  • foo1.2.js
  • some/
    • newmodule.js
    • oldmodule.js

当'some/newmodule'执行`require('foo')`时,它将获取foo1.2.js文件;当'some/oldmodule'执行`require('foo')`时,它将获取foo1.0。 js文件。

该函数仅适用于调用了define()并注册为匿名模块的真实AMD模块的脚本。另外,仅对映射配置使用绝对模块ID。相对ID(如'../some/thing')不起作用。

还支持"*"映射值,这意味着"对于所有加载的模块,请使用此映射配置"。如果有更具体的地图配置,则该配置优先于星型配置。例:


requirejs.config({
    map: {
        '*': {
            'foo': 'foo1.2'
        },
        'some/oldmodule': {
            'foo': 'foo1.0'
        }
    }
});

表示对于除"some/oldmodule"以外的任何模块,当需要"foo"时,请改用"foo1.2"。仅对于"some/oldmodule",当要求"foo"时使用"foo1.0"。

注意: 使用map config进行构建时,需要将map config馈送到优化器,并且build输出必须仍然包含requirejs config调用来设置map config。优化器在构建期间不会进行ID重命名,因为项目中的某些依赖项引用可能取决于运行时变量状态。因此,优化器不会在构建后使对映射配置的需求无效。

config: 通常需要将配置信息传递给模块。该配置信息通常被称为应用程序的一部分,并且需要一种将其传递给模块的方法。在RequireJS中,这是通过requirejs.config()的 config选项完成的。然后,模块可以通过请求特殊的依赖项"模块"并调用 module.config()来读取该信息。例:

requirejs.config({
    config: {
        'bar': {
            size: 'large'
        },
        'baz': {
            color: 'blue'
        }
    }
});

//bar.js, which uses simplified CJS wrapping:
//https://requirejs.org/docs/whyamd.html#sugar
define(function (require, exports, module) {
    //Will be the value 'large'
    var size = module.config().size;
});

//baz.js which uses a dependency array,
//it asks for the special module ID, 'module':
//https://github.com/requirejs/requirejs/wiki/Differences-between-the-simplified-CommonJS-wrapper-and-standard-AMD-define#wiki-magic
define(['module'], function (module) {
    //Will be the value 'blue'
    var color = module.config().color;
});

要将config传递给软件包,请以软件包中的主模块为目标,而不是软件包ID为目标:

requirejs.config({
    //Pass an API key for use in the pixie package's
    //main module.
    config: {
        'pixie/index': {
            apiKey: 'XJKDLNS'
        }
    },
    //Set up config for the "pixie"package, whose main
    //module is the index.js file in the pixie folder.
    packages: [
        {
            name: 'pixie',
            main: 'index'
        }
    ]
});

packages: 配置来自CommonJS包的加载模块。请参阅软件包主题以获取更多信息。

nodeIdCompat: Node治疗模块IDexample.js和example相同的。默认情况下,这是RequireJS中的两个不同ID。如果最终使用的是从npm安装的模块,则可能需要设置此配置值true以避免出现解析问题。此选项仅适用于以不同方式处理".js"后缀,它不执行任何其他Node解析和评估匹配,例如.json文件处理(JSON处理仍然需要"json!"加载程序插件)。在2.1.10及更高版本中可用。

waitSeconds: 放弃放弃加载脚本之前要等待的秒数。将其设置为0将禁用超时。默认值为7秒。

context: 赋予加载上下文的名称。只要每个顶级require调用指定一个唯一的上下文字符串,这都允许require.js在页面中加载模块的多个版本。要正确使用它,请参阅"Multiversion支持"部分。

deps: 要加载的依赖项数组。当在require.js加载之前将require定义为配置对象时,并且您要指定要在require()定义后立即加载的依赖项时,此选项很有用。使用deps就像进行require([])调用一样,但是在加载程序处理完配置后立即使用。它不会阻止 其他任何require()调用启动对模块的请求,它只是指定某些模块作为config块的一部分异步加载的一种方法。

callback: 加载 deps后执行的函数。在将require.js加载之前,将require定义为配置对象,并且您希望在加载配置的 deps数组后指定要使用的函数时,此选项很有用。

enforceDefine: 设置为true时,如果加载的脚本未调用define()或具有可检查的填充程序导出字符串值,则将引发错误。有关更多信息,请参见在IE中捕获负载故障。

xhtml: 如果设置为true,则document.createElementNS()将用于创建脚本元素。

urlArgs: 附加到RequireJS用于获取资源的URL的附加查询字符串参数。当浏览器或服务器配置不正确时,最有用的方法是缓存崩溃。urlArgs的高速缓存半身设置示例:

urlArgs: "bust="+  (new Date()).getTime()

从RequireJS 2.2.0开始,urlArgs可以是一个函数。如果是函数,它将接收模块ID和URL作为参数,并且应返回将添加到URL末尾的字符串。如果没有参数,则返回一个空字符串。请务必注意添加"?" 或"&"(取决于URL的现有状态)。例:

requirejs.config({
    urlArgs: function(id, url) {
        var args = 'v=1';
        if (url.indexOf('view.html') !== -1) {
            args = 'v=2'
        }

        return (url.indexOf('?') === -1 ? '?' : '&') + args;
    }
});

在开发过程中,使用它可能会很有用,但是请确保在部署代码之前将其删除。

scriptType: 指定type =""属性的值,该属性用于RequireJS插入文档中的脚本标签。默认值为"文本/ javascript"。要使用Firefox的JavaScript 1.8函数,请使用"text/javascript; version = 1.8"。

skipDataMain: 在RequireJS 2.1.9中引入:如果设置为true,则跳过对数据主属性的扫描以开始加载模块。如果RequireJS嵌入在可以与页面上的其他RequireJS库进行交互的实用程序库中,并且嵌入的版本不应进行数据主加载,则很有用。

高级用法 § 4

从包中加载模块§ 4.1

RequireJS支持加载CommonJS Packages目录结构中的模块,但是需要指定一些其他配置才能使其正常工作。具体来说,它支持以下CommonJS Packages函数:

  • 包可以与模块名称/前缀关联。
  • 程序包配置可以为特定程序包指定以下属性:
    • name: 包的名称(用于模块名称/前缀映射)
    • location: 磁盘上的位置。位置相对于baseUrl配置值,除非它们包含协议或以反斜杠(/)开头。
    • main: 某人对"packageName"的要求时应使用的包装内部模块的名称。默认值为"main",因此仅当它不同于默认值时才指定它。该值相对于包文件夹。

重要笔记

  • 尽管软件包可以具有CommonJS目录布局,但模块本身应采用RequireJS可以理解的模块格式。规则的例外:如果使用r.jsNode适配器,则模块可以采用传统的CommonJS模块格式。如果需要将传统的CommonJS模块转换为RequireJS使用的异步模块格式,则可以使用CommonJS转换工具。
  • 一次只能在项目上下文中使用软件包的一个版本。您可以使用RequireJS 多版本支持来加载两个不同的模块上下文,但是如果您想在一个上下文中使用程序包A和B,并且它们依赖于程序包C的不同版本,那么这将是一个问题。将来可能会改变。

如果您使用《入门指南》中指定的类似项目布局,则Web项目的开始将看起来像这样(基于Node/Rhino的项目是类似的,只需使用scripts目录的内容作为顶级项目目录):

  • project-directory/
    • project.html
    • scripts/
      • require.js

这是带有两个包cart和store的示例目录布局的外观:

  • project-directory/
    • project.html
    • scripts/
      • cart/
        • main.js
      • store/
        • main.js
        • util.js
      • main.js
      • require.js

project.html 将具有如下脚本标记:

<script data-main="scripts/main"src="scripts/require.js"></script>

这将指示require.js加载脚本/main.js。main.js使用"packages"配置来设置相对于require.js的软件包,在这种情况下,它们是源软件包"cart"和"store":

//main.js contents
//Pass a config object to require
require.config({
    "packages": ["cart", "store"]
});

require(["cart", "store", "store/util"],
function (cart,   store,   util) {
    //use the modules as usual.
});

"cart"的需求意味着它将从scripts/cart/main.js加载,因为"main"是RequireJS支持的默认主模块设置。将从scripts/store/util.js加载"store/util"的需求。

如果"store"包未遵循"main.js"约定,则看起来更像这样:

  • project-directory/
    • project.html
    • scripts/
      • cart/
        • main.js
      • store/
        • store.js
        • util.js
      • main.js
      • package.json
      • require.js

然后,RequireJS配置将如下所示:

require.config({
    packages: [
        "cart",
        {
            name: "store",
            main: "store"
        }
    ]
});

为避免冗长,强烈建议始终使用在其结构中使用"主要"约定的软件包。

多版本支持§ 4.2

如配置选项中所述,可以使用不同的"上下文"配置选项将模块的多个版本加载到页面中。require.config()返回一个使用上下文配置的require函数。这是加载两个不同版本的alpha和beta模块的示例(此示例摘自一个测试文件):

<script src="../require.js"></script>
<script>
var reqOne = require.config({
  context: "version1",
  baseUrl: "version1"
});

reqOne(["require", "alpha", "beta",],
function(require,   alpha,   beta) {
  log("alpha version is: "+ alpha.version); //prints 1
  log("beta version is: "+ beta.version); //prints 1

  setTimeout(function() {
    require(["omega"],
      function(omega) {
        log("version1 omega loaded with version: "+
             omega.version); //prints 1
      }
    );
  }, 100);
});

var reqTwo = require.config({
      context: "version2",
      baseUrl: "version2"
    });

reqTwo(["require", "alpha", "beta"],
function(require,   alpha,   beta) {
  log("alpha version is: "+ alpha.version); //prints 2
  log("beta version is: "+ beta.version); //prints 2

  setTimeout(function() {
    require(["omega"],
      function(omega) {
        log("version2 omega loaded with version: "+
            omega.version); //prints 2
      }
    );
  }, 100);
});
</script>

注意,"require"被指定为模块的依赖项。这允许传递给函数回调的require()函数使用正确的上下文正确加载模块以支持多版本。如果未将"require"指定为依赖项,则可能会出现错误。

页面加载后加载代码§ 4.3

上面"Multiversion支持"部分中的示例显示了以后如何通过嵌套的require()调用来加载代码。

Web Worker支持§ 4.4

从0.12版开始,RequireJS可以在Web Worker中运行。只需在网络工作者中使用importScripts()来加载require.js(或包含require()定义的JS文件),然后调用require。

您可能需要设置baseUrl 配置选项,以确保require()可以找到要加载的脚本。

通过查看单元测试中使用的文件之一,可以看到其用法示例。

Rhino 支持§ 4.5

RequireJS可以通过r.js适配器在Rhino中使用。有关更多信息,请参见r.js自述文件。

Nashorn 支持§ 4.6

从RequireJS 2.1.16开始,RequireJS可以通过r.js适配器在Java 8+的JavaScript引擎Nashorn中使用。有关更多信息,请参见r.js自述文件。

处理错误§ 4.7

错误的一般类别是脚本(未找到)的404,网络超时或加载的脚本中的错误。RequireJS有一些用于处理它们的工具:特定于需求的errback,"paths"数组配置以及全局的requirejs.onError。

传递给errbacks的错误对象和全局requirejs.onError函数通常将包含两个自定义属性:

  • requireType: 具有一般分类的字符串值,例如"timeout","nodefine","scripterror"。
  • requireModules: 超时的模块名称/ URL的数组。

如果您在requireModules中遇到错误,则可能意味着未定义依赖于requireModules数组中模块的其他模块。

在追赶IE加载失败 § 4.6.1

Internet Explorer存在一系列问题,使得难以检测到错误/路径后备的加载失败:

  • script.onerror在IE 6-8中不起作用。无法知道加载脚本是否会生成404,更糟糕的是,即使在404情况下,它也会以完整状态触发onreadystatechange。
  • script.onerror确实可以在IE 9+中运行,但存在一个错误,即在执行脚本后不立即触发script.onload事件处理程序,因此它不支持允许匿名AMD模块的标准方法。因此仍使用script.onreadystatechange。但是,在script.onerror函数启动之前,onreadystatechange会以完整状态启动。

因此,使用IE很难同时允许匿名的AMD模块和可靠的检测错误,匿名的AMD模块是AMD模块的核心优势。

但是,如果您知道在一个项目中使用define()声明其所有模块,或者它使用shim config为不使用define()的任何内容指定字符串导出,那么如果您设置了defineDefine配置值确实,加载器可以通过检查define()调用或填充程序的导出全局值的存在来确认脚本是否已加载。

因此,如果要支持Internet Explorer,捕获负载错误并通过直接define()调用或shim config获得模块化代码,请始终将forcedDefine设置为true。有关示例,请参见下一部分。

注意: 如果您确实设置了forceDefine:true,并且使用data-main =""来加载主JS模块,则该主JS模块必须调用define()而不是require()来加载所需的代码。JS主模块仍然可以调用require/requirejs来设置配置值,但是对于加载模块,它应该使用define()。

如果然后还使用杏仁来构建没有require.js的代码,请确保使用insertRequire构建设置为主模块插入一个require调用-达到与最初的require()调用相同的目的,即调用data-main做。

require([]) 需求 § 4.6.2

当与requirejs.undef()一起使用时,Errbacks 将允许您检测模块是否无法加载,取消定义该模块,将配置重置到另一个位置,然后重试。

一个常见的用例是使用CDN托管的库版本,但是如果失败,请切换到本地加载文件:

requirejs.config({
    enforceDefine: true,
    paths: {
        jquery: 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min'
    }
});

//Later
require(['jquery'], function ($) {
    //Do something with $ here
}, function (err) {
    //The errback, error callback
    //The error has a list of modules that failed
    var failedId = err.requireModules && err.requireModules[0];
    if (failedId === 'jquery') {
        //undef is function only on the global requirejs object.
        //Use it to clear internal knowledge of jQuery. Any modules
        //that were dependent on jQuery and in the middle of loading
        //will not be loaded yet, they will wait until a valid jQuery
        //does load.
        requirejs.undef(failedId);

        //Set the path to jQuery to local path
        requirejs.config({
            paths: {
                jquery: 'local/jquery'
            }
        });

        //Try again. Note that the above require callback
        //with the "Do something with $ here"comment will
        //be called if this new attempt to load jQuery succeeds.
        require(['jquery'], function () {});
    } else {
        //Some other error. Maybe show message to the user.
    }
});

使用`requirejs.undef()`,如果您稍后设置其他配置并尝试加载相同的模块,则加载器仍会记住哪些模块需要该依赖关系,并在新配置的模块加载时完成加载。

注意: errbacks仅适用于回调样式的require调用,而不适用define()调用。define()仅用于声明模块。

路径配置回退 § 4.6.3

上面的用于检测负载故障,对模块进行undef(),修改路径和重新加载的模式是一个足够普遍的要求,它也有一个简写形式。路径配置允许数组值:

requirejs.config({
    //To get timely, correct error triggers in IE, force a define/shim exports check.
    enforceDefine: true,
    paths: {
        jquery: [
            'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min',
            //If the CDN location fails, load from this location
            'lib/jquery'
        ]
    }
});

//Later
require(['jquery'], function ($) {
});

上面的代码将尝试CDN位置,但是如果失败,请退回到本地lib/jquery.js位置。

注意:路径回退仅适用于确切的模块ID匹配。这与可应用于模块ID前缀段的任何部分的普通路径配置不同。后备的目标更多是针对异常错误的恢复,而不是通用的路径搜索路径解决方案,因为它们在浏览器中效率低下。

Global requirejs.onError function § 4.6.4

要检测本地错误未捕获的错误,可以覆盖requirejs.onError():

requirejs.onError = function (err) {
    console.log(err.requireType);
    if (err.requireType === 'timeout') {
        console.log('modules: ' + err.requireModules);
    }

    throw err;
};

加载程序插件 § 5

RequireJS支持加载程序插件。这是一种支持依赖关系的方法,该依赖关系不是普通的JS文件,但是对于脚本在执行工作之前已加载仍然很重要。RequireJS Wiki有一个插件列表。本节讨论与RequireJS一起维护的一些特定插件:

指定文本文件依赖性§ 5.1

使用常规HTML标签构建HTML很好,而不是在脚本中构建DOM结构。但是,没有很好的方法将HTML嵌入JavaScript文件中。最好的办法是使用HTML字符串,但这可能很难管理,尤其是对于多行HTML。

RequireJS有一个插件text.js,可以帮助解决此问题。如果文本将自动加载!前缀用于依赖项。有关更多信息,请参见 text.js自述文件。

页面加载事件支持/ DOM就绪§ 5.2

使用RequireJS足够快地加载脚本以使其在DOM准备好之前完成时,这是可能的。任何尝试与DOM交互的工作都应等待DOM准备就绪。对于现代浏览器,这是通过等待DOMContentLoaded事件来完成的。

但是,并非所有使用中的浏览器都支持DOMContentLoaded。domReady模块实现了跨浏览器方法来确定DOM准备就绪的时间。下载模块,并在您的项目中使用它,如下所示:

require(['domReady'], function (domReady) {
  domReady(function () {
    //This function is called once the DOM is ready.
    //It will be safe to query the DOM and manipulate
    //DOM nodes in this function.
  });
});

由于DOM ready是常见的应用程序需求,因此理想情况下可以避免上面API中的嵌套函数。domReady模块还实现了Loader Plugin API,因此您可以使用loader插件语法(注意domReady依赖项中的!)来强制require()回调函数在执行之前等待DOM准备就绪。

domReady
用作加载程序插件时,将返回当前文档:

require(['domReady!'], function (doc) {
    //This function is called once the DOM is ready,
    //notice the value for 'domReady!' is the current
    //document.
});

注意: 如果文档加载时间较长(可能是非常大的文档,或者HTML脚本标签加载了大型JS文件,这些文件会阻止DOM完成直到完成),那么使用domReady作为加载程序插件可能会导致RequireJS"超时"错误。如果这是一个问题,请增加waitSeconds配置,或者仅使用domReady作为模块并在require()回调内调用domReady()。

定义I18N捆绑包§ 5.3

一旦您的Web应用达到一定的大小和流行度,在界面中本地化字符串并提供其他特定于语言环境的信息就变得更加有用。但是,制定一个可以很好地扩展以支持多个语言环境的方案可能很麻烦。

RequireJS允许您设置具有本地化信息的基本模块,而不必强制您预先提供所有特定于语言环境的信息。它可以随时间添加,并且只能在特定于语言环境的文件中定义在语言环境之间更改的字符串/值。

i18n.js插件提供了对i18n包的支持。当模块或依赖项指定i18n时,它将自动加载!前缀(下面有更多信息)。下载插件,并将其与应用程序的主JS文件放在同一目录中。

要定义包,请将其放在名为"nls"的目录中-i18n!插件假定模块名称中带有"nls",表示一个i18n软件包。名称中的"nls"标记告诉i18n插件在哪里可以看到语言环境目录(它们应该是nls目录的直接子目录)。如果要在"我的"模块集中提供一组颜色名称,请按以下方式创建目录结构:

  • my/nls/colors.js

该文件的内容应如下所示:

//my/nls/colors.js contents:
define({
    "root": {
        "red": "red",
        "blue": "blue",
        "green": "green"
    }
});

属性为"root"的对象文字定义了此模块。您要做的就是为以后的本地化工作奠定基础。

然后,您可以在my/lamps.js文件的另一个模块中使用上述模块:

//Contents of my/lamps.js
define(["i18n!my/nls/colors"], function(colors) {
    return {
        testMessage: "The name for red in this locale is: "+ colors.red
    }
});

my/lamps模块具有一个名为"testMessage"的属性,该属性使用colors.red来显示红色的本地化值。

稍后,当您想向文件添加特定的翻译时,例如使用fr-fr语言环境,请将my/nls/colors更改为如下所示:

//Contents of my/nls/colors.js
define({
    "root": {
        "red": "red",
        "blue": "blue",
        "green": "green"
    },
    "fr-fr": true
});

然后在my/nls/fr-fr/colors.js定义一个文件,该文件包含以下内容:

//Contents of my/nls/fr-fr/colors.js
define({
    "red": "rouge",
    "blue": "bleu",
    "green": "vert"
});

RequireJS将使用浏览器的navigator.languages,navigator.language或navigator.userLanguage属性来确定要用于my/nls/colors的语言环境值,因此您的应用程序不必更改。如果您希望设置语言环境,则可以使用模块配置将语言环境传递给插件:

requirejs.config({
    config: {
        //Set the config for the i18n
        //module ID
        i18n: {
            locale: 'fr-fr'
        }
    }
});

注意 RequireJS将始终使用小写版本的语言环境,以避免出现大小写问题,因此,i18n软件包的磁盘上的所有目录和文件都应使用小写语言环境。

RequireJS也足够聪明,可以选择正确的语言环境包,该语言包与my/nls/colors提供的语言包最匹配。例如,如果区域设置为"en-us",则将使用"root"捆绑包。如果区域设置为"fr-fr-paris",则将使用"fr-fr"捆绑包。

RequireJS还将捆绑包合并在一起,因此,例如,如果法式捆绑包是这样定义的(将红色值省略):

//Contents of my/nls/fr-fr/colors.js
define({
    "blue": "bleu",
    "green": "vert"
});

然后将使用"root"中红色的值。这适用于所有语言环境。如果定义了下面列出的所有捆绑包,那么RequireJS将按照以下优先级顺序使用值(顶部的优先级最高):

  • my/nls/fr-fr-paris/colors.js
  • my/nls/fr-fr/colors.js
  • my/nls/fr/colors.js
  • my/nls/colors.js

如果您不希望在顶级模块中包含根包,则可以像普通语言环境包一样定义它。在这种情况下,顶层模块如下所示:

//my/nls/colors.js contents:
define({
    "root": true,
    "fr-fr": true,
    "fr-fr-paris": true
});

根束看起来像:

//Contents of my/nls/root/colors.js
define({
    "red": "red",
    "blue": "blue",
    "green": "green"
});