1

我正在尝试在 AMD/Require 站点中使用一些较旧的脚本。其中一些较旧的脚本通过使用 document.write 或 document.writeln 标签来注入其他脚本。以下是正在发生的事情的简化形式:

脚本1.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 上的行为相同。

编辑:我忘了提到,在真实场景中,“script2”的路径是动态的,基于一些服务器端逻辑,因为生成了第一个脚本。

EDIT2:我在尝试简化场景时掩盖了其他内容:我不能(轻松)更改这些旧库,因为它们由公司的不同部门控制并且基于服务器端逻辑部分是动态的(这又是,我不控制)。所以正如@ddotsenko 建议的那样,也许我应该改写这个问题:如何采用一些依赖于注入脚本标签的遗留脚本,并使它们适合试图通过使用 AMD/RequireJS 做正确事情的站点的其余部分? 建议的 shim 方法接近但不起作用,因为依赖关系未知。

4

1 回答 1

1

问题是 document.write() 在页面加载后不起作用(并且 RequireJS 使用 XHR)。

但是您可以使用“shim”来预定义旧模块的依赖关系 - http://requirejs.org/docs/api.html#config-shim

配置.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;
于 2013-03-05T05:55:53.517 回答