常见错误

此页面列出了由 RequireJS 生成的错误。如果以下信息未能解决问题,您可以在RequireJS 邮件列表中提问中的或者提交问题报告无论哪种情况,最好提供一个示例或对问题的详细解释,并希望附带可复现问题的步骤。

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

如果你在 HTML 中手动编码 script 标签来加载一个包含匿名 define() 调用的脚本,就会出现此错误。

如果你在 HTML 中手动编码 script 标签来加载一个包含几个已命名模块的脚本,然后尝试加载一个最终具有与手动编码脚本标签加载的脚本中的某个模块相同名称的匿名模块,就会发生此错误。

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

如果你在文件顶部使用了var define;用于 jshint/jslint 目的的语句,这会导致优化器出现问题,因为它会避免解析那些声明了define变量的文件,因为这可能表示是通过连接一些使用本地 define 的脚本创建的脚本。

避免该错误的方法:

  • 确保通过 RequireJS API 加载所有调用 define() 的脚本。不要在 HTML 中手动编写 script 标签来加载包含 define() 调用的脚本。
  • 如果你手动编写了一个 HTML script 标签,请确保它只包含已命名的模块,并且不会加载一个将与该文件中某个模块同名的匿名模块。
  • 如果问题是由于使用了加载器插件或匿名模块但未使用 RequireJS 优化工具进行文件打包,请改用 RequireJS 优化工具。
  • 如果问题是var definelint 方法,请改用/*global define */(注释中 "global" 前面没有空格)的注释风格。

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

可能的原因和解决方法:

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

模块评估错误...§ 3

当定义函数被调用时发生了错误,错误消息中给出了模块名称。这是 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');
});

如果你在依赖数组中列出依赖项,请确保requirename也在依赖数组中:

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

特别注意,下面的做法将不起作用:

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

这会失败是因为 requirejs 需要确保存在依赖数组的情况下,在调用上面的 factory 函数之前加载并执行所有依赖项。如果给 define() 提供了一个依赖数组,requirejs 会假设所有依赖项都在该数组中,而不会扫描 factory 函数中的其他依赖项。因此,要么不传入依赖数组,要么如果你使用依赖数组,请将其所有的依赖项列出。

如果是在 require() 回调中使用,所有的依赖项都需要列在数组中:

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

请确保require('name')仅在 define() 定义函数或 require() 回调函数内部发生,永远不会单独出现在全局空间中。

在 RequireJS 1.0.x 版本中,存在一个 bug,当使用简化版 CommonJS 包装(没有依赖数组)时,在 require 和括号之间有空格的情况下,WebKit 浏览器会出现问题: with having a space between the require and parens in WebKit browsers when using the simplified CommonJS wrapping (no dependency array):

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) {});

没有为 ... 定义任何 call§ 6

enforceDefine 设置为 true 时会发生此错误,并且加载的脚本存在以下情况之一:

  • 未调用 define() 来声明模块。
  • 或者属于一个shim 配置指定 字符串exports属性用于验证加载,并且该检查失败了。
  • 或者属于一个shim 配置没有为exportsconfig 选项设置字符串值。

或者,如果错误只在 IE 中出现而在其他浏览器中不存在(可能生成一个脚本错误,则脚本可能:

  • 抛出了 JavaScript 语法/执行错误。
  • 或者在 IE 中发生了 404 错误导致脚本加载失败。

这些 IE 表现会导致IE 在检测脚本错误方面的怪癖造成的。.

解决办法:

  • 如果该模块调用了 define(),请通过脚本调试器进行调试以确保 define 调用被执行到了。
  • 如果属于 shim 配置的一部分,请确保 shim 配置中的 exports 检查是正确的。
  • 如果在 IE 中运行,请使用脚本调试器检查是否存在 HTTP 404 错误或 JavaScript 语法错误。

脚本错误§ 7

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

此错误可能不会在 IE 中显示,而只会在其他浏览器中显示。在 IE 中你可能会看到没有为 ... 定义任何 call错误,当你看到 "Script error" 时。这是由于IE 在检测脚本错误方面的怪癖造成的。.

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

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

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

不支持的路径:...§ 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 配置,指向该本地文件。

如果你希望exclude排除该文件不被包含,并且只需要在构建时映射 "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被用来加载模块。如果该调用因某种原因失败,则会生成此错误。