を使用してスクリプトを挿入することはできませんが、とinnerHTMLを使用して文字列をスクリプト タグにロードすることは可能です。BlobURL.createObjectURL
文字列をスクリプトとして実行し、promise を通じて返されるスクリプトの「エクスポート」を取得できる例を作成しました。
function loadScript(scriptContent, moduleId) {
// create the script tag
var scriptElement = document.createElement('SCRIPT');
// create a promise which will resolve to the script's 'exports'
// (i.e., the value returned by the script)
var promise = new Promise(function(resolve) {
scriptElement.onload = function() {
var exports = window["__loadScript_exports_" + moduleId];
delete window["__loadScript_exports_" + moduleId];
resolve(exports);
}
});
// wrap the script contents to expose exports through a special property
// the promise will access the exports this way
var wrappedScriptContent =
"(function() { window['__loadScript_exports_" + moduleId + "'] = " +
scriptContent + "})()";
// create a blob from the wrapped script content
var scriptBlob = new Blob([wrappedScriptContent], {type: 'text/javascript'});
// set the id attribute
scriptElement.id = "__loadScript_module_" + moduleId;
// set the src attribute to the blob's object url
// (this is the part that makes it work)
scriptElement.src = URL.createObjectURL(scriptBlob);
// append the script element
document.body.appendChild(scriptElement);
// return the promise, which will resolve to the script's exports
return promise;
}
...
function doTheThing() {
// no evals
loadScript('5 + 5').then(function(exports) {
// should log 10
console.log(exports)
});
}
これを実際の実装から単純化したので、バグがないという保証はありません。しかし、原則は機能します。
スクリプトの実行後に値を取得する必要がない場合は、さらに簡単です。Promiseビットとビットを省略しonloadます。window.__load_script_exports_スクリプトをラップしたり、グローバルプロパティを作成したりする必要さえありません。