caoccao/Javet

'IV8Module v8ModuleReferrer' is always null

Closed this issue ยท 6 comments

Hi again,

I'm trying to implement a custom JavetBuiltInModuleResolver to be able to resolve modules automatically. Every time it enters to IV8ModuleResolver#resolve method, IV8Module v8ModuleReferrer variable is always null.

I need to be able to understand from which module has requested another module, so I can load from correct directory the correct module. For example sometimes there are some imports like import {test} from "./abc.js" which is under server folder and I load main script as index.js and when I'm about to resolve that module "abc.js" it seems like I'm in dir ./ but if IV8Module v8ModuleReferrer came with it's path, then I would be able to understand it is under server folder.

Example dir:

index.js (imports b.js from server folder)
server/b.js (imports {test} from ./abc.js file)
server/abc.js (exports test function)

Good question. Most of Javet users virtualize the module system with absolute module path so that the referrer is always ignored. And, yes, I think the case you present is equally important. I'll check it out later.

I checked the code. Here's my finding.

The referrer exists, but the resource name is always null because V8 doesn't provide that. The official solution is to keep a Map<Integer, String> of script ID to resource name in the application so that the application may look up in the callback. I'll try to build this feature in.

Please let me know if you have any questions.

By this method, will it be the solution to this problem?

I thought it over and found out: It's right for V8 not to carry resource name with the module because the referrer's resource name may change based on the relative referencing hierarchy.

e.g. Consider the following 2 chains: module d.js has 2 resource names ./d.js and ./b/d.js. V8 or Javet has no idea on which one is the one. I think only the application knows which one is suitable in that context, and it's better to have the application maintain the relationship between module script ID and resource name. That's what I suggested in my previous reply.

โ”‚โ”€ a.js
โ””โ”€ b
   โ”œโ”€ c.js
   โ”œโ”€ d.js
   โ””โ”€ e.js
  1. ./a.js โ†’ ./b/c.js โ†’ ./d.js -> ./e.js
  2. ./a.js โ†’ ./b/d.js -> ./e.js

Hence, there are no changes required in Javet. Please let me know if you have any questions. You may join discord to discuss with me in detail.

Good news!

I enhanced V8Module.getResourceName() so that it can return the actual module name. V8 stores the module name somewhere, but doesn't want to expose it. I had to dig in hardly.

Now, both options are open to you. Please wait for the new release for this new feature.

Oh, that's great! I also mentioned in Discord help channel about this issue but now it fixes this. I'll be able to test it out when it's released and close the issue. Thanks again.