Java에서도 ES2015를 사용하고 싶다! → (´・ω・`)
MOTIVATION
Babel 은 최신의 ECMAScript 구문 (클래스나 람다나
const
, let
등)을 낡은 사양의 JS 환경에서도 실행할 수 있도록(듯이) 변환하는 트랜스 컴파일러. 예를 들어 React는 ECMA2015 + JSX 소스를 Babel의 일반적인 브라우저에서도 해석할 수 있는 JS로 변환하고 있습니다.React 를 사용하는 일이 있어, 익숙한 Finagle 인가 Akka 로 API 서버를 준비하려고 생각해, Node/React 와 JavaVM 는 잘 공존시키고 싶었던 것이 원래 시작. Babel에서 브라우저 실행 가능한 JS를 생성할 수 있다면 Java Scripting API의 Nashorn에서 ES2015를 사용할 수 있거나 Node.js 라이브러리를 사용할 수 있는 것은?
CONCLUSION
결론부터 먼저.
ES2015로 작성된 JS를 Babel로 트랜스 컴파일하고 Nashorn에서 실행할 수 있습니다. 그러나:
힘든. 이유는 다음과 같습니다.
eval()
에 30 초 걸린다. 우는 CPU 팬. 아무튼 서버사이드등은 준비가 끝난 ScriptEngine
를 캐쉬 해 두면 좋을지도 모른다. require()
가 없으므로 외부 라이브러리를 사용할 수 없습니다. webpack도 함께 사용할 필요가 있을 것 같다. 혹은 Java 로 동등 기능을 구현해 bindings 로 건네주면 회피 가능할지도 모른다. npm
를 전제로 하기 때문에 Nashorn 를 사용하지 않고도 babel 를 직접 기동하는 수단이 있다 (그리고 그쪽이 빠르다). 따라서 Nashorn을 사용하는 것보다 실행 환경의
node
npm
PLAN
이런 계획으로 실행했다는 절차.
npm에서 es2015의 presets를 설치하고 있습니다 (정말로 필요한지 알 수 없음).
$ npm init
$ npm install babel-cli babel-preset-es2015 --save
1. babel.js 준비
babel-standalone 의 Installation 에서처럼 출시 페이지 또는 npm 에서
Runtime.exec()
를 얻습니다.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);
}
이
babel.js
에서 30초 정도 걸립니다. 또한 babel.eval(in)
를 사용하면 예외가 발생하므로 babel.min.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. 트랜스 컴파일 실행
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.js
는 왜 undefined 이었습니다. 함수 내에서 arguments를 사용하고 있습니까?먼저 ES2015 소스를 한 번 읽고
Babel.transformFileSync
결과를 반환 버퍼에 저장합니다. es2015.js 안에서는 다음과 같다:// run `npm install kuromoji` before
import kuromoji from "kuromoji"
kuromoji.builder({ dicPath: "./node_modules/kuromoji/dict" }).build((err, tokenizer) => {
var path = tokenizer.tokenize("すもももももももものうち")
console.log(path)
})
Nashorn에서의 트랜스컴파일에 의해 다음과 같은 소스가 생성되었습니다.
"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("すもももももももものうち");
console.log(path);
}); // run `npm install kuromoji` before
Babel로 트랜스 컴파일한 결과도 똑같다.
$ node_modules/.bin/babel --presets=es2015 es2015.js
3. 트랜스 컴파일된 코드 실행
스크립트 엔진을 Babel과는 별도로 트랜스 컴파일된 코드를 실행합니다.
final ScriptEngine engine = manager.getEngineByName("JavaScript");
engine.put(ScriptEngine.FILENAME, es2015JS);
engine.eval(result[0].toString());
그러나
transform
를 사용하기 때문에 실행할 수 없습니다. 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)
...
오시마
Reference
이 문제에 관하여(Java에서도 ES2015를 사용하고 싶다! → (´・ω・`)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/torao@github/items/50394172c06be23af3ce텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)