This repository has been archived by the owner on Feb 15, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 6ad299a
Showing
3 changed files
with
696 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
This document specifies the extensions to the [ESTree ES6 AST][] types to | ||
support the "export-ns-from" proposal. | ||
|
||
|
||
# Modules | ||
|
||
## ExportNamedDeclaration | ||
|
||
```js | ||
extend interface ExportNamedDeclaration { | ||
specifiers: [ ExportSpecifier | ExportNamespaceSpecifier ]; | ||
} | ||
``` | ||
|
||
Extends the [ExportNamedDeclaration][], e.g., `export {foo} from "mod";` to | ||
allow a new type of specifier: *ExportNamespaceSpecifier*. | ||
|
||
_Note: When `source` is `null`, having `specifiers` include | ||
*ExportNamespaceSpecifier* results in an invalid state._ | ||
|
||
_Note: Having `specifiers` include more than one *ExportNamespaceSpecifier* | ||
results in an invalid state._ | ||
|
||
_Note: Having `specifiers` include both *ExportSpecifier* and | ||
*ExportNamespaceSpecifier* results in an invalid state._ | ||
|
||
|
||
## ExportNamespaceSpecifier | ||
|
||
```js | ||
interface ExportNamespaceSpecifier <: Node { | ||
type: "ExportNamespaceSpecifier"; | ||
exported: Identifier; | ||
} | ||
``` | ||
|
||
An exported binding `* as ns` in `export * as ns from "mod";`. The `exported` | ||
field refers to the name exported in this module. That name is bound to the | ||
ModuleNameSpace exotic object from the `source` of the parent *ExportNamedDeclaration*. | ||
|
||
|
||
[ESTree ES6 AST]: https://github.com/estree/estree/blob/master/es6.md | ||
[ExportNamedDeclaration]: https://github.com/estree/estree/blob/master/es6.md#exportnameddeclaration |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
# export-ns-from | ||
|
||
## Future ECMAScript Proposal | ||
|
||
**Stage:** 1 | ||
|
||
**Author:** Lee Byron | ||
|
||
**Specification:** [Spec.md](./Spec.md) | ||
|
||
**AST:** [ESTree.md](./ESTree.md) | ||
|
||
**Transpiler:** See Babel's `es7.exportExtensions` option. | ||
|
||
## Problem statement and rationale | ||
|
||
The `export ___ from "module"` statements are a very useful mechanism for | ||
building up "package" modules in a declarative way. In the ECMAScript 2015 spec, | ||
we can: | ||
|
||
* export through a single export with `export {x} from "mod"` | ||
* ...optionally renaming it with `export {x as v} from "mod"` | ||
* We can also spread all exports with `export * from "mod"`. | ||
|
||
These three export-from statements are easy to understand if you understand the | ||
semantics of the similar looking import statements. | ||
|
||
However there is an import statement which does not have corresponding | ||
export-from statement, exporting the ModuleNameSpace object as a named export. | ||
|
||
Example: | ||
|
||
```js | ||
export * as someIdentifier from "someModule"; | ||
``` | ||
|
||
|
||
### Current ECMAScript 2015 Modules: | ||
|
||
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";` | | | | ||
|
||
|
||
Export Statement Form | [[ModuleRequest]] | [[ImportName]] | [[LocalName]] | [[ExportName]] | ||
--------------------- | ----------------- | -------------- | ------------- | -------------- | ||
`export var v;` | **null** | **null** | `"v"` | `"v"` | ||
`export default function f(){};`| **null** | **null** | `"f"` | `"default"` | ||
`export default function(){};` | **null** | **null** | `"*default*"` | `"default"` | ||
`export default 42;` | **null** | **null** | `"*default*"` | `"default"` | ||
`export {x}`; | **null** | **null** | `"x"` | `"x"` | ||
`export {x as v}`; | **null** | **null** | `"x"` | `"v"` | ||
`export {x} from "mod"`; | `"mod"` | `"x"` | **null** | `"x"` | ||
`export {x as v} from "mod"`; | `"mod"` | `"x"` | **null** | `"v"` | ||
`export * from "mod"`; | `"mod"` | `"*"` | **null** | **null** | ||
|
||
|
||
### Proposed addition: | ||
|
||
Export Statement Form | [[ModuleRequest]] | [[ImportName]] | [[LocalName]] | [[ExportName]] | ||
--------------------- | ----------------- | -------------- | ------------- | -------------- | ||
`export * as ns from "mod";` | `"mod"` | `"*"` | **null** | `"ns"` | ||
|
||
|
||
### Symmetry between import and export | ||
|
||
There's a syntactic symmetry between the export-from statements and the import | ||
statements they resemble. There is also a semantic symmetry; where import | ||
creates a locally named binding, export-from creates an export entry. | ||
|
||
As an example: | ||
|
||
```js | ||
export {v} from "mod"; | ||
``` | ||
|
||
Is symmetric to: | ||
|
||
```js | ||
import {v} from "mod"; | ||
``` | ||
|
||
However, where importing `v` introduces a name in the local scope, export-from | ||
`v` does not alter the local scope, instead creating an export entry. | ||
|
||
The proposed addition follows this same symmetric pattern: | ||
|
||
**Exporting a namespace exotic object without altering local scope:** | ||
|
||
```js | ||
// proposed: | ||
export * as ns from "mod"; | ||
// symmetric to: | ||
import * as ns from "mod"; | ||
``` | ||
|
||
Using the terminology of [Table 40][] and [Table 42][] in ECMAScript 2015, the | ||
export-from form can be created from the symmetric import form by setting | ||
export-from's **[[ExportName]]** to import's **[[LocalName]]** and export-from's | ||
**[[LocalName]]** to **null**. | ||
|
||
[Table 40]: http://www.ecma-international.org/ecma-262/6.0/#table-40 | ||
[Table 42]: http://www.ecma-international.org/ecma-262/6.0/#table-42 | ||
|
||
#### Table showing symmetry | ||
|
||
Statement Form | [[ModuleRequest]] | [[ImportName]] | [[LocalName]] | [[ExportName]] | ||
-------------- | ----------------- | -------------- | -------------- | -------------- | ||
`import v from "mod";` | `"mod"` | `"default"` | `"v"` | | ||
`import {x} from "mod";` | `"mod"` | `"x"` | `"x"` | | ||
`export {x} from "mod";` | `"mod"` | `"x"` | **null** | `"x"` | ||
`import {x as v} from "mod";` | `"mod"` | `"x"` | `"v"` | | ||
`export {x as v} from "mod";` | `"mod"` | `"x"` | **null** | `"v"` | ||
`import * as ns from "mod";` | `"mod"` | `"*"` | `"ns"` | | ||
<ins>`export * as ns from "mod";`</ins> | `"mod"` | `"*"` | **null** | `"ns"` | ||
`export * from "mod";` | `"mod"` | `"*"` | **null** | **null** (many) |
Oops, something went wrong.