Как импортировать модуль es6, который был определен в теге <script type = "module"> внутри html?
у, чтобы мои пользователи могли использовать JavaScript в качестве языка сценариев внутри моего приложения JavaScript. Для этого мне нужно динамически выполнить исходный код.
Кажется, есть два основных варианта динамического выполнения JavaScript:
а) использоватьeval(...)
метод (илиvar func = new Function(...);
)
б) Добавить<script>
узел к DOM (например, с помощью$('body').append(...)
).
Оба метода работают нормально, пока я не используюimport
операторы в динамически выполняемом исходном коде. Если я включуimport
заявления я получаю сообщение об ошибкеUnexpected identifier
.
Пример исходного кода пользователя для выполнения:
import Atom from './src/core.atom.js':
window.createTreeModel = function(){
var root = new Atom('root');
root.createChildAtom('child');
return root;
}
Пример кода приложения для иллюстрации возможного использования этого динамического кода:
а) Использование eval
var sourceCode = editor.getText();
window.createTreeModel = undefined;
eval(sourceCode);
var model = window.createTreeModel();
treeView.setModel(model);
б) Используя модификацию DOM:
var sourceCode = editor.getText();
window.createTreeModel = undefined;
var script = "<script >\n"+
sourceCode + "\n" +
"</script>";
$('body').append(script);
var model = window.createTreeModel();
treeView.setModel(model);
Если я не укажу тип сценария или использоватьtype="application,/javascript"
для варианта б) я получаюUnexpected identifier
ошибка. Если я используюtype="module"
Я не получаю ошибки. Тег сценария успешно добавлен в DOM, но код модуля не выполняется.
Сначала я подумал, что это может быть связано с асинхронной загрузкой. Однако ожидание завершения загрузки тега сценария не работало сtype='module'
, Механизм загрузки работает сtype="application/javascript"
но затем снова...import
не работает.
Пример кода для асинхронного выполнения после загрузки тега скрипта:
function loadScript(sourceCode, callback){
// Adding the script tag to the head as suggested before
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'application/javascript';
script.innerHTML = sourceCode;
//script.async=false;
// Then bind the event to the callback function.
// There are several events for cross browser compatibility.
script.onreadystatechange = callback;
script.onload = callback;
// Fire the loading
head.appendChild(script);
}
-
loadScript(sourceCode, function(){
var model = window.createModel();
console.log('model:' + model);
});
Если я жестко закодирую исходный код пользователя в моем index.html, используя<source type="module">
код модуля выполнен. Динамическая загрузка кода модуля, похоже, не работает. Я использую Chrome версии 63.0.3239.108.
=> I. Как я могу форсировать исполнение<script type="module">
тег после его динамического добавления в DOM? или же
=> II. Как я могу оценить скрипт, который содержитimport
(и, возможно, экспорт) заявления? или же
=> III. Что может быть хорошим способом разрешить пользовательскому исходному коду определять зависимости, которые могут быть разрешены динамически?
Связанные вопросы и статьи:
Выполнить код JavaScript, хранящийся в виде строки
https://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/#safely-sandboxing-eval
https://javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval/
Как включить файл JavaScript в другой файл JavaScript?
Почему script.onload не работает в пользовательском скрипте Chrome?
Как импортировать модуль es6, который был определен в теге <script type = "module"> внутри html?
Дальнейшие заметки:
Я знаю, что рабочий процесс примеров, используя,window.createTreeModel
не идеален Я использовал его здесь, потому что код легко понять. Я улучшу свой рабочий процесс и буду думать о таких вещах, как проблемы безопасности ... после того, как мне удалось как-то запустить исходный код пользователя, включая его зависимости.