You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+31-24Lines changed: 31 additions & 24 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,21 +1,21 @@
1
-
# A Modest Proposal for ES6 Modules in Node.js
1
+
# A Modest Proposal for ES Modules in Node.js
2
2
3
3
## Guiding Principles
4
4
5
5
- The solution must be 100% backward-compatible.
6
-
- In the far future, developers should be able to write Node programs and libraries without knowledge of the CommonJS module system.
6
+
- In the future, developers should be able to write Node programs and libraries without knowledge of the CommonJS module system.
7
7
- Module resolution rules should be reasonably compatible with the module resolution rules used by browsers.
8
8
- The ability to import a legacy package is important for adoption.
9
9
10
10
## Design Summary
11
11
12
-
**1. There is no change to the behavior of `require`. It cannot be used to import ES6 modules.**
12
+
**1. There is no change to the behavior of `require`. It cannot be used to import ES modules.**
13
13
14
14
This ensures 100% backward-compatibility, while still allowing some freedom of design.
15
15
16
-
**2. The only folder entry point for ES6 modules is "default.js". "package.json" files are not used for resolving ES6 module paths.**
16
+
**2. Instead of "index.js", the entry point for ES modules is "default.js", or instead of a package.json "main", "module" is used.**
17
17
18
-
A distinct entry point file name ("default.js") allows us to detect when a user is attempting to import from a legacy package or a folder containing legacy modules.
18
+
A distinct entry point ("default.js") allows us to distinguish when a user is attempting to import from a legacy package or a folder containing CommonJS modules.
19
19
20
20
**3. When `import`ing a file path, file extensions are not automatically appended.**
21
21
@@ -25,10 +25,14 @@ The default resolution algorithm used by web browsers will not automatically app
25
25
26
26
This provides users with the ability to `import` from legacy packages.
27
27
28
-
**5. `require.import(modulePath)`synchronously imports an ES6 module.**
28
+
**5. `import(modulePath)`asynchronously imports an ES module from CommonJS.**
29
29
30
30
This allows old-style modules to `import` from new-style modules.
31
31
32
+
**6. Node will support a `--module` flag.**
33
+
34
+
This provides the context that the module being loaded is a module, where in future this could be set by default.
35
+
32
36
## Use Cases
33
37
34
38
### Existing modules
@@ -37,35 +41,35 @@ Since there is no change to the behavior of `require`, there is no change to the
37
41
38
42
### Supporting `import` for old-style packages
39
43
40
-
If a "default.js" file does not exist in the package root, then it will be loaded as an old-style module with no further changes. It just works.
44
+
If a "default.js" file or "module" main does not exist in the package root, then it will be loaded as an old-style module with no further changes. It just works.
41
45
42
-
### Supporting `require` for ES6 packages
46
+
### Supporting `require` for ES Module packages
43
47
44
-
Since `require` cannot be directly used to import ES6 modules, we need to provide an old-style "index.js" entry point if we want to allow consumers to `require` our package:
48
+
Since `require` cannot be directly used to import ES modules, we need to provide an old-style "index.js" entry point if we want to allow consumers to `require` our package:
45
49
46
50
```
47
51
src/
48
-
[ES6 modules]
52
+
[ES modules]
49
53
default.js -> src/default.js
50
54
index.js
51
55
```
52
56
53
-
The purpose of the "index.js" file will be to map the ES6 module into an old-style module and can be as simple as:
57
+
The purpose of the "index.js" file will be to map the ES module into an old-style module and can be as simple as:
### Distributing both transpiled and native ES6 modules
64
+
### Distributing both transpiled and native ES modules
61
65
62
-
In this usage scenario, a package is authored in ES6 modules and transpiled to old-style modules using a compiler like Babel. A typical directory layout for such a project is:
66
+
In this usage scenario, a package is authored in ES modules and transpiled to old-style modules using a compiler like Babel. A typical directory layout for such a project is:
63
67
64
68
```
65
69
lib/
66
70
[Transpiled modules]
67
71
src/
68
-
[ES6 modules]
72
+
[ES modules]
69
73
index.js -> lib/index.js
70
74
```
71
75
@@ -75,7 +79,7 @@ Users that `require` the package will load the transpiled version of the code.
75
79
lib/
76
80
[Transpiled modules]
77
81
src/
78
-
[ES6 modules]
82
+
[ES modules]
79
83
index.js -> lib/index.js
80
84
default.js -> src/index.js
81
85
```
@@ -86,7 +90,7 @@ We might also want our transpiler to rename "default.js" source files to "index.
86
90
lib/
87
91
[Transpiled modules]
88
92
src/
89
-
[ES6 modules]
93
+
[ES modules]
90
94
index.js -> lib/index.js
91
95
default.js -> src/default.js
92
96
```
@@ -110,7 +114,7 @@ var someModule = require('./some-module');
110
114
to:
111
115
112
116
```js
113
-
var someModule =require.import('./some-module.js').default;
117
+
var someModule =(awaitimport('./some-module.js')).default;
114
118
```
115
119
116
120
### Deep-linking into a package
@@ -133,10 +137,10 @@ bar/
133
137
## Why "default.js"?
134
138
135
139
- "default.html" is frequently used as a folder entry point for web servers.
136
-
- The word "default" has a special, and similar meaning in ES6 modules.
140
+
- The word "default" has a special, and similar meaning in ES modules.
137
141
- Despite "default" being a common English word, "default.js" is not widely used as a file name.
138
142
139
-
In a [search of all the filenames in the @latest NPM packages as of 2016-01-28](https://gist.github.com/bmeck/9b234011938cd9c1f552d41db97ad005), "default.js" was only found 23 times in a package root. Of these packages, 8 are using "default.js" as an ES6 module entry point already (they are published by @zenparsing, so no surprises there). The remaining 15 packages would need to be updated in order to allow `import`ing them from other ES6 modules.
143
+
In a [search of all the filenames in the @latest NPM packages as of 2016-01-28](https://gist.github.com/bmeck/9b234011938cd9c1f552d41db97ad005), "default.js" was only found 23 times in a package root. Of these packages, 8 are using "default.js" as an ES module entry point already (they are published by @zenparsing, so no surprises there). The remaining 15 packages would need to be updated in order to allow `import`ing them from other ES modules.
140
144
141
145
As a filename, "default.js" was found 1968 times.
142
146
@@ -149,7 +153,7 @@ When a user executes
149
153
$ node my-module.js
150
154
```
151
155
152
-
from the command line, there is absolutely no way for Node to tell whether "my-module.js" is a legacy CJS module or an ES6 module. Due to the need of this knowledge for various interactive scenarios such as the entry file being provided over STDIN, node will support a `--module` flag.
156
+
from the command line, there is absolutely no way for Node to tell whether "my-module.js" is a legacy CJS module or an ES module. Due to the need of this knowledge for various interactive scenarios such as the entry file being provided over STDIN, node will support a `--module` flag.
153
157
154
158
```sh
155
159
$ node --module my-module.js
@@ -174,7 +178,7 @@ Loads _X_ from a module at path _Y_. _T_ is either "require" or "import".
174
178
175
179
1. If T is "import",
176
180
1. If X is a file, then
177
-
1. If extname(X) is ".js", load X as ES6 module text. STOP
181
+
1. If extname(X) is ".js", load X as ES module text. STOP
178
182
1. If extname(X) is ".json", parse X to a JavaScript Object. STOP
179
183
1. If extname(X) is ".node", load X as binary addon. STOP
180
184
1. THROW "not found"
@@ -188,8 +192,11 @@ Loads _X_ from a module at path _Y_. _T_ is either "require" or "import".
188
192
### LOAD_AS_DIRECTORY(X, T)
189
193
190
194
1. If T is "import",
191
-
1. If X/default.js is a file, load X/default.js as ES6 module text. STOP
192
-
1. NOTE: If X/default.js is not a file, then fallback to legacy behavior
195
+
1. If X/default.js is a file, load X/default.js as ES module text. STOP
196
+
1. If X/package.json is a file,
197
+
1. Parse X/package.json, and look for "module" field.
198
+
1. load X/(json module field) as ES module text. STOP
199
+
1. NOTE: If neither of the above are a file, then fallback to legacy behavior
193
200
1. If X/package.json is a file,
194
201
1. Parse X/package.json, and look for "main" field.
0 commit comments