2013-07-30 56 views
4

內考慮這個:RequireJS - AMD加載模塊既需要流量和在線

<script src='global.js'></script> 
<script src='require.js'></script> 
<script> 
require(['modular_foo'], function() { 
    //do stuff 
}); 

...在側global.js我們有,除其他事項外:

//global.js 
$.getScript("modular_bar.js"); 

其中兩個modular_foo和modular_bar是匿名定義的AMD模塊。使用requireJS,加載類似上面的東西會給你我們最喜歡的錯誤,mismatched anonymous define() modules

對於發生錯誤的原因已經足夠了(如果您想知道,請閱讀該頁面),但問題是,如果您無法擺脫這種情況,該怎麼辦?

我正在建立一個非常逐漸遷移到RJS流程的平臺,因爲現在沒有辦法使用內聯遺留腳本(其中一些具有AMD檢查以觸發define())和我們的requireJS同時入口點。

在某些情況下,我可以簡單地在加載require.js庫的位置放置內聯的AMD兼容腳本,但是當您需要根據DOM內容異步加載其他東西(modular_bar.js)時,這不起作用。我也可以將這些從外部加載到RJS的文件中的所有AMD檢查註釋掉,但這阻止了它們與在模塊化流程中加載的文件不兼容。

有沒有人有過類似的經歷?你如何融合你的流程來克服這些衝突?

回答

0

我沒有在生產環境中使用此解決方案的經驗,但我在這個問題上花了幾天的時間來找出解決問題的最佳方法。

如果正在通過eval傳遞,您可以使用修改後的RequireJS庫,該庫不允許執行匿名define的庫。此外,您可以通過刪除以下代碼段中的name字符串的類型檢查來拒絕任何define調用。

以下片段是對RequireJS的修改,如果被eval調用,它將忽略匿名定義。你可以找到fully modified require.js in this GitHub Gist

該代碼依賴於parse-stack library。如果在RequireJS之前不能包含庫,我建議將它連接到文件的頂部。

Demo

// This is a snippet of RequireJS 
// ... 
define = function (name, deps, callback) { 
    var node, context; 

    // We will allow named modules to be defined by `eval` 
    if (!(typeof name == 'string' || name instanceof String)) 
    { 
     var stack = parseStack(new Error()); 

     // If we find any eval in the stack, do not define the module 
     // This is to avoid the "Mismatched anonymous define() module" error 
     // Caused by executing an anonymous define without requireJS 
     for(var i = 0; i < stack.length; i++) 
     { 
      if(stack[i].name == "eval") 
      { 
       return; 
      } 
     } 
    } 

    // ...