Skip to content

Commit da7c5ef

Browse files
authored
Merge pull request #8 from guybedford/module
Update for "module" field support
2 parents 4a407d1 + 57c2bd5 commit da7c5ef

File tree

1 file changed

+31
-24
lines changed

1 file changed

+31
-24
lines changed

README.md

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff 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
22

33
## Guiding Principles
44

55
- 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.
77
- Module resolution rules should be reasonably compatible with the module resolution rules used by browsers.
88
- The ability to import a legacy package is important for adoption.
99

1010
## Design Summary
1111

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.**
1313

1414
This ensures 100% backward-compatibility, while still allowing some freedom of design.
1515

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.**
1717

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.
1919

2020
**3. When `import`ing a file path, file extensions are not automatically appended.**
2121

@@ -25,10 +25,14 @@ The default resolution algorithm used by web browsers will not automatically app
2525

2626
This provides users with the ability to `import` from legacy packages.
2727

28-
**5. `require.import(modulePath)` synchronously imports an ES6 module.**
28+
**5. `import(modulePath)` asynchronously imports an ES module from CommonJS.**
2929

3030
This allows old-style modules to `import` from new-style modules.
3131

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+
3236
## Use Cases
3337

3438
### Existing modules
@@ -37,35 +41,35 @@ Since there is no change to the behavior of `require`, there is no change to the
3741

3842
### Supporting `import` for old-style packages
3943

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.
4145

42-
### Supporting `require` for ES6 packages
46+
### Supporting `require` for ES Module packages
4347

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:
4549

4650
```
4751
src/
48-
[ES6 modules]
52+
[ES modules]
4953
default.js -> src/default.js
5054
index.js
5155
```
5256

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:
5458

5559
```js
5660
// [index.js]
57-
module.exports = require.import('./src/default.js');
61+
module.exports = import('./src/default.js');
5862
```
5963

60-
### Distributing both transpiled and native ES6 modules
64+
### Distributing both transpiled and native ES modules
6165

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:
6367

6468
```
6569
lib/
6670
[Transpiled modules]
6771
src/
68-
[ES6 modules]
72+
[ES modules]
6973
index.js -> lib/index.js
7074
```
7175

@@ -75,7 +79,7 @@ Users that `require` the package will load the transpiled version of the code.
7579
lib/
7680
[Transpiled modules]
7781
src/
78-
[ES6 modules]
82+
[ES modules]
7983
index.js -> lib/index.js
8084
default.js -> src/index.js
8185
```
@@ -86,7 +90,7 @@ We might also want our transpiler to rename "default.js" source files to "index.
8690
lib/
8791
[Transpiled modules]
8892
src/
89-
[ES6 modules]
93+
[ES modules]
9094
index.js -> lib/index.js
9195
default.js -> src/default.js
9296
```
@@ -110,7 +114,7 @@ var someModule = require('./some-module');
110114
to:
111115

112116
```js
113-
var someModule = require.import('./some-module.js').default;
117+
var someModule = (await import('./some-module.js')).default;
114118
```
115119

116120
### Deep-linking into a package
@@ -133,10 +137,10 @@ bar/
133137
## Why "default.js"?
134138

135139
- "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.
137141
- Despite "default" being a common English word, "default.js" is not widely used as a file name.
138142

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.
140144

141145
As a filename, "default.js" was found 1968 times.
142146

@@ -149,7 +153,7 @@ When a user executes
149153
$ node my-module.js
150154
```
151155

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.
153157

154158
```sh
155159
$ node --module my-module.js
@@ -174,7 +178,7 @@ Loads _X_ from a module at path _Y_. _T_ is either "require" or "import".
174178

175179
1. If T is "import",
176180
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
178182
1. If extname(X) is ".json", parse X to a JavaScript Object. STOP
179183
1. If extname(X) is ".node", load X as binary addon. STOP
180184
1. THROW "not found"
@@ -188,8 +192,11 @@ Loads _X_ from a module at path _Y_. _T_ is either "require" or "import".
188192
### LOAD_AS_DIRECTORY(X, T)
189193

190194
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
193200
1. If X/package.json is a file,
194201
1. Parse X/package.json, and look for "main" field.
195202
1. let M = X + (json main field)

0 commit comments

Comments
 (0)