I want to use ES2015 in Java too! → (´ ・ ω ・ `)

MOTIVATION

Babel is a transcompiler that translates the latest ECMAScript syntax (classes, lambdas, const, let, etc.) so that it can be run in older JS environments. For example, React translates ECMA2015 + JSX source into Babel JS that can be interpreted by common browsers.

I had a business to use React, I wanted to prepare an API server with Finagle or Akka, which I'm used to, and I wanted Node / React and JavaVM to coexist well. If Babel can generate a browser-executable JS, I wonder if ES2015 can be used with Nashorn, a Java Scripting API, or the Node.js library can be used.

CONCLUSION

First from the conclusion.

It is possible to transcompile JS written in ES2015 with Babel and run it with Nashorn. However:

Strict. The reason is as follows.

Therefore, it is better to use the execution environment node or npm in Runtime.exec () than to use Nashorn.

PLAN

The procedure that I executed with such a plan.

I have es2015 presets installed on npm (but I'm not sure if I really needed it).

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

1. Preparation of babel.js

Installation of babel-standalone Get babel.js on the Release Page (https://github.com/babel/babel-standalone/releases) or npm as 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);
}

This babel.eval (in) takes about 30 seconds. Also, if you use babel.min.js, an exception will occur, so use 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. Perform transcompile

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 was undefined for some reason. Because you use arguments in the function?

For the time being, read the ES2015 source once, transform and store the result in the return buffer. Inside es2015.js is:

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

kuromoji.builder({ dicPath: "./node_modules/kuromoji/dict" }).build((err, tokenizer) => {
  var path = tokenizer.tokenize("Of the thighs and thighs")
  console.log(path)
})

Transcompiling on Nashorn generated the following source:

"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("Of the thighs and thighs");
  console.log(path);
}); // run `npm install kuromoji` before

The result of transcompiling with Babel is exactly the same.

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

3. Executing transcompiled code

Runs transcompiled code separately from Babel in the script engine.

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

But I can't do it because I'm using require (): 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

I want to use ES2015 in Java too! → (´ ・ ω ・ `)
I want to use @Autowired in Servlet
I want to send an email in Java.
I want to use arrow notation in Ruby
I want to use java8 forEach with index
rsync4j --I want to touch rsync in Java.
[Java Spring MVC] I want to use DI in my own class
I want to use Combine in UIKit as well.
I want to do something like "cls" in Java
I want to use a little icon in Rails
I want to use FormObject well
How to use classes in Java?
I want to use the Java 8 DateTime API slowly (now)
Even in Java, I want to output true with a == 1 && a == 2 && a == 3
I want to simplify the conditional if-else statement in Java
Multilingual Locale in Java How to use Locale
I want to use DBViewer with Eclipse 2018-12! !!
I tried setting Java beginners to use shortcut keys in eclipse
I want to stop Java updates altogether
[Java] I want to perform distinct with the key in the object
Even in Java, I want to output true with a == 1 && a == 2 && a == 3 (PowerMockito edition)
(Limited to Java 7 or later) I want you to compare objects in Objects.equals
I want to get the IP address when connecting to Wi-Fi in Java
I want to ForEach an array with a Lambda expression in Java
Run R from Java I want to run rJava
I tried to implement deep learning in Java
I want to pass APP_HOME to logback in Gradle
I wanted to make (a == 1 && a == 2 && a == 3) true in Java
I tried to output multiplication table in Java
[Xcode] I want to manage images in folders
I want to be eventually even in kotlin
I want to write quickly from java to sqlite
I tried to create Alexa skill in Java
I want to get the value in Ruby
Use OpenCV in Java
Use PreparedStatement in Java
I want you to use Scala as Better Java for the time being
Even in Java, I want to output true with a == 1 && a == 2 && a == 3 (black magic edition)
[Java] I want to calculate the difference from the date
I want to use NetBeans on Mac → I can use it!
I want to embed any TraceId in the log
I tried to implement Firebase push notification in Java
# 2 [Note] I tried to calculate multiplication tables in Java.
I tried to create a Clova skill in Java
I tried to make a login function in Java
I want to define a function in Rails Console
[Android Studio] I want to use Maven library on Android
I want to transition screens with kotlin and java!
I want to stop snake case in table definition
When you want to dynamically replace Annotation in Java8
I want to click a GoogleMap pin in RSpec
I tried to implement the Euclidean algorithm in Java
~ I tried to learn functional programming in Java now ~
I want to get along with Map [Java beginner]
Notes on how to use regular expressions in Java
I tried to find out what changed in Java 9
[Android Studio] I want to set restrictions on the values registered in EditText [Java]
I want to use PowerMock in a class that combines parameterized tests and ordinary tests
I want to return an object in CSV format with multi-line header & filter in Java
# 1_JAVA I want to get the index number by specifying one character in the character string.
Code to use when you want to process Json with only standard library in Java