常见错误

本页面列出了 RequireJS 生成的错误。如果以下信息无法解决问题,您可以在 RequireJS 列表 中提问或 提交问题。无论哪种情况,最好提供一个示例或对问题的详细说明,最好是包含重现步骤。

不匹配的匿名 define() 模块 ...§ 1

如果您在 HTML 中手动编写 script 标签以加载带有匿名 define() 调用的脚本,则可能会发生此错误。

如果您在 HTML 中手动编写 script 标签以加载包含几个命名模块的脚本,但随后尝试加载一个匿名模块,该模块的名称最终与手动编写的 script 标签加载的脚本中的一个命名模块的名称相同。

如果您使用加载器插件或匿名模块(使用没有字符串 ID 的 define() 调用的模块),但没有使用 RequireJS 优化器将文件合并在一起,则可能会发生此错误。优化器知道如何正确命名匿名模块,以便可以将它们与优化文件中的其他模块合并。

如果您出于 jshint/jslint 的目的在文件的顶部使用 var define;,这将导致优化器出现问题,因为它会避免解析声明 define 变量的文件,因为这可能表示该脚本是由使用本地 define 的某些脚本连接而成的。

为避免此错误

  • 请确保通过 RequireJS API 加载所有调用 define() 的脚本。不要在 HTML 中手动编写 script 标签以加载包含 define() 调用的脚本。
  • 如果您手动编写 HTML script 标签,请确保它只包含命名模块,并且不会加载与该文件中某个模块同名的匿名模块。
  • 如果问题是使用了加载器插件或匿名模块,但没有使用 RequireJS 优化器进行文件捆绑,请使用 RequireJS 优化器。
  • 如果问题是 var define lint 方法,请改用 /*global define */(“global”之前没有空格)注释样式。

模块加载超时: ...§ 2

可能的原因和解决方法

  • 列出的某个模块中存在脚本错误。如果浏览器的错误控制台中没有脚本错误,并且您使用的是 Firebug,请尝试在其他浏览器(如 Chrome 或 Safari)中加载页面。有时脚本错误不会显示在 Firebug 中。
  • 模块的路径配置不正确。检查浏览器开发者工具中的“网络”选项卡,查看是否存在与模块名称对应的 URL 的 404 错误。确保脚本文件位于正确的位置。在某些情况下,您可能需要使用 paths 配置 来修复脚本的 URL 解析。
  • paths 配置用于将两个模块 ID 设置为同一个文件,并且该文件只有一个匿名模块。如果模块 ID“something”和“lib/something”都被配置为指向同一个“scripts/libs/something.js”文件,并且 something.js 中只有一个匿名模块,则可能会发生这种超时错误。解决方法是确保所有模块 ID 引用都使用相同的 ID(为所有引用选择“something”或“lib/something”),或者使用 map 配置

模块求值错误 ...§ 3

为错误消息中给出的模块调用 define() 函数时发生错误。这是 define 函数内部的代码逻辑错误。该错误可能发生在 require 回调内部。

在 Firefox 和 WebKit 浏览器中,错误信息中会指示行号和文件名。它可以用来定位问题的根源。可以通过使用调试器在包含错误的文件中放置断点来更好地隔离错误。

模块名称 ... 尚未加载,上下文为: ...§ 4

当存在 require('name') 调用但“name”模块尚未加载时,会发生这种情况。

如果错误消息包含“使用 require([])”,则表示这是一个顶级 require 调用(不是 define() 调用内部的 require 调用),它应该使用异步回调版本的 require 来加载代码

//If this code is not in a define call,
//DO NOT use require('foo'), but use the async
//callback version:
require(['foo'], function (foo) {
    //foo is now loaded.
});

如果您使用的是简化的 define 包装器,请确保将“require”作为定义函数的第一个参数

define(function (require) {
    var namedModule = require('name');
});

如果您在依赖项数组中列出依赖项,请确保“require”和“name”都在依赖项数组中

define(['require', 'name'], function (require) {
    var namedModule = require('name');
});

特别是,以下代码将无法正常工作

//THIS WILL FAIL
define(['require'], function (require) {
    var namedModule = require('name');
});

这会失败,因为 requirejs 需要确保在调用上面的工厂函数之前加载并执行所有依赖项。如果将依赖项数组传递给 define(),则 requirejs 假定所有依赖项都列在该数组中,并且不会扫描工厂函数以查找其他依赖项。因此,要么不要传入依赖项数组,要么如果使用依赖项数组,请在其中列出所有依赖项。

如果是 require() 回调的一部分,则所有依赖项都需要列在数组中

require(['require', 'name'], function (require) {
    var namedModule = require('name');
});

请确保“require('name')”只出现在 define() 定义函数或 require() 回调函数内部,而不会单独出现在全局空间中。

在 RequreJS 1.0.x 版本中,使用简化的 CommonJS 包装(没有依赖项数组)时,WebKit 浏览器中 require 和括号之间存在空格会导致 错误

define(function (require) {
    //Notice the space between require and the arguments.
    var namedModule = require ('name');
});

解决方法是删除空格。此问题已在 2.0 代码中修复,如果发布 1.0.9 版本,则可能会向后移植到 1.0.x 系列。

无效的 require 调用§ 5

当出现如下调用时会发生这种情况

require('dependency', function (dependency) {});

异步加载依赖项应该使用数组来列出依赖项

require(['dependency'], function (dependency) {});

没有针对 ... 的 define 调用§ 6

enforceDefine 设置为 true 时,会发生这种情况,并且加载的脚本要么

  • 没有调用 define() 来声明模块。
  • 要么是 shim 配置 的一部分,该配置指定了一个字符串 exports 属性,可以检查该属性以验证加载,并且该检查失败。
  • 要么是 shim 配置 的一部分,该配置没有为 exports 配置选项设置字符串值。

或者,如果错误只出现在 IE 中,而没有出现在其他浏览器中(这可能会生成 脚本错误,则该脚本可能

  • 抛出了 JavaScript 语法/求值错误。
  • 或者 IE 中出现了 404 错误,导致脚本加载失败。

这些 IE 行为会导致 IE 在检测脚本错误方面的怪癖

要解决此问题

  • 如果模块调用了 define(),请在脚本调试器中进行调试,确保到达了 define 调用。
  • 如果是 shim 配置的一部分,请确保 shim 配置的 exports 检查正确。
  • 如果是在 IE 中,请使用脚本调试器检查 HTTP 404 错误或 JavaScript 语法错误。

脚本错误§ 7

当浏览器中触发 script.onerror 函数时,会发生这种情况。这通常意味着存在 JavaScript 语法错误或运行脚本时的其他执行问题。要解决此问题,请在脚本调试器中检查生成错误的脚本。

此错误可能不会出现在 IE 中,而只出现在其他浏览器中,而在 IE 中,当您看到“脚本错误”时,您可能会看到 没有针对 ... 的 define 调用 错误。这是由于 IE 在检测脚本错误方面的怪癖

没有匹配的交互式脚本 ...§ 8

此错误只出现在某些 IE 浏览器中。最有可能的原因是加载了一个调用 define() 的脚本,但该脚本是在普通 script 标签中加载的,或者通过其他调用加载的,例如对 JavaScript 字符串的 eval() 调用。

为避免此错误,请确保通过 RequireJS API 加载所有调用 define 的脚本。

不支持的路径: ...§ 9

当优化器遇到模块或脚本的路径是网络路径时,会发生此错误。优化器只允许使用本地资源进行构建。要解决此问题

请确保将网络依赖项引用为模块名称,而不是完整的 URL,以便在构建过程中可以将其映射到不同的位置

//DO NOT DO THIS
require(['http://some.domain.dom/path/to/dependency.js'],
function (dependency) {});

//Rather, do this:
require.config({
    paths: {
        'dependency': 'http://some.domain.dom/path/to/dependency'
    }
});

require(['dependency'], function (dependency) {});

如果要将此依赖项包含在构建/优化后的文件中,请下载 JS 文件,并在优化器的构建配置文件中添加一个指向该本地文件的 paths 配置。

如果要从包含的文件中排除该文件,并且只需要为构建映射“dependency”(否则将无法构建),请使用特殊的“empty:”paths 配置

//Inside the build profile
{
    paths: {
        'dependency': 'empty:'
    }
}

无法同时使用 preserveLicenseComments 和 generateSourceMaps§ 10

在 r.js 优化器中,preserveLicenseComments 作为 JS 文件的前置和后置处理步骤工作。它会查找各种许可证注释,将它们从 JS 源代码中提取出来,然后将修改后的源代码传递给压缩器。压缩器完成后,r.js 优化器会将注释添加到文件的顶部。

但是,为了让压缩器准确地构建源映射,压缩后的源代码不能以任何方式修改,因此 preserveLicenseCommentsgenerateSourceMaps 不兼容。generateSourceMaps 是在优化器的 2.1.2 版本中引入的。

优化器的默认设置是 preserveLicenseComments 为 true。因此,如果使用 generateSourceMaps,则需要显式地将 preserveLicenseComments 设置为 false。如果要保留某些许可证注释,可以手动修改 JS 源代码中的许可证注释,以使用 JSDoc 样式的 @license 注释。有关更多信息,请参阅“为 Closure Compiler 添加 JavaScript 注释”。UglifyJS2 也使用相同的格式。

importScripts 对 ... 失败§ 11

当 RequireJS 在 Web Worker 中使用时,会使用 importScripts 来加载模块。如果该调用由于某种原因失败,则会生成此错误。