Will it be possible to retrieve a loaded module's exports synchronously?

# John Lenz (9 years ago)

Background:

I'm trying to plan a migration to ES6 modules. For interop with the existing systems in the short-medium term, I would like to be able to retrieve a loaded modules exports synchronously (basically a "get or fail").

It looks like retrieving the exports synchronously is possible using the Registry object, however the registry requires that you have an appropriate "key". The "key" appears to only be resolvable asynchronously which means the whole operation must async.

Am I missing something?

# Caridy Patiño (9 years ago)

I’m not sure what are you trying to do, but from within the module itself, you will have access to some metadata about the module, we have been chatting about import() and import.<key> as the imperative forms to import relative modules, accessing module’s metadata, and potentially a reference to the loader instance bound to the module (thru module status), but all that in up in the air.

From outside, things are more complicated, you have access to the registry of every loader instance, you can walk each registry, and do what you please, but there is no guarantee that the module status that you’re looking for is accessible (they can be removed from the registry and still function).

You should probably post this question on whatwg/loader repo.

# Bradley Meck (9 years ago)

In Node we can get the import path synchronously just from the parsed module, as proposed API in bmeck/node-eps/blob/es6-module/002-es6-modules.md suggests. Can you clarify what you mean with

The "key" appears to only be resolvable asynchronously

Which key? the path resolved from the source text?

# John Lenz (9 years ago)

On Wed, Feb 24, 2016 at 3:28 PM, Bradley Meck <bradley.meck at gmail.com>

wrote:

In Node we can get the import path synchronously just from the parsed module, as proposed API in bmeck/node-eps/blob/es6-module/002-es6-modules.md suggests. Can you clarify what you mean with

The "key" appears to only be resolvable asynchronously

Which key? the path resolved from the source text?

From the spec the "key" appears to be opaque. For my purpose the I would

be interested in resolving the "name" so the module exports can be retrieved.

# John Lenz (9 years ago)

I'm trying to do exactly what it sounds (I hope): given a path and the system loader registry, retrieve the module exports. This would allow an action to be taken only if the module hand already be loaded without forcing the module to be if it weren't.

# Caridy Patiño (9 years ago)

There is no such thing as a key in 262 (module spec). The key is a concept defined by the loader, and there it is not opaque.

For my purpose the I would be interested in resolving the "name" so the module exports can be retrieved.

Can you explain more? Resolving from where? The context matters for the resolution process, e.g.: the referral can define how to resolve a module identifier. As for retrieving the module exports, you have to go thru the APIs that will guarantee that those exports are ready to be consumed, and those are the import statements, the import() calls, and Reflect.Module.evaluate(), you have no other way to access those exports in a way that is reliable. Via the registry, you can attempt to inspect every module status in the registry, trying to access the namespace exotic object via ModuleStatus.prototype.module getter, but there is no guarantee that you get it, it depends on the current stage of the module in the pipeline.

# John Lenz (9 years ago)

var exports = System.loader.registery.get('path/file.js');

On Wed, Feb 24, 2016 at 3:53 PM, Caridy Patiño <caridy at gmail.com> wrote:

There is no such thing as a key in 262 (module spec). The key is a concept defined by the loader, and there it is not opaque.

I don't see where the value of the key/meaning of the key is defined. Can you be more specific as to what it is required to be?

For my purpose the I would be interested in resolving the "name" so the module exports can be retrieved.

Can you explain more? Resolving from where?

A script or a module. If this isn't helpful, I'm unclear on what the possible values for "where" are.

The context matters for the resolution process, e.g.: the referral can define how to resolve a module identifier.

The context is user code, where the available "name" of a module would be identical to what would be used in an import declaration.

As for retrieving the module exports, you have to go thru the APIs that will guarantee that those exports are ready to be consumed, and those are the import statements, the import() calls, and Reflect.Module.evaluate(), you have no other way to access those exports in a way that is reliable.

"import", "import()" and "evaluate" all force a load and a wait. Forcing a load is distinctly not what is desired here. I understand that a load could be "under way" but if one wanted to wait they would simply call "import()".

Via the registry, you can attempt to inspect every module status in the registry, trying to access the namespace exotic object via ModuleStatus.prototype.module getter, but there is no guarantee that you get it, it depends on the current stage of the module in the pipeline.

I having a hard time here to trying to understand what I can say differently to explain what I desire: I need to know if a module is loaded and ready, if it is I want the module exports immediately.

# Caridy Patiño (9 years ago)

inline (but again, we should move this conversation to the loader repo where you will get more people looking at your questions)...

On Feb 24, 2016, at 7:57 PM, John Lenz <concavelenz at gmail.com> wrote:

var exports = System.loader.registery.get('path/file.js');

No, the registry contains Module Status Objects.

On Wed, Feb 24, 2016 at 3:53 PM, Caridy Patiño <caridy at gmail.com <mailto:caridy at gmail.com>> wrote: There is no such thing as a key in 262 (module spec). The key is a concept defined by the loader, and there it is not opaque.

I don't see where the value of the key/meaning of the key is defined. Can you be more specific as to what it is required to be?

The registry is essentially a Map of Module Status Objects. Users will have control over the keys associated to a Module Status Object via the "resolve" hook.

As for retrieving the module exports, you have to go thru the APIs that will guarantee that those exports are ready to be consumed, and those are the import statements, the import() calls, and Reflect.Module.evaluate(), you have no other way to access those exports in a way that is reliable.

"import", "import()" and "evaluate" all force a load and a wait. Forcing a load is distinctly not what is desired here. I understand that a load could be "under way" but if one wanted to wait they would simply call "import()".

No, if you go thru the loader, it will be asynchronous to guarantee that the module and its dependencies are ready and evaluated.

I need to know if a module is loaded and ready, if it is I want the module exports immediately.

No, the closest you can get to that is by doing this:

let moduleStatusObj = System.loader.registry.get(key);
if (moduleStatusObj.module !== undefined) {
   // you’re lucky! you have access to the exotic namespace object of the module
} 

In user-land, when you have access to an exotic namespace object, its module is guarantee to be instantiated, but there is not guarantee to be evaluated, or its circular dependencies evaluated, which you will have to force by calling Reflect.Module.evaluate(), which returns a promise that resolves once the module graph is ready to roll.

On the other side of the coin, what if the entry is not in the registry? Are you planning to fork the logic in your code to go and attempt to load it?

# John Lenz (9 years ago)

On Wed, Feb 24, 2016 at 7:35 PM, Caridy Patiño <caridy at gmail.com> wrote:

inline (but again, we should move this conversation to the loader repo where you will get more people looking at your questions)...

whatwg/loader#130

On Feb 24, 2016, at 7:57 PM, John Lenz <concavelenz at gmail.com> wrote:

var exports = System.loader.registery.get('path/file.js');

No, the registry contains Module Status Objects.

Right, I'm just frame the general idea

On Wed, Feb 24, 2016 at 3:53 PM, Caridy Patiño <caridy at gmail.com> wrote:

There is no such thing as a key in 262 (module spec). The key is a concept defined by the loader, and there it is not opaque.

I don't see where the value of the key/meaning of the key is defined. Can you be more specific as to what it is required to be?

The registry is essentially a Map of Module Status Objects. Users will have control over the keys associated to a Module Status Object via the "resolve" hook.

Right, for my purpose, if it can be "any loader defined value" that makes it an opaque value. Generally a library won't control the environment it is loaded in.

As for retrieving the module exports, you have to go thru the APIs that

will guarantee that those exports are ready to be consumed, and those are the import statements, the import() calls, and Reflect.Module.evaluate(), you have no other way to access those exports in a way that is reliable.

"import", "import()" and "evaluate" all force a load and a wait. Forcing a load is distinctly not what is desired here. I understand that a load could be "under way" but if one wanted to wait they would simply call "import()".

No, if you go thru the loader, it will be asynchronous to guarantee that the module and its dependencies are ready and evaluated.

"wait" here meant "wait for the promise to resolve".

I need to know if a module is loaded and ready, if it is I want the module exports immediately.

No, the closest you can get to that is by doing this:

let moduleStatusObj = System.loader.registry.get(key);
if (moduleStatusObj.module !== undefined) {
   // you’re lucky! you have access to the exotic namespace object of the
module
}

In user-land, when you have access to an exotic namespace object, its module is guarantee to be instantiated, but there is not guarantee to be evaluated, or its circular dependencies evaluated, which you will have to force by calling Reflect.Module.evaluate(), which returns a promise that resolves once the module graph is ready to roll.

Doesn't the "stage" tell you if it is "ready to roll"?

On the other side of the coin, what if the entry is not in the registry? Are you planning to fork the logic in your code to go and attempt to load it?

Nope, in this case, continue without it.