├── ESTree.md ├── README.md └── Spec.md /ESTree.md: -------------------------------------------------------------------------------- 1 | This document specifies the extensions to the [ESTree ES6 AST](https://github.com/estree/estree/blob/master/es6.md) 2 | types to support this module export extensions proposal. 3 | 4 | 5 | # Modules 6 | 7 | ## ExportNamedDeclaration 8 | 9 | ```js 10 | extend interface ExportNamedDeclaration { 11 | specifiers: [ ExportSpecifier | ExportDefaultSpecifier | ExportNamespaceSpecifier ]; 12 | } 13 | ``` 14 | 15 | Extends the [ExportNamedDeclaration](https://github.com/estree/estree/blob/master/es6.md#exportnameddeclaration), 16 | e.g., `export {foo} from "mod";` to allow two new types of specifiers: 17 | *ExportDefaultSpecifier* and *ExportNamespaceSpecifier*. 18 | 19 | _Note: When `source` is `null`, having `specifiers` include either 20 | *ExportDefaultSpecifier* or *ExportNamespaceSpecifier* results in an invalid state._ 21 | 22 | _Note: Having `specifiers` include more than one of either 23 | *ExportDefaultSpecifier* or *ExportNamespaceSpecifier* results in an invalid state._ 24 | 25 | _Note: Having `specifiers` include both *ExportNamespaceSpecifier* and 26 | *ExportSpecifier* results in an invalid state._ 27 | 28 | 29 | 30 | ## ExportDefaultSpecifier 31 | 32 | ```js 33 | interface ExportDefaultSpecifier <: Node { 34 | type: "ExportDefaultSpecifier"; 35 | exported: Identifier; 36 | } 37 | ``` 38 | 39 | An exported binding `foo` in `export foo from "mod";`. The `exported` field 40 | refers to the name exported in this module. That name is bound to the 41 | `"default"` export from the `source` of the parent *ExportNamedDeclaration*. 42 | 43 | 44 | ## ExportNamespaceSpecifier 45 | 46 | ```js 47 | interface ExportNamespaceSpecifier <: Node { 48 | type: "ExportNamespaceSpecifier"; 49 | exported: Identifier; 50 | } 51 | ``` 52 | 53 | An exported binding `* as ns` in `export * as ns from "mod";`. The `exported` 54 | field refers to the name exported in this module. That name is bound to the 55 | ModuleNameSpace exotic object from the `source` of the parent *ExportNamedDeclaration*. 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 |


3 | 4 | This spec has been withdrawn in favor of the equivalent micro-proposals: export ns from and export default from. 5 | 6 |


7 |

8 | 9 |





10 | 11 | 12 | # Additional export-from statements in ES7 13 | 14 | ## ES7 Proposal 15 | 16 | **Stage:** 1 17 | 18 | **Author:** Lee Byron 19 | 20 | **Specification:** [Spec.md](./Spec.md) 21 | 22 | **AST:** [ESTree.md](./ESTree.md) 23 | 24 | **Transpiler:** See Babel's `es7.exportExtensions` option. 25 | 26 | ## Problem statement and rationale 27 | 28 | The `export ___ from "module"` statements are a very useful mechanism for 29 | building up "package" modules in a declarative way. In the ES6 spec, we can: 30 | 31 | * export through a single export with `export {x} from "mod"` 32 | * ...optionally renaming it with `export {x as v} from "mod"` 33 | * We can also spread all exports with `export * from "mod"`. 34 | 35 | These three export-from statements are easy to understand if you understand the 36 | semantics of the similar looking import statements. 37 | 38 | However, there are other import statements which would have very useful 39 | export-from forms. 40 | 41 | * Exporting the ModuleNameSpace object as a named export: `export * as ns from "mod"` 42 | * Forwarding the *default* export of the referenced module 43 | as a named export of this module: `export v from "mod"` 44 | 45 | 46 | ### Current ES6 Modules: 47 | 48 | Import Statement Form | [[ModuleRequest]] | [[ImportName]] | [[LocalName]] 49 | --------------------- | ----------------- | -------------- | ------------- 50 | `import v from "mod";` | `"mod"` | `"default"` | `"v"` 51 | `import * as ns from "mod";` | `"mod"` | `"*"` | `"ns"` 52 | `import {x} from "mod";` | `"mod"` | `"x"` | `"x"` 53 | `import {x as v} from "mod";` | `"mod"` | `"x"` | `"v"` 54 | `import "mod";` | | | 55 | 56 | 57 | Export Statement Form | [[ModuleRequest]] | [[ImportName]] | [[LocalName]] | [[ExportName]] 58 | --------------------- | ----------------- | -------------- | ------------- | -------------- 59 | `export var v;` | **null** | **null** | `"v"` | `"v"` 60 | `export default function f(){};`| **null** | **null** | `"f"` | `"default"` 61 | `export default function(){};` | **null** | **null** | `"*default*"` | `"default"` 62 | `export default 42;` | **null** | **null** | `"*default*"` | `"default"` 63 | `export {x}`; | **null** | **null** | `"x"` | `"x"` 64 | `export {x as v}`; | **null** | **null** | `"x"` | `"v"` 65 | `export {x} from "mod"`; | `"mod"` | `"x"` | **null** | `"x"` 66 | `export {x as v} from "mod"`; | `"mod"` | `"x"` | **null** | `"v"` 67 | `export * from "mod"`; | `"mod"` | `"*"` | **null** | **null** 68 | 69 | 70 | ### Proposed additions: 71 | 72 | Export Statement Form | [[ModuleRequest]] | [[ImportName]] | [[LocalName]] | [[ExportName]] 73 | --------------------- | ----------------- | -------------- | ------------- | -------------- 74 | `export * as ns from "mod";` | `"mod"` | `"*"` | **null** | `"ns"` 75 | `export v from "mod";` | `"mod"` | `"default"` | **null** | `"v"` 76 | 77 | 78 | ### Symmetry between import and export 79 | 80 | There's a syntactic symmetry between the export-from statements and the import 81 | statements they resemble. There is also a semantic symmetry; where import 82 | creates a locally named binding, export-from creates an export entry. 83 | 84 | As an example: 85 | 86 | ```js 87 | export {v} from "mod"; 88 | ``` 89 | 90 | Is symmetric to: 91 | 92 | ```js 93 | import {v} from "mod"; 94 | ``` 95 | 96 | However, where importing `v` introduces a name in the local scope, export-from 97 | `v` does not alter the local scope, instead creating an export entry. 98 | 99 | The two proposed additions follow this same symmetric pattern: 100 | 101 | **Exporting a namespace exotic object without altering local scope:** 102 | 103 | ```js 104 | // proposed: 105 | export * as ns from "mod"; 106 | // symmetric to: 107 | import * as ns from "mod"; 108 | ``` 109 | 110 | **Re-exporting a module's default export with a name:** 111 | 112 | ```js 113 | // proposed: 114 | export v from "mod"; 115 | // symmetric to: 116 | import v from "mod"; 117 | ``` 118 | 119 | Using the terminology of Table 42 in ECMA-262 v6 RC4, the export-from form can 120 | be created from the symmetric import form by setting export-from's 121 | **[[ExportName]]** to import's **[[LocalName]]** and export-from's 122 | **[[LocalName]]** to **null**. 123 | 124 | #### Table showing symmetry 125 | 126 | Statement Form | [[ModuleRequest]] | [[ImportName]] | [[LocalName]] | [[ExportName]] 127 | -------------- | ----------------- | -------------- | -------------- | -------------- 128 | `import v from "mod";` | `"mod"` | `"default"` | `"v"` | 129 | `export v from "mod";` | `"mod"` | `"default"` | **null** | `"v"` 130 | `import * as ns from "mod";` | `"mod"` | `"*"` | `"ns"` | 131 | `export * as ns from "mod";` | `"mod"` | `"*"` | **null** | `"ns"` 132 | `import {x} from "mod";` | `"mod"` | `"x"` | `"x"` | 133 | `export {x} from "mod";` | `"mod"` | `"x"` | **null** | `"x"` 134 | `import {x as v} from "mod";` | `"mod"` | `"x"` | `"v"` | 135 | `export {x as v} from "mod";` | `"mod"` | `"x"` | **null** | `"v"` 136 | `import * from "mod"` | `"mod"` | **null** | **null** (many)| 137 | `export * from "mod";` | `"mod"` | `"*"` | **null** | **null** (many) 138 | 139 | > Note: `import * from "mod"` is only included for illustrative purposes. It is 140 | > not in existing spec or part of this proposal. 141 | 142 | ### Compound export-from statements 143 | 144 | This proposal also includes the symmetric export-from for the compound imports: 145 | 146 | ```js 147 | // proposed 148 | export v, {x, y as w} from "mod" 149 | // symmetric to 150 | import v, {x, y as w} from "mod" 151 | ``` 152 | 153 | As well as 154 | 155 | ```js 156 | // proposed 157 | export v, * as ns from "mod" 158 | // symmetric to 159 | import v, * as ns from "mod" 160 | ``` 161 | 162 | ### Export default from 163 | 164 | One use case is to take the default export of an inner module and export it as 165 | the default export of the outer module. This is written as: 166 | 167 | ```js 168 | export default from "mod"; 169 | ``` 170 | 171 | This is *not* additional syntax above what's already proposed. In fact, 172 | this is just the `export v from "mod"` syntax where the export name happens to 173 | be `default`. This nicely mirrors the other `export default ____` forms in both 174 | syntax and semantics without requiring additional specification. An alteration 175 | to an existing lookahead restriction is necessary for supporting this case. 176 | -------------------------------------------------------------------------------- /Spec.md: -------------------------------------------------------------------------------- 1 | > Note: This document is written as a delta against the ES6 RC4 2 | > specification. Headers illustrate the location in the specification. The use 3 | > of ins and del illustrate addition and removal to 4 | > existing sections. Shaded blocks followed by content indicates an existing 5 | > portion of content to be replaced by the followed content. Unadorned content 6 | > is new or contextually unalterned. Omitted content should be assumed 7 | > irrelevant to this proposal unless otherwise noted. 8 | 9 | --- 10 | 11 | # 15 ECMAScript Language: Scripts and Modules 12 | 13 | ## 15.2 Modules 14 | 15 | ### 15.2.1 Module Semantics 16 | 17 | #### 15.2.1.15 Source Text Module Records 18 | 19 | **Table 42 (Informative) — Export Forms Mappings to ExportEntry Records** 20 | 21 | Export Statement Form | [[ExportName]] | [[ModuleRequest]] | [[ImportName]] | [[LocalName]] 22 | --------------------- | -------------- | ----------------- | -------------- | ------------- 23 | `export var v;` | `"v"` | **null** | **null** | `"v"` 24 | `export default function f(){};` | `"default"` | **null** | **null** | `"f"` 25 | `export default function(){};` | `"default"` | **null** | **null** | `"*default*"` 26 | `export default 42;` | `"default"` | **null** | **null** | `"*default*"` 27 | `export {x};` | `"x"` | **null** | **null** | `"x"` 28 | `export {v as x};` | `"x"` | **null** | **null** | `"v"` 29 | `export v from "mod";` | `"v"` | `"mod"`| `"default"`| **null** 30 | `export * as ns from "mod";` | `"ns"` | `"mod"`| `"*"` | **null** 31 | `export {x} from "mod";` | `"x"` | `"mod"` | `"x"` | **null** 32 | `export {v as x} from "mod";` | `"x"` | `"mod"` | `"v"` | **null** 33 | `export * from "mod";` | **null** | `"mod"` | `"*"` | **null** 34 | 35 | 36 | ### 15.2.3 Exports 37 | 38 | **Syntax** 39 | 40 | > Note: *ExportClause* has been renamed to *NamedExports* for clarity 41 | > and symmetry with *NamedImports*. This rename should be reflected throughout 42 | > the entire ECMA spec document, which this delta document does not fully cover. 43 | 44 | *ExportDeclaration* : 45 | - `export` `*` *FromClause* `;` 46 | - `export` *ExportClause* *FromClause* `;` 47 | - `export` *ExportClause* `;` 48 | - `export` *ExportFromClause* *FromClause* `;` 49 | - `export` *NamedExports* `;` 50 | - `export` *VariableStatement* 51 | - `export` *Declaration* 52 | - `export` `default` *HoistableDeclaration*[Default] 53 | - `export` `default` *ClassDeclaration*[Default] 54 | - `export` `default` [lookahead ∉ {`function`, `class`, `from`}] *AssignmentExpression*[In] `;` 55 | 56 | 57 | *ExportFromClause* : 58 | - `*` 59 | - *ExportedDefaultBinding* 60 | - *NameSpaceExport* 61 | - *NamedExports* 62 | - *ExportedDefaultBinding* `,` *NameSpaceExport* 63 | - *ExportedDefaultBinding* `,` *NamedExports* 64 | 65 | *ExportedDefaultBinding* : 66 | - *IdentifierName* 67 | 68 | *NameSpaceExport* : 69 | - `*` `as` *IdentifierName* 70 | 71 | *ExportClauseNamedExports* : 72 | 73 | - `{` `}` 74 | - `{` *ExportsList* `}` 75 | - `{` *ExportsList* `,` `}` 76 | 77 | *ExportsList* : 78 | - *ExportSpecifier* 79 | - *ExportsList* `,` *ExportSpecifier* 80 | 81 | *ExportSpecifier* : 82 | - *IdentifierName* 83 | - *IdentifierName* `as` *IdentifierName* 84 | 85 | 86 | #### 15.2.3.2 Static Semantics: BoundNames 87 | 88 | *ExportDeclaration* : 89 | - `export` `*` *FromClause* `;` 90 | - `export` *ExportClause* *FromClause* `;` 91 | - `export` *ExportClause* `;` 92 | - `export` *ExportFromClause* *FromClause* `;` 93 | - `export` *NamedExports* `;` 94 | 95 | 1. Return a new empty List. 96 | 97 | 98 | #### 15.2.3.3 Static Semantics: ExportedBindings 99 | 100 | *ExportDeclaration* : 101 | - `export` *ExportClause* *FromClause* `;` 102 | - `export` `*` *FromClause* `;` 103 | - `export` *ExportFromClause* *FromClause* `;` 104 | 105 | 1. Return a new empty List. 106 | 107 | 108 | #### 15.2.3.4 Static Semantics: ExportedNames 109 | 110 | > *ExportDeclaration* : `export` `*` *FromClause* `;` 111 | > 112 | > 1. Return a new empty List. 113 | > 114 | > *ExportDeclaration* : 115 | > - `export` *ExportClause* *FromClause* `;` 116 | > - `export` *ExportClause* `;` 117 | > 118 | > 1. Return the ExportedNames of *ExportClause*. 119 | 120 | *ExportDeclaration* : `export` *ExportFromClause* *FromClause* `;` 121 | 122 | 1. Return the ExportedNames of *ExportFromClause*. 123 | 124 | *ExportFromClause* : `*` 125 | 126 | 1. Return a new empty List. 127 | 128 | *ExportFromClause* : *ExportedDefaultBinding* `,` *NameSpaceExport* 129 | 130 | 1. Let *names* be the ExportedNames of *ExportedDefaultBinding*. 131 | 2. Append to *names* the elements of the ExportedNames of *NameSpaceExport*. 132 | 3. Return *names*. 133 | 134 | *ExportFromClause* : *ExportedDefaultBinding* `,` *NamedExports* 135 | 136 | 1. Let *names* be the ExportedNames of *ExportedDefaultBinding*. 137 | 2. Append to *names* the elements of the ExportedNames of *NamedExports*. 138 | 3. Return *names*. 139 | 140 | 141 | #### 15.2.3.5 Static Semantics: ExportEntries 142 | 143 | > *ExportDeclaration* : `export` `*` *FromClause* `;` 144 | > 145 | > 1. Let *module* be the sole element of ModuleRequests of *FromClause*. 146 | > 2. Let *entry* be the Record {[[ModuleRequest]]: *module*, [[ImportName]]: **"*"**, [[LocalName]]: **null**, [[ExportName]]: **null** }. 147 | > 3. Return a new List containing *entry*. 148 | > 149 | > *ExportDeclaration* : `export` *ExportClause* *FromClause* `;` 150 | > 151 | > 1. Let *module* be the sole element of ModuleRequests of *FromClause*. 152 | > 2. Return ExportEntriesForModule of *ExportClause* with argument *module*. 153 | 154 | *ExportDeclaration* : `export` *ExportFromClause* *FromClause* `;` 155 | 156 | 1. Let *module* be the sole element of ModuleRequests of *FromClause*. 157 | 2. Return ExportEntriesForModule of *ExportFromClause* with argument *module*. 158 | 159 | 160 | #### 15.2.3.6 Static Semantics: ExportEntriesForModule 161 | 162 | *ExportFromClause* : `*` 163 | 164 | 1. Return a new List containing the Record {[[ModuleRequest]]: *module*, [[ImportName]]: **"*"**, [[LocalName]]: **null**, [[ExportName]]: **null** }. 165 | 166 | *ExportFromClause* : *ExportedDefaultBinding* `,` *NameSpaceExport* 167 | 168 | 1. Let *entries* be ExportEntriesForModule of *ExportedDefaultBinding* with argument *module*. 169 | 2. Append to *entries* the elements of the ExportEntriesForModule of *NameSpaceExport* with argument *module*. 170 | 3. Return *entries*. 171 | 172 | *ExportFromClause* : *ExportedDefaultBinding* `,` *NamedExports* 173 | 174 | 1. Let *entries* be ExportEntriesForModule of *ExportedDefaultBinding* with argument *module*. 175 | 2. Append to *entries* the elements of the ExportEntriesForModule of *NamedExports* with argument *module*. 176 | 3. Return *entries*. 177 | 178 | *ExportedDefaultBinding* : *IdentifierName* 179 | 180 | 1. Let *exportName* be the StringValue of *IdentifierName*. 181 | 2. Return a new List containing the Record {[[ModuleRequest]]: *module*, [[ImportName]]: **"default"**, [[LocalName]]: **null**, [[ExportName]]: *exportName* }. 182 | 183 | *NameSpaceExport* : `*` `as` *IdentifierName* 184 | 185 | 1. Let *exportName* be the StringValue of *IdentifierName*. 186 | 2. Return a new List containing the Record {[[ModuleRequest]]: *module*, [[ImportName]]: **"*"**, [[LocalName]]: **null**, [[ExportName]]: *exportName* }. 187 | 188 | 189 | #### 15.2.3.7 Static Semantics: IsConstantDeclaration 190 | 191 | *ExportDeclaration* : 192 | - `export` `*` *FromClause* `;` 193 | - `export` *ExportClause* *FromClause* `;` 194 | - `export` *ExportClause* `;` 195 | - `export` *ExportFromClause* *FromClause* `;` 196 | - `export` *NamedExports* `;` 197 | - `export` `default` *AssignmentExpression* `;` 198 | 199 | 1. Return false. 200 | 201 | 202 | #### 15.2.3.8 Static Semantics: LexicallyScopedDeclarations 203 | 204 | *ExportDeclaration* : 205 | - `export` `*` *FromClause* `;` 206 | - `export` *ExportClause* *FromClause* `;` 207 | - `export` *ExportClause* `;` 208 | - `export` *ExportFromClause* *FromClause* `;` 209 | - `export` *NamedExports* `;` 210 | - `export` *VariableStatement* 211 | 212 | 1. Return a new empty List. 213 | 214 | 215 | #### 15.2.3.9 Static Semantics: ModuleRequests 216 | 217 | *ExportDeclaration* : 218 | - `export` `*` *FromClause* `;` 219 | - `export` *ExportClause* *FromClause* `;` 220 | - `export` *ExportFromClause* *FromClause* `;` 221 | 222 | 1. Return the ModuleRequests of *FromClause*. 223 | 224 | 225 | #### 15.2.3.11 Runtime Semantics: Evaluation 226 | 227 | *ExportDeclaration* : 228 | - `export` `*` *FromClause* `;` 229 | - `export` *ExportClause* *FromClause* `;` 230 | - `export` *ExportClause* `;` 231 | - `export` *ExportFromClause* *FromClause* `;` 232 | - `export` *NamedExports* `;` 233 | 234 | 1. Return NormalCompletion(empty). 235 | 236 | 237 | # Annex A (informative) Grammar Summary 238 | 239 | ## A.5 Scripts and Modules 240 | 241 | > Note: See alterations in 15.2.3. 242 | --------------------------------------------------------------------------------