This proposal adds a new form of "export from" which exports another module's namespace exotic object as an exported name of another, filling a use case similar to the use cases for existing "export from" forms.
See the proposal repository for motivations and more information.
This proposal is closely related to the export default from proposal.
This spec proposal is written as a diff against the existing ECMAScript specification.
A module namespace object is an exotic object that exposes the bindings exported from an ECMAScript export *
export items. Each String-valued own property key is the StringValue of the corresponding exported binding name. These are the only String-keyed properties of a module namespace exotic object. Each such property has the attributes { [[Writable]]:
When the [[Get]] internal method of a module namespace exotic object O is called with property key P and
"*namespace*"
, thenResolveExport is idempotent and side-effect free. An implementation might choose to pre-compute or cache the ResolveExport results for the [[Exports]] of each module namespace exotic object.
A Module Record encapsulates structural information about the imports and exports of a single module. This information is used to link the imports and exports of sets of connected modules. A Module Record includes four fields that are only used when evaluating a module.
For specification purposes Module Record values are values of the
Module Record defines the fields listed in
Field Name | Value Type | Meaning |
---|---|---|
[[Realm]] |
|
The |
[[Environment]] |
|
The |
[[Namespace]] |
Object | |
The Module Namespace Object ( |
[[HostDefined]] |
Any, default value is |
Field reserved for use by host environments that need to associate additional information with a module. |
Method | Purpose |
---|---|
GetExportedNames(exportStarSet) | Return a list of all names that are either directly or indirectly exported from this module. |
ResolveExport(exportName, resolveSet) |
Return the binding of a name exported by this module. Bindings are represented by a ResolvedBinding Record, of the form {[[Module]]: This operation must be idempotent if it completes normally. Each time it is called with a specific exportName, resolveSet pair as arguments it must return the same result. |
Instantiate() |
Prepare the module for evaluation by transitively resolving all module dependencies and creating a module |
Evaluate() |
If this module has already been evaluated successfully, return Instantiate must have completed successfully prior to invoking this method. |
A Source Text Module Record is used to represent information about a module that was defined from ECMAScript source text (
A
In addition to the fields, defined in
Field Name | Value Type | Meaning |
---|---|---|
[[ECMAScriptCode]] | a Parse Node |
The result of parsing the source text of this module using |
[[RequestedModules]] |
|
A |
[[ImportEntries]] |
|
A |
[[LocalExportEntries]] |
|
A |
[[IndirectExportEntries]] |
|
A |
[[StarExportEntries]] |
|
A |
[[Status]] | String |
Initially "uninstantiated" . Transitions to "instantiating" , "instantiated" , "evaluating" , "evaluated" (in that order) as the module progresses throughout its lifecycle.
|
[[EvaluationError]] |
An |
A completion of type "evaluated" .
|
[[DFSIndex]] |
Integer | |
Auxiliary field used during Instantiate and Evaluate only.
If [[Status]] is "instantiating" or "evaluating" , this non-negative number records the point at which the module was first visited during the ongoing depth-first traversal of the dependency graph.
|
[[DFSAncestorIndex]] |
Integer | |
Auxiliary field used during Instantiate and Evaluate only. If [[Status]] is "instantiating" or "evaluating" , this is either the module's own [[DFSIndex]] or that of an "earlier" module in the same strongly connected component.
|
An ImportEntry Record is a
Field Name | Value Type | Meaning |
---|---|---|
[[ModuleRequest]] | String |
String value of the |
[[ImportName]] | String |
The name under which the desired binding is exported by the module identified by [[ModuleRequest]]. The value "*" indicates that the import request is for the target module's namespace object.
|
[[LocalName]] | String | The name that is used to locally access the imported value from within the importing module. |
Import Statement Form | [[ModuleRequest]] | [[ImportName]] | [[LocalName]] |
---|---|---|---|
import v from "mod";
|
"mod"
|
"default"
|
"v"
|
import * as ns from "mod";
|
"mod"
|
"*"
|
"ns"
|
import {x} from "mod";
|
"mod"
|
"x"
|
"x"
|
import {x as v} from "mod";
|
"mod"
|
"x"
|
"v"
|
import "mod";
|
An |
An ExportEntry Record is a
Field Name | Value Type | Meaning |
---|---|---|
[[ExportName]] | String | null | The name used to export this binding by this module. |
[[ModuleRequest]] | String | null |
The String value of the |
[[ImportName]] | String | null |
The name under which the desired binding is exported by the module identified by [[ModuleRequest]]. "*" indicates that the export request is for all exported bindings.
|
[[LocalName]] | String | null |
The name that is used to locally access the exported value from within the importing module. |
Export Statement Form | [[ExportName]] | [[ModuleRequest]] | [[ImportName]] | [[LocalName]] |
---|---|---|---|---|
export var v;
|
"v"
|
|
|
"v"
|
export default function f(){}
|
"default"
|
|
|
"f"
|
export default function(){}
|
"default"
|
|
|
"*default*"
|
export default 42;
|
"default"
|
|
|
"*default*"
|
export {x};
|
"x"
|
|
|
"x"
|
export {v as x};
|
"x"
|
|
|
"v"
|
export {x} from "mod";
|
"x"
|
"mod"
|
"x"
|
|
export {v as x} from "mod";
|
"x"
|
"mod"
|
"v"
|
|
export * from "mod";
|
|
"mod"
|
"*"
|
|
export * as ns from "mod";
|
"ns"
|
"mod"
|
"*"
|
|
The following definitions specify the required concrete methods and other abstract operations for Source Text Module Records
The abstract operation ParseModule with arguments sourceText, realm, and hostDefined creates a
"*"
, then"*"
and ee.[[ExportName]] is "uninstantiated"
, [[EvaluationError]]: An implementation may parse module source text and analyse it for Early Error conditions prior to the evaluation of ParseModule for that module source text. However, the reporting of any errors must be deferred until the point where this specification actually performs ParseModule upon that source text.
The ResolveExport concrete method of a
ResolveExport attempts to resolve an imported binding to the actual defining module and local binding name. The defining module may be the module represented by the
If a defining module is found, a "*namespace*"
. If no definition was found or the request is found to be circular, "ambiguous"
is returned.
This abstract method performs the following steps:
"*"
, then"*namespace*"
}."default"
) is default
export was not explicitly defined by this module.default
export cannot be provided by an export *
."ambiguous"
, return "ambiguous"
.*
import that includes the requested name."ambiguous"
.The Instantiate concrete method of a
On success, Instantiate transitions this module's [[Status]] from "uninstantiated"
to "instantiated"
. On failure, an exception is thrown and this module's [[Status]] remains "uninstantiated"
.
This abstract method performs the following steps (most of the work is done by the auxiliary function InnerModuleInstantiation):
"instantiating"
or "evaluating"
."instantiating"
."uninstantiated"
."uninstantiated"
."instantiated"
or "evaluated"
.The ModuleDeclarationEnvironmentSetup abstract operation is used by InnerModuleInstantiation to initialize the
This abstract operation performs the following steps:
"ambiguous"
, throw a "*"
, then"ambiguous"
, throw a "*namespace*"
, then"*"
, [[LocalName]]: With parameter module.
A Module Namespace Object is a module namespace exotic object that provides runtime property-based access to a module's exported bindings. There is no constructor function for Module Namespace Objects. Instead, such an object is created for each module that is imported by an
In addition to the properties specified in
The initial value of the @@toStringTag property is the String value "Module"
.
This property has the attributes { [[Writable]]: