我正在尝试在AMD / Require网站中使用一些旧脚本。其中一些较旧的脚本通过使用document.write或document.writeln标记来注入其他脚本。以下是正在发生的事情的简化形式:
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 已执行,但文档.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的行为相同。
编辑:我忘了提到在实际场景中,'script2'的路径是动态的,基于一些服务器端逻辑,因为第一个脚本是生成的。
EDIT2:我试图将这个场景归结为其他东西:我不能(轻松)改变这些旧库,因为它们由公司的不同部门控制,并且部分动态基于服务器端逻辑(再次,我不控制)。正如@ddotsenko建议的那样,也许我应该重新解释一下这个问题:如何使用一些依赖于注入脚本标记的遗留脚本,并使它们适合尝试使用正确的东西的网站的其余部分AMD / RequireJS?建议的填充方法接近但不起作用,因为依赖性未知。
答案 0 :(得分:1)
问题是document.write()在页面加载后不起作用(并且RequireJS使用XHR)。
但您可以使用“shim”预定义旧模块的依赖关系 - 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
<强>更新。第二种变体:覆盖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;