tc39 / proposal-source-phase-imports

Proposal to enable importing modules at the source phase
https://tc39.es/proposal-source-phase-imports/
MIT License
132 stars 8 forks source link

Initial spec text #21

Closed guybedford closed 2 years ago

guybedford commented 2 years ago

This provides initial spec text for the feature based on the simplification that import reflection is now only the module reflection, and syntactical as opposed to an arbitrary string: import module x from './x.js' and import('./x.js', { reflect: 'module' }).

This approach is fully compatible and symmetric with the asset references proposal as being a future reflection implementation replacing module with asset.

This implementation leaves reflected modules out of the normal [[ModuleRequests]] list on a source text, then entirely defers to a HostResolveModuleReflection hook - further narrowing the host invariants around this hook will be for follow up work, per the previous approaches described around possibly splitting resolution into an opaque resolution and final resolution stage. If considered, this work needs to be done carefully to align with other proposals.

The readme is also updated to the latest directions.

ljharb commented 2 years ago

Why is the syntax and the dynamic form so different? Meaning, the word “reflect” is in one but not the other.

guybedford commented 2 years ago

@ljharb the idea is that module reflection is one type of import reflection, whereas import assertions in future might be seen to be another type of import reflection. This proposal here is now primarily concerned with module import reflection though, aiming to rather set a precedent for future reflections as opposed to over-generalizing any mechanic from the start.

Specifically, the dynamic import object effectively has a named argument for the reflection syntax position.

ljharb commented 2 years ago

@guybedford doesn't have to block this PR, but it’s pretty important to me that the static and dynamic forms are mirrored, like they are for import assertions.

guybedford commented 2 years ago

@ljharb I'm pretty sure this mirroring requirement is being met if you consider the following relation between syntax and dynamic import:

import <reflection> <identifier> from '<specifier>'

being symmetrical to:

const <identifier> = await import('<specifier>', { 'reflect': '<reflection>' })

Where we are specifying <reflection> = module but in future other reflections may exist like asset.

ljharb commented 2 years ago

the word "reflect" doesn't appear in the static form tho. import reflect module, for example (not that i'm suggesting this), would be mirrored.

guybedford commented 2 years ago

Right, it's more like a numbered argument in this case.

ljharb commented 2 years ago

import(specifier, 'module', {}) would also be mirrored, but i don't think that would be a great overload for import().