好吧,在上面 Thomas Broyer的评论之后,我能够走得更远,找到(目前)明确的答案:“这不可能完全干净。” (没有编写自定义链接器)......但是我仍在进一步追求一种不太干净的方式。
具体来说,有三个官方 GWT 链接器,其中两个生成的代码本身想要通过 http 请求主代码片段。第三个,“sso”产生一个文件,只适用于一个排列(这在我的情况下是可以接受的)。但是,生成的代码会执行 document.write(),它会在动态调用时删除主文档。
它这样做是为了在它期望来自的标签之后创建一个标记标签,以便它可以从中提取自己的 URL 和脚本基础 URI。在我的情况下,主机页面位于 GWT 模块文件夹的父文件夹中,通常包含以下内容:
<script ... src="moduleName/moduleName.nocache.js"></script>
...并且 moduleName.nocache.js 想要找出所有其他与模块相关的请求(例如其他代码片段等)的“ host-base /moduleName”基本 URI。
在任何情况下,如果它无法找到它使用 document.write() 写入的标记标记,它将尝试查找标记并使用它。麻烦的是,该标签既不正常存在,也不正确——在我们的例子中,它会引用所需内容的父级。但是,这个标签也可以在我们实际注入 moduleName.nocache.js 之前动态插入......然后在注入后更正回来。
就像是:
// Obtain the main fragment script code using alternate means:
var scriptCode = ...;
// Create the script tag for the main code fragment
var codeElement = document.createElement("script");
codeElement.type = "text/javascript";
// Prepare the environment to run it, to hack around
// its document.write and base URI needs.
// First remember the normal/original document.write method:
var originalWriteMethod = document.write;
// ... and replace it with a dummy one (we'll put this back later):
document.write = function() {}
// ... and also remember the document base
var originalBase = document.baseURI;
// Figure out the script base based on the originalBase:
var scriptBase = originalBase + "moduleName/";
// Failing document.write case, the main code fragment will look for
// the last <base> tag to get the script base. Add that element and
// set it to reference the scriptBase (we'll have to undo this later):
var baseElement = document.createElement("base");
baseElement.href = scriptBase;
document.head.appendChild(baseElement);
// Different browsers work differently... try to cover two cases:
try {
codeElement.appendChild.document.createTextNode(scriptCode);
document.head.appendChild(codeElement);
} catch (e) {
codeElement.text = scriptCode;
document.head.appendChild(codeElement);
} finally {
// Whatever case occurred above, we must return the document.write()
// to normal implementation and undo our temporary document base
// change:
document.write = originalWriteMethod;
baseElement.href = originalBase;
}
这使代码“加载”、初始化和运行。我还有一些测试要做,但这是我迄今为止最接近的一次。