graaljs icon indicating copy to clipboard operation
graaljs copied to clipboard

[Feature Request] Reference preloaded ECMA Module

Open abelsromero opened this issue 4 years ago • 5 comments

I am trying to use an ECMA Module and I find I am forces to use the Import.

import {Asciidoctor} from 'graalvm/asciidoctor.mjs`;

var asciidoctor = Asciidoctor();

That works on a normal FS, but fails when the script (let's call it app.mjs) and graalvm/asciidoctor.mjs are bundled inside a Jar. I am trying to make it work with a custom FS, but given the module can be preloaded like the example below, I'd be nice to reference the preloaded module instead of having to process it again. That could benefit from cached modules right? I understand that the use of a custom FS invalidates it, I can preload the module content in memory, but it will be parsed on every call.

String ASCIIDOCTOR_JS="graalvm/asciidoctor.mjs"
String APP_JS="app.mjs"

Source asciidoctorSource = Source.newBuilder("js", Utils.fromClasspathUrl(ASCIIDOCTOR_JS)).build();
Value result = context.eval(asciidoctorSource);

Source appSource = Source.newBuilder("js", Utils.fromClasspathUrl(APP_JS)).build();
Value result2 = context.eval(appSource);

abelsromero avatar May 10 '21 22:05 abelsromero

Thinking about it after sleep, the real issue is pre-loading the modules and being able to reference them somehow without parsing them again. With normal JS scripts I can "eval" the first, and have the symbols available when running the second, but that's not possible with ECMA Modules. Maybe import could be handled via bindings?

abelsromero avatar May 11 '21 07:05 abelsromero

@abelsromero a module can be loaded in multiple ways (e.g., you could also use dynamic import). Module caching should work with a custom FS, but of course we might have a bug. Could you provide a full reproducible code example (e.g., a self-contained test with your custom FS etc) describing what's your expected caching semantics?

eleinadani avatar May 11 '21 07:05 eleinadani

Could you provide a full reproducible code example (e.g., a self-contained test with your custom FS etc)

Sure thing! I can prepare something later. Just for context, I just copied the FS from this example https://github.com/oracle/graaljs/blob/master/graal-js/src/com.oracle.truffle.js.test/src/com/oracle/truffle/js/test/builtins/LoadWithCustomFsTest.java.

abelsromero avatar May 11 '21 07:05 abelsromero

Many thanks. Other things got me busy but at the end I got it working. Both loading and caching of modules from within a Jar file using a custom FS. The issue was the {} arround the import :facepalm: amongst other things.

I am renaming the title to clarify this is a FR, not a bug then. I found interesting that you can define a name to a Source like

Source moduleSource = Source.newBuilder(JS, Utils.fromClasspathUrl(ASCIIDOCTOR_JS))
        .name("asciidoctor-module")
        .mimeType("application/javascript+module")
        .build();
context.eval(moduleSource);

But you cannot use it like below. If that did work it would be possible to preload modules much more easily without having to implement a custom FS.

import Asciidoctor from 'custom-fs-asciidoctor';

var asciidoctor = Asciidoctor();

abelsromero avatar May 11 '21 23:05 abelsromero

Happy to hear that you were able to use your ESM modules from a Jar! Regarding the FR, we will discuss whether what you propose can be implemented.

eleinadani avatar May 12 '21 08:05 eleinadani