2013-03-04 123 views
1

我想在AMD/Require站點中使用一些較舊的腳本。其中一些舊腳本通過使用document.write或tags.writeln來注入其他腳本。下面是發生了什麼事的簡化形式:阻止Require'ed腳本插入更多腳本標記

script1.js:

console.log('script1'); 
document.writeln("<script src='script2.js'></script>"); 

script2.js

console.log('script2'); 

如果我在經典的方式加載SCRIPT1,DOM同時顯示腳本標記存在並且控制檯輸出顯示兩者都已執行:

<head> 
    <script src="script1.js"></script> 
</head> 
<body></body> 

但如果我通過RequireJS加載script1,DOM僅顯示 script1標記。控制檯輸出顯示SCRIPT1 執行,但document.writeln是顯然忽略,因此SCRIPT2沒有添加到DOM:

<head> 
    <script src="require-jquery.js"></script> 
    <script language="javascript"> 
     require(['script1'], function() { }); 
    </script> 
</head> 
<body></body> 

什麼防止被插入到DOM這種額外的腳本?即使上面的工作正常,我懷疑我還會遇到加載順序的其他問題。但我想了解這個漏洞,因爲我知道RequireJS做什麼不同,以防止加載額外的腳本。

我正在使用RequireJS的2.1.4版本。 Firefox和Chromium的行爲是相同的。

編輯:我忘了提到,在真實場景中,'腳本2'的路徑是基於某些服務器端邏輯的動態生成第一個腳本。我不能(很容易)改變這些舊的庫,因爲它們是由公司的不同部門控制的,並且是基於服務器端的部分動態的邏輯(再次,我不控制)。正如@ddotsenko建議的那樣,也許我應該改寫這個問題:如何採取一些依賴於注入腳本標記的遺留腳本,並使它們適合於試圖通過使用AMD/RequireJS?建議的勻場方法接近但不起作用,因爲依賴關係未知。

+0

看起來你來自.Net世界,其中document.write()是一個習慣性問題。我很驚訝你以前沒有燒過你的手指。 DOM的準備狀態和AMD規範的不同步意味着你最終必須在關閉HTML標籤後嘗試document.write()......問題可以重寫爲「當我用刀刺自己時,爲什麼刀讓我的血液出來?「讓我知道你是否願意在你的編程方法上靈活一點,我會很樂意幫助你。 – ddotsenko 2013-03-05 18:55:19

+0

@ddotsenko :-)查看上面的修改。不,它不是.Net。但是,是的,在我過去的生活中,我太依賴於ASP.NET,並沒有深入瞭解Javascript的實際操作。 – explunit 2013-03-05 20:09:15

回答

1

問題是document.write()在頁面加載後(而RequireJS使用XHR)不起作用。

但是你可以用 「墊片」 預定義的舊模塊的依賴 - http://requirejs.org/docs/api.html#config-shim

config.js

require.config({ 

    deps: ["main"], 

    shim: { 
     script1: { 
      deps: ['script2'], 
      exports: "someScript1Object" 
     } 
    } 
}); 

main.js

require(
    [ "script1" ], 
    function(someScript1Object) { 
     // ... 
    } 
); 

和控制檯輸出爲

script2 
script1 

UPDATE。第二種變體:覆蓋document.write/document。writeln

你可以使用來自ControlJS的技巧 - 覆蓋document.write。試試這個代碼:

require.docwrite = function(text){ 
    var aMatches = text.match(/src='([^']*)/i) || 
     text.match(/src="([^"]*)/i) || 
     text.match(/src=([^ >]*)/i); 
    if (aMatches) { 
     var url = aMatches[1]; 
     require([ url ]); 
    } 
} 

document.write = require.docwrite; 
document.writeln = require.docwrite; 
+0

看我上面的修改。我不知道提前給script2的路徑,所以我不能將它作爲依賴關係來填充。對不起,我忘了這部分。 – explunit 2013-03-05 12:10:17

+0

根據這個答案和上面的其他評論,我認爲沒有可能的解決方案,我的問題。即使陷印document.write並用require()調用替換也會將行爲從同步更改爲異步。但是,我接受這個答案,因爲它可能是我將會得到的最接近的答案。 – explunit 2013-03-06 15:35:37