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.
takes ** 30 seconds **. Groaning CPU fan. Well, on the server side etc., it may be good to cache the prepared
ScriptEngine`.require ()
, so ** external libraries cannot be used **. It seems that webpack also needs to be used. Alternatively, it may be possible to avoid it by implementing the equivalent function in Java and passing it in bindings.npm
in the environment settings in the first place, there is a way to start babel directly without using Nashorn (and that is faster).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
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)
...
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
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