添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Graal.js importing module causes org.graalvm.polyglot.PolyglotException: SyntaxError: Expected an operand but found import

Ask Question

I am trying to use experimental ES module support from Grall.js. I use following scripts: ES module "lib"

export const sqrt = Math.sqrt;
export function square(x) {
    return x * x;
export function diag(x, y) {
    return sqrt(square(x) + square(y));

and main script "script"

import { square, diag } from 'lib';
console.log('square(11)=' + square(11));
console.log('diag(4,3)=' + diag(4, 3));

I use graalvm-ce-19.2.1 and I use Polyglot inside JVM via JSR 223 to run the main script. Instead of trying to load lib from some place on disk it throws:

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)

What's wrong?

There is a convention on file names which trigger treating them as ES modules - file must end with .mjs. Alternatively it is possible to use (unofficial) mime type application/javascript+module on org.graalvm.polyglot.Source object. Without this import statement is not allowed 1.

This is how it looks when using 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(); 

and this is for JSR-223 API:

javax.script.ScriptEngine engine = factory.getEngineByName("graal.js");
engine.getContext().setAttribute(ScriptEngine.FILENAME, "script.mjs", ScriptContext.ENGINE_SCOPE);

It seems that there also was an older convention - using module: prefix, but this doesn't seem to work anymore.

As far as I remember there is only this comment: github.com/graalvm/graaljs/issues/92#issuecomment-474858574 – tporeba Jul 28, 2020 at 8:32 Oh it seems there is some new piece of documentation here github.com/graalvm/graaljs/blob/master/docs/user/… – tporeba Jul 28, 2020 at 8:34

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.