我正在尝试使用Grall.js的实验性ES模块支持。
我使用以下脚本:ES模块“lib”
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
和主脚本“脚本”
import { square, diag } from 'lib';
console.log('square(11)=' + square(11));
console.log('diag(4,3)=' + diag(4, 3));
我使用graalvm-ce-19.2.1,并通过JSR 223在JVM内使用Polyglot运行主脚本。
它不会尝试从磁盘上的某个位置加载lib而是抛出:
javax.script.ScriptException: org.graalvm.polyglot.PolyglotException: SyntaxError: script:1:0 Expected an operand but found import
import { square, diag } from 'lib';
^
script:1:30 Expected ; but found lib
import { square, diag } from 'lib';
^
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:348)
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:323)
怎么了?
最佳答案
关于文件名有一个约定,触发将它们视为ES模块-文件必须以.mjs
结尾。或者,可以在application/javascript+module
对象上使用(非官方)哑剧类型org.graalvm.polyglot.Source
。如果没有此import
语句,则不允许1。
使用Polyglot Source / Context API时的外观如下:
String script = "import {x} from 'lib'";
// these two support "import"
Source source1 = Source.newBuilder("js", script, "script.mjs").build();
Source source2 = Source.newBuilder("js", script, "script").mimeType("application/javascript+module").build();
// this one doesn't
//Source source3 = Source.newBuilder("js", script, "script").build();
这是针对JSR-223 API的:
javax.script.ScriptEngine engine = factory.getEngineByName("graal.js");
engine.getContext().setAttribute(ScriptEngine.FILENAME, "script.mjs", ScriptContext.ENGINE_SCOPE);
似乎也有an older convention-使用
module:
前缀,但这似乎不再起作用。