Ich möchte ES2015 auch in Java verwenden! → (´ ・ ω ・ `)

MOTIVATION

Babel ist ein Transcompiler, der die neueste ECMAScript-Syntax (Klassen, Lambdas, "const", "let" usw.) übersetzt, damit sie in älteren JS-Umgebungen ausgeführt werden kann. Beispielsweise konvertiert React die ECMA2015 + JSX-Quelle in JS, die von Babel in gängigen Browsern interpretiert werden kann.

Ich hatte ein Unternehmen, das React verwenden wollte, und ich wollte einen API-Server mit Finagle oder Akka vorbereiten, an den ich gewöhnt bin, und ich wollte, dass Node / React und JavaVM überhaupt gut koexistieren. Wenn Babel vom Browser ausführbare JS generieren kann, frage ich mich, ob ES2015 mit Nashorn der Java Scripting API oder der Node.js-Bibliothek verwendet werden kann.

CONCLUSION

Zunächst aus der Schlussfolgerung.

Es ist möglich, in ES2015 geschriebenes JS mit Babel zu transkompilieren und in Nashorn auszuführen. Jedoch:

Streng. Der Grund ist wie folgt.

Daher ist es besser, die Ausführungsumgebung "node" oder "npm" in "Runtime.exec ()" zu verwenden, als Nashorn zu verwenden.

PLAN

Das Verfahren, das ich mit einem solchen Plan ausgeführt habe.

Ich habe es2015-Presets mit npm installiert (bin mir aber nicht sicher, ob ich es wirklich brauchte).

$ npm init
$ npm install babel-cli babel-preset-es2015 --save

1. Vorbereitung von babel.js

Installation von babel-standalone Holen Sie sich babel.js auf der Release-Seite (https://github.com/babel/babel-standalone/releases) oder npm wie in / babel-standalone # -Installation).

final ScriptEngineManager manager = new ScriptEngineManager();

final ScriptEngine babel = manager.getEngineByName("JavaScript");
final String babelJS = "babel.js";
babel.put(ScriptEngine.FILENAME, babelJS);
try(Reader in = new FileReader(babelJS)){
  babel.eval(in);
}

Dieses babel.eval (in) dauert ungefähr 30 Sekunden. Wenn Sie "babel.min.js" verwenden, tritt eine Ausnahme auf. Verwenden Sie daher "babel.js".

javax.script.ScriptException: SyntaxError: empty range in char class in babel.min.js at line number 4
        at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(Unknown Source)
...
Caused by: babel.min.js:4 SyntaxError: empty range in char class
        at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ECMAErrors.error(Unknown Source)
...
Caused by: jdk.nashorn.internal.runtime.ParserException: empty range in char class
        at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.regexp.RegExp.throwParserException(Unknown Source)
...

2. Führen Sie eine Transkompilierung durch

final String es2015JS = "es2015.js";
final String es2015 = new String(Files.readAllBytes(Paths.get(es2015JS)), StandardCharsets.UTF_8);
babel.put(ScriptEngine.FILENAME, "<transcompile>");
babel.put("src", es2015);
babel.put("a", new Object[3]);
final Object[] result = (Object[])babel.eval(
  "var r = Babel.transform(src, {presets:['es2015']});\n" +
  "a[0] = r.code;\n" +
  "a[1] = r.map;\n" +
  "a[2] = r.ast;\n" +
  "a"
);
System.out.println(result[0]);

Babel.transformFileSync war aus irgendeinem Grund undefiniert. Weil Sie Argumente in der Funktion verwenden?

Lesen Sie vorerst die ES2015-Quelle einmal, transformieren Sie sie und speichern Sie das Ergebnis im Rückgabepuffer. In es2015.js ist:

// run `npm install kuromoji` before
import kuromoji from "kuromoji"

kuromoji.builder({ dicPath: "./node_modules/kuromoji/dict" }).build((err, tokenizer) => {
  var path = tokenizer.tokenize("Von den Oberschenkeln und Oberschenkeln")
  console.log(path)
})

Durch das Umkompilieren auf Nashorn wurde die folgende Quelle generiert:

"use strict";

var _kuromoji = require("kuromoji");

var _kuromoji2 = _interopRequireDefault(_kuromoji);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

_kuromoji2.default.builder({ dicPath: "./node_modules/kuromoji/dict" }).build(function (err, tokenizer) {
  var path = tokenizer.tokenize("Von den Oberschenkeln und Oberschenkeln");
  console.log(path);
}); // run `npm install kuromoji` before

Das Ergebnis der Transkompilierung mit Babel ist genau das gleiche.

$ node_modules/.bin/babel --presets=es2015 es2015.js

3. Transkompilierten Code ausführen

Führt den transkompilierten Code getrennt von Babel in der Skript-Engine aus.

final ScriptEngine engine = manager.getEngineByName("JavaScript");
engine.put(ScriptEngine.FILENAME, es2015JS);
engine.eval(result[0].toString());

Aber ich kann es nicht tun, weil ich require () verwende: frowning2:

javax.script.ScriptException: ReferenceError: "require" is not defined in es2015.js at line number 3
        at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(Unknown Source)
...

Oshimashi

Recommended Posts

Ich möchte ES2015 auch in Java verwenden! → (´ ・ ω ・ `)
Ich möchte @Autowired in Servlet verwenden
Ich möchte eine E-Mail in Java senden.
Ich möchte Java8 für jeden mit Index verwenden
rsync4j - Ich möchte rsync in Java berühren.
[Java Spring MVC] Ich möchte DI in meiner eigenen Klasse verwenden
Ich möchte Combine auch in UIKit verwenden.
Ich möchte so etwas wie "cls" in Java machen
Ich möchte ein kleines Symbol in Rails verwenden
Wie verwende ich Klassen in Java?
Ich möchte die Java 8 DateTime-API (jetzt) langsam verwenden.
Selbst in Java möchte ich true mit == 1 && a == 2 && a == 3 ausgeben
Ich möchte die if-else-Anweisung für bedingte Verzweigungen in Java vereinfachen
Mehrsprachige Unterstützung für Java Verwendung des Gebietsschemas
Ich möchte DBViewer mit Eclipse 2018-12 verwenden! !!
Ich habe versucht, Java-Anfänger so einzustellen, dass sie Tastenkombinationen in Eclipse verwenden
Ich möchte Java-Updates insgesamt stoppen
[Java] Ich möchte mit dem Schlüssel im Objekt eindeutig arbeiten
Selbst in Java möchte ich true mit == 1 && a == 2 && a == 3 ausgeben (PowerMockito Edition)
(Beschränkt auf Java 7 oder höher) Ich möchte, dass Sie Objekte in Objects.equals vergleichen
Ich möchte die IP-Adresse erhalten, wenn ich mit Java eine Verbindung zu Wi-Fi herstelle
Ich möchte für jedes Array mit Lambda-Ausdruck in Java
R von Java ausführen Ich möchte rJava ausführen
Ich möchte APP_HOME an Logback in Gradle übergeben
Ich wollte (a == 1 && a == 2 && a == 3) in Java wahr machen
Ich habe versucht, neunundneunzig in Java auszugeben
Ich möchte irgendwann sogar in Kotlin sein
Ich möchte schnell von Java nach SQLite schreiben
Ich habe versucht, Alexa-Fähigkeiten mit Java zu erstellen
Ich möchte den Wert in Ruby erhalten
Verwenden Sie OpenCV mit Java
Verwenden Sie PreparedStatement in Java
Ich möchte, dass Sie Scala vorerst als besseres Java verwenden
Selbst in Java möchte ich true mit == 1 && a == 2 && a == 3 (Black Magic) ausgeben.
[Java] Ich möchte die Differenz zum Datum berechnen
Ich möchte NetBeans auf einem Mac verwenden → Ich kann es verwenden!
Ich möchte eine TraceId in das Protokoll einbetten
Ich habe versucht, die Firebase-Push-Benachrichtigung in Java zu implementieren
# 2 [Anmerkung] Ich habe versucht, neunundneunzig mit Java zu berechnen.
Ich habe versucht, eine Clova-Fähigkeit in Java zu erstellen
Ich habe versucht, eine Anmeldefunktion mit Java zu erstellen
Ich möchte eine Funktion in der Rails Console definieren
[Android Studio] Ich möchte eine Maven-Bibliothek unter Android verwenden
Ich möchte Bildschirmübergänge mit Kotlin und Java machen!
Ich möchte Schlangenfälle mit Tabellendefinitionen stoppen
Wenn Sie Annotation in Java 8 dynamisch ersetzen möchten
Ich möchte in RSpec auf einen GoogleMap-Pin klicken
Ich habe versucht, die Methode der gegenseitigen Teilung von Eugrid in Java zu implementieren
~ Ich habe jetzt versucht, funktionale Programmierung mit Java zu lernen ~
Hinweise zur Verwendung regulärer Ausdrücke in Java
Ich habe versucht herauszufinden, was sich in Java 9 geändert hat
[Android Studio] Ich möchte Einschränkungen für die in EditText [Java] registrierten Werte festlegen.
Ich möchte PowerMock in einer Klasse verwenden, die parametrisierte Tests und gewöhnliche Tests kombiniert
Ich möchte ein Objekt im CSV-Format mit mehrzeiligem Header und Filter in Java zurückgeben
# 1_JAVA Ich möchte die Indexnummer durch Angabe eines Zeichens in der Zeichenfolge erhalten
Code, der verwendet werden soll, wenn Sie Json nur mit Standardbibliotheken in Java verarbeiten möchten