2015-11-03 32 views
0

我已經加載了帶有bower的把手,因此它駐留在供應商目錄中。看來我已經配置了一切,我可以在檢查器中看到handlebars.js文件已加載,它沒有提供404 ..但據我所知,以下內容應該將其添加到全局名稱空間(窗口)。正如你可以看到我有我的模塊「裝」,並且工作正確的,但是這個模塊裏面取決於車把 - 與墊片配置ReferenceError: Handlebars is not defined無法加載需要配置路徑和墊片的把手

requirejs.config({ 
    baseUrl: "/scripts", 
    urlArgs: "bust=" + (new Date()).getTime(), 
    paths: { 
     "jquery": "vendor/jquery/dist/jquery", 
     "loaded": "vendor/loaded/dist/loaded", 
     "handlebars": "vendor/handlebars/handlebars" 
    }, 
    shim: { 
     "loaded": { 
      deps: ["jquery", "handlebars"], 
      exports: "loaded" 
     }, 
     "handlebars": { 
      exports: "Handlebars" 
     } 
    } 
}); 

requirejs(["app"]); 

這裏是加載模塊(非AMD的一個片段,負載):

if(typeof loaded === "undefined") loaded = {}; 

loaded.dispatch = (function() { 

    // ... 

    return { 
     render: function() { 

      // ... 

      // gets this far, but error as the library is missing 
      var template = Handlebars.compile(_template); 

      // ... 
     } 
    } 
})(); 

如前所述,我可以在把手不是全局命名空間(窗口)的屬性檢查看看。從我讀過的其他文章中,我看不到我配置錯誤。另外,因爲加載是需要的,我不知道這是什麼問題與車把。

UPDATE

新main.js作爲車把版本不需要它,它似乎:

requirejs.config({ 
    baseUrl: "/scripts", 
    urlArgs: "bust=" + (new Date()).getTime(), 
    paths: { 
     "jquery": "vendor/jquery/dist/jquery", 
     "loaded": "vendor/loaded/dist/loaded", 
     "handlebars": "vendor/handlebars/handlebars" 
    }, 
    shim: { 
     "loaded": { 
      deps: ["jquery", "handlebars"], 
      exports: "loaded" 
     } 
    } 
}); 

requirejs(["app"]); 

回答

1

你不需要(也不應該)墊片handlebars作爲庫集成了UMD wrapper因此,是與AMD pattern(其中requirejs是一個實現)兼容:

if(typeof exports === 'object' && typeof module === 'object') 
    module.exports = factory(); 
else if(typeof define === 'function' && define.amd) 
    define([], factory); 
else if(typeof exports === 'object') 
    exports["Handlebars"] = factory(); 
else 
    root["Handlebars"] = factory(); 

實際上,因爲庫加載時會找到define函數,它不會將Handlebars附加到根對象(即window)。因此,顯然,你的墊片找不到它。

現在你的問題是你想使用一個非AMD模塊的AMD加載模塊Handlebars。不幸的是,這不是官方支持:

只能使用其他的「墊片」模塊作爲依賴於墊高的腳本,或者說有沒有依賴性,並調用定義()後,他們也創造了一個全球性的(如jQuery或lodash AMD庫)。否則,如果您使用AMD模塊作爲shim配置模塊的依賴項,則在構建之後,只有在構建中的shimmed代碼執行後才能評估AMD模塊,並且會發生錯誤。最終的解決方案是升級所有shimmed代碼以具有可選的AMD define()調用。

沒有很好的解決方案。這裏有一些想法:

(1)我仍設法使其工作與創建globalHandlebars模塊:

define(["handlebars"], function(Handlebars){ 
    window.Handlebars = Handlebars; 
}); 

但是,這是非常哈克,而不是正式支持。事實上,看起來你不能保證dep的define將在非AMD腳本加載之前被調用。從來沒有發生在我的筆記本雖然...

(2)另一種方法,使其工作原理是包括handlebarsrequirejs(這樣define尚未確定)之前在HTML文件中的腳本。 還是很哈克,如果你也使用車把與requirejs,它將被載入兩次......

(3)顯然,最好的是,如果你能在一個define呼叫換你loaded劇本,但我想它可能不可能。

(4)如果使用優化器,也有一個wrapShim選項,雖然它不取決於你的勻碼的內容總是工作。

我沒有任何其他的解決方案,但也許requirejs人有一個。我很驚訝沒有人在你面前發現這個問題。

您也可以考慮切換到browserifywebpack而不是requirejs(webpack本身支持AMD模塊,並且有一個用於browserify的AMD loader)。 此外,它們都可以讓您預先構建您的模板(使用this loader用於webpack,或者這個transform用於browserify),並避免包含整個handlebars庫,這總是一個很好的做法。

+0

感謝您的回覆。我有handlebars v4.0.4,我可以在文件中看到它確實擁有你發佈的if if else else條件。我匹配你提供的配置(刪除車把墊片),但仍然有同樣的錯誤。我會看到main.js(配置文件)沒有被緩存。所以,如果handlebars沒有被添加到窗口對象,你知道在DOM中我應該找到它嗎?我嘗試在DOM檢查器中搜索,但沒有提供任何結果。或者還有什麼我可以看看?我會用新的main.js更新我的OP。再次感謝。 – Martyn

+0

它可能不會被附加到全局上下文中(變量永遠不會附加到dom上,dom是針對節點的,例如div,而不是變量)。使用requirejs,您可以檢索一個模塊作爲define函數的參數:'define([「handlebars」],function(Handlebars){/ * stuff * /}'。我目前沒有電腦,但我會更近一些 –

+0

我編輯了我的答案不幸的是,這並不完美,但我認爲你可以做得更好 –