常見錯誤
- 不匹配的匿名 define() 模組 ...§ 1
- 模組載入逾時:...§ 2
- 評估模組時發生錯誤 ...§ 3
- 模組名稱 ... 尚未載入,內容:...§ 4
- 無效的 require 呼叫§ 5
- 沒有針對 ... 的 define 呼叫§ 6
- 腳本錯誤§ 7
- 沒有與 ... 相符的腳本互動§ 8
- 不支援的路徑:...§ 9
- 無法同時使用 preserveLicenseComments 和 generateSourceMaps§ 10
- importScripts 針對 ... 失敗§ 11
此頁面列出 RequireJS 產生的錯誤。如果下列資訊無法解決問題,您可以在 RequireJS 清單 上發問,或 開啟問題。不論是哪一種方式,最好提供問題範例或詳細說明,並附上重現步驟。
不匹配的匿名 define() 模組 ...§ 1
如果您手動在 HTML 中編寫腳本標籤,以載入具有匿名 define() 呼叫的腳本,可能會發生此錯誤。
如果您手動在 HTML 中編寫腳本標籤,以載入具有幾個命名模組的腳本,但隨後嘗試載入一個匿名模組,而此模組最後具有與手動編寫腳本標籤載入的腳本中其中一個命名模組相同的名稱。
如果您使用載入器外掛程式或匿名模組(呼叫 define() 但沒有字串 ID 的模組),但沒有使用 RequireJS 最佳化器來合併檔案,可能會發生此錯誤。最佳化器知道如何正確命名匿名模組,以便它們可以在最佳化檔案中與其他模組合併。
如果您在檔案頂端使用 var define;
來進行 jshint/jslint,這會導致最佳化器產生問題,因為它會避免解析宣告 define
變數的檔案,因為這可能會指出一個由使用區域定義的某些腳本串接而成的腳本。
若要避免錯誤
- 請務必透過 RequireJS API 載入所有呼叫 define() 的腳本。請勿手動編寫 HTML 中的腳本標籤,以載入其中包含 define() 呼叫的腳本。
- 如果您手動編寫 HTML 腳本標籤,請務必只包含命名模組,而且不會載入與該檔案中某個模組同名的匿名模組。
- 如果問題出在使用載入器外掛程式或匿名模組,但 RequireJS 最佳化器並未用於檔案綑綁,請使用 RequireJS 最佳化器。
- 如果問題出在
var define
程式碼檢查方法,請改用/*global define */
(「global」前面沒有空格)註解樣式。
模組載入逾時:...§ 2
可能原因及解決方法
- 列出的其中一個模組發生腳本錯誤。如果瀏覽器的錯誤主控台中沒有腳本錯誤,而且您正在使用 Firebug,請嘗試在其他瀏覽器(例如 Chrome 或 Safari)中載入頁面。有時腳本錯誤不會顯示在 Firebug 中。
- 模組的路徑設定不正確。請檢查瀏覽器開發人員工具中的「網路」或「網路」標籤,查看是否有一個 404 錯誤,對應到會對應到模組名稱的 URL。請確定腳本檔案位於正確的位置。在某些情況下,您可能需要使用 路徑設定 來修正腳本的 URL 解析。
- 路徑設定用於將兩個模組 ID 設定到同一個檔案,而且該檔案只有一個匿名模組。如果模組 ID「something」和「lib/something」都設定為指向同一個「scripts/libs/something.js」檔案,而且 something.js 中只有一個匿名模組,可能會發生這種逾時錯誤。解決方法是確保所有模組 ID 參考都使用同一個 ID(針對所有參考選擇「something」或「lib/something」),或使用 對應設定。
評估模組時發生錯誤...§ 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');
});
請務必僅在 define() 定義函式或 require() 回呼函式中使用 require('name'),絕不要單獨在全域空間中使用。
在 RequireJS 1.0.x 版本中,在使用簡化的 CommonJS 包裝(沒有相依性陣列)時,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) {});
未針對 ... 定義呼叫§ 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 中看到「腳本錯誤」時,您可能會看到 未針對 ... 定義呼叫 錯誤。這是由於 IE 偵測腳本錯誤的怪異行為。
沒有與 ... 相符的腳本互動§ 8
此錯誤只會出現在某些 IE 瀏覽器中。最可能的原因是載入呼叫 define() 的腳本,但透過一般腳本標籤或其他呼叫載入,例如 eval() JavaScript 字串。
為避免錯誤,請務必透過 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 檔案,並在最佳化器的建置設定檔中,放入指向該本機檔案的路徑設定。
如果您想排除該檔案,而只需要對建置進行「相依性」對應(否則無法建置),請使用特殊的「empty:」路徑設定
//Inside the build profile
{
paths: {
'dependency': 'empty:'
}
}
無法同時使用 preserveLicenseComments 和 generateSourceMaps§ 10
在 r.js 最佳化器中,preserveLicenseComments 會作為 JS 檔案的處理前和處理後步驟。會找到各種授權註解,從 JS 原始碼中取出,然後將修改後的原始碼傳遞給縮小器。縮小器完成後,r.js 最佳化器會將註解新增到檔案頂端。
然而,為了讓縮小器準確建立原始碼對應,縮小的原始碼不能以任何方式修改,因此 preserveLicenseComments 與 generateSourceMaps 不相容。generateSourceMaps 已在最佳化器的 2.1.2 版中推出。
最佳化器的預設值是將 preserveLicenseComments 設為 true。因此,如果使用 generateSourceMaps,請明確將 preserveLicenseComments 設為 false。如果您想保留一些授權註解,您可以手動修改 JS 原始碼中的授權註解,以使用 JSDoc 風格的 @license
註解。請參閱「為 Closure Compiler 加註 JavaScript」以取得更多資訊。相同的格式適用於 UglifyJS2。
importScripts 失敗,原因是...§ 11
當 RequireJS 用於 Web Worker 中時,importScripts 用於載入模組。如果該呼叫因某種原因失敗,就會產生此錯誤。