├── 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 |
--------------------------------------------------------------------------------