How to dynamically execute / eval javascript containing the ES6 module / requires certain dependencies?

I want my users to be able to use JavaScript as a scripting language inside my JavaScript application. To do this, I need to dynamically execute the source code.

There seem to be two main options for dynamically executing JavaScript:

a) Use the method eval(...)(or var func = new Function(...);).

b) Add a <script>node to the DOM (e.g. using $('body').append(...)).

Both methods work fine as long as I don't use any operators importin the dynamically executable source code. If I include instructions import, I get an error message Unexpected identifier.

Example user source code:

import Atom from './src/core.atom.js':

window.createTreeModel = function(){
   var root = new Atom('root');
   root.createChildAtom('child');
   return root;
}

:

a) eval

var sourceCode =  editor.getText(); 
window.createTreeModel = undefined;
eval(sourceCode);
var model = window.createTreeModel();
treeView.setModel(model);

b) 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);

script type="application/javascript" b), Unexpected identifier. type="module", . script DOM, .

, . , script , type='module'. type="application/javascript", ... ... import .

script :

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. eval script, import (, , )?

= > III. , ?

:

:

, , window.createTreeModel, . , . , ... , - , .

+6
1

, type="module":

  • $('body').append(script);

  • body.appendChild(script); , onload onreadystatechange , addEventListener (...) script.onload =...

. , :

    var sourceCode =  editor.getText(); 

    window.scriptLoadedHook = function(){
        var model = window.createModel();
        console.log('model:' + model);
        window.scriptLoadedHook = undefined;
    };

    var body = document.body;
    var script = document.createElement('script');
    script.type = 'module';
    script.innerHTML = sourceCode + "\n" + 
                       "if(window.scriptLoadedHook){window.scriptLoadedHook();}";           
    body.appendChild(script);   

, <script type="module"> window.createModel:

es6, <script type = "module"> html?

+3

Source: https://habr.com/ru/post/1691382/


All Articles