是什么阻止了需要脚本注入更多脚本标记

时间:2013-03-04 21:46:08

标签: javascript requirejs

我正在尝试在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?建议的填充方法接近但不起作用,因为依赖性未知。

1 个答案:

答案 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;