2017-12-26 29 views
3

내 사용자가 내 JavaScript 응용 프로그램에서 JavaScript를 스크립팅 언어로 사용할 수있게하고 싶습니다. 그렇게하기 위해서는 소스 코드를 동적으로 실행해야합니다.ES6 모듈이 들어있는/eval JavaScript 코드를 동적으로 실행하는 방법/일부 종속성이 필요합니까?

A) eval(...) 방법 (또는 var func = new Function(...);를 사용) :

동적으로 자바 스크립트를 실행하기위한 두 가지 옵션이 될 것 같다.

b) $('body').append(...)을 사용하여 DOM에 <script> 노드를 추가합니다.

두 방법 모두 동적으로 실행되는 소스 코드에서 import 문을 사용하지 않는 한 제대로 작동합니다. import 문을 포함하면 오류 메시지 Unexpected identifier이 표시됩니다.

사용자 소스 코드를 실행하는

예 :

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

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

예 어플리케이션 코드가 동적 코드의 가능한 사용을 설명하기 :

a) 평가를

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

옵션 b)에 대해 스크립트 유형을 지정하지 않거나 type="application/javascript"을 사용하면 Unexpected identifier 오류가 발생합니다. type="module"을 사용하면 오류가 발생하지 않습니다. script 태그는 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. DOM에 동적으로 추가 한 후 <script type="module"> 태그를 강제로 실행하려면 어떻게해야합니까? 또는

=> II. import (및 아마도 엑스포트) 문장이 포함 된 스크립트를 어떻게 평가합니까? 또는

=> III. 동적으로 해석 될 수있는 의존성을 정의하기 위해 사용자 소스 코드를 허용하는 좋은 방법은 무엇입니까?

관련 질문 및 기사 :

  • Why is script.onload not working in a Chrome userscript?

  • 또한 노트 :

    나는 예제의 작업 흐름, 사용, window.createTreeModel이 좋지 않은 것을 알고있다. 코드를 이해하기 쉽기 때문에 여기에서 사용했습니다. 모든 업무 흐름을 개선하고 보안 문제와 같은 것에 대해 생각해 봅니다 ... 어떻게 든 종속성을 포함하여 사용자 소스 코드를 실행하도록 관리하면됩니다.

    +0

    transpiler를 사용하십시오. 'window'를 사용하여 export하지 말고,'export' 선언문을 사용하십시오. 특히 코드를 동적으로로드 할 때 코드 평가가 비동기가 될 수 있으므로이를 대비하십시오. – Bergi

    +0

    @Bergi : 모듈 코드가 실행되지 않는 한 내보내기가 작동하지 않습니다. "추가 정보"를 참조하십시오. 로딩이 끝날 때까지 기다릴 수 있었지만 도움이되지 않았습니다. 비동기 로딩을 고려한 예제로 내 질문을 업데이트했습니다. 당신은 transpiler가 내 문제를 해결할 수 있다는 예를 들어 주시겠습니까? – Stefan

    +0

    @Stefan 그는 transpiler를 사용하여 ES6 코드를 ES5로 컴파일 한 다음 ES5 코드를 실행합니다. 브라우저에서 작동하는 변환기는 알지 못합니다. 대부분 PC에서 컴파일하고 브라우저에만 ES5 코드를 배포합니다. – slebetman

    답변

    1

    type="module"을 사용할 때 알아 낸 일부 로그 메시지를 추가 한 후 :

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

    • body.appendChild(script); 비동기 모듈의 코드를 실행 않습니다 모듈의 코드를 실행하지 않고 이벤트 onloadscript.onload =... 대신 addEventListener (...)를 사용하더라도 onreadystatechange이 작동하지 않습니다.

    다음 작품은 저에게 적합합니다.

    : 나는 적어도 전역 함수 window.createModel 제거에 <script type="module"> 태그에서 수출을 사용하는 방법을 찾기 위해 지금 노력

    var sourceCode = editor.getText(); 
    
        window.scriptLoadedHook = function(){ 
         var model = window.createModel(); 
         console.log('model:' + model); 
         window.scriptLoadedHook = undefined; 
        }; 
    
        var body = document.getElementsByTagName('body')[0]; 
        var script = document.createElement('script'); 
        script.type = 'module'; 
        script.innerHTML = sourceCode + "\n" + 
             "if(window.scriptLoadedHook){window.scriptLoadedHook();}";   
        body.appendChild(script); 
    

    : 그것은 글로벌 콜백의 호출을 포함하는 사용자의 소스 코드를 수정

    How to import es6 module that has been defined in <script type="module"> tag inside html?