Нашорн добавил скрипт компиляции в область видимости движка - PullRequest
0 голосов
/ 08 мая 2020

У меня есть два js файлов,

  • один - js библиотека
  • второй - простой скрипт, обычно около 50 строк, который требует доступа к функциям из библиотека.

В моем проекте я пытаюсь предварительно скомпилировать все javascripts во время запуска моего приложения, а затем во время выполнения вызывать только CompiledScripts с желаемыми параметрами.

Я получил следующий код



    static String LIBRARY = "function hello(arg) {return 'Hello ' + arg;};";

    static String SCRIPT = "hello(arg)";

    public static void main(String... args) throws Exception {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("Nashorn");
        Compilable compilable = ((Compilable) engine);
        CompiledScript compiledLib = compilable.compile(LIBRARY);
        compiledLib.eval();

        CompiledScript actualScript = compilable.compile(SCRIPT);

        Bindings helloParams = new SimpleBindings();
        helloParams.put("arg","world");
        ScriptObjectMirror result = (ScriptObjectMirror) actualScript.eval(helloParams);
        System.out.println(result);
}

Но этот код выдает ошибку

> compiledScript.eval(helloParams);
<eval>:1 ReferenceError: "hello" is not defined

Как мне получить доступ к контексту compiledLib (ie методов и переменных) из «actualScript»?

1 Ответ

2 голосов
/ 08 мая 2020

Компиляция не регистрирует функцию hello(), она просто анализирует код JavaScript.

Вам необходимо выполнить код для функции, которая будет зарегистрирована.

Помните, что в JavaScript между этими двумя операторами очень мало различий, за исключением того, что function объявления поднимаются и поэтому могут использоваться перед оператором объявления:

function hello(arg) {return 'Hello ' + arg;};

var hello = function(arg) {return 'Hello ' + arg;};

Есть поэтому мало причин для отдельной компиляции кода БИБЛИОТЕКИ, вы просто запускаете его и сохраняете все созданные глобальные переменные, которые являются методами библиотеки. Например, после выполнения кода БИБЛИОТЕКИ у вас будет глобальная переменная с именем hello.


ScriptEngine engine = new ScriptEngineManager().getEngineByName("Nashorn");
Compilable compilable = ((Compilable) engine);

// Process LIBRARY code
Bindings bindings = new SimpleBindings();
engine.eval(LIBRARY, bindings);

// Compile SCRIPT code
CompiledScript actualScript = compilable.compile(SCRIPT);

// Run SCRIPT code
bindings.put("foo", "world");
Object result = actualScript.eval(bindings);
System.out.println(result);

Вывод

Hello world
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...