Skip to content
This repository has been archived by the owner on Feb 15, 2022. It is now read-only.

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
leebyron committed Mar 29, 2016
0 parents commit 6ad299a
Show file tree
Hide file tree
Showing 3 changed files with 696 additions and 0 deletions.
43 changes: 43 additions & 0 deletions ESTree.md
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
120 changes: 120 additions & 0 deletions README.md
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)
Loading

0 comments on commit 6ad299a

Please sign in to comment.