Skip to content
This repository was archived by the owner on Apr 16, 2020. It is now read-only.

Commit b1da781

Browse files
committed
esm: replace --entry-type with --input-type, which applies only to string input
1 parent 0a5a762 commit b1da781

File tree

17 files changed

+119
-129
lines changed

17 files changed

+119
-129
lines changed

doc/api/cli.md

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -131,19 +131,6 @@ conjunction with native stack and other runtime environment data.
131131
added: v6.0.0
132132
-->
133133

134-
### `--entry-type=type`
135-
<!-- YAML
136-
added: REPLACEME
137-
-->
138-
139-
Used with `--experimental-modules`, this configures Node.js to interpret the
140-
initial entry point as CommonJS or as an ES module.
141-
142-
Valid values are `"commonjs"` and `"module"`. The default is to infer from
143-
the file extension and the `"type"` field in the nearest parent `package.json`.
144-
145-
Works for executing a file as well as `--eval`, `--print`, `STDIN`.
146-
147134
Enable FIPS-compliant crypto at startup. (Requires Node.js to be built with
148135
`./configure --openssl-fips`.)
149136

@@ -253,6 +240,17 @@ added: v0.11.15
253240

254241
Specify ICU data load path. (Overrides `NODE_ICU_DATA`.)
255242

243+
### `--input-type=type`
244+
<!-- YAML
245+
added: REPLACEME
246+
-->
247+
248+
Used with `--experimental-modules`, this configures Node.js to interpret string
249+
input as CommonJS or as an ES module. String input is input via `--eval`,
250+
`--print`, or `STDIN`.
251+
252+
Valid values are `"commonjs"` and `"module"`. The default is `"commonjs"`.
253+
256254
### `--inspect-brk[=[host:]port]`
257255
<!-- YAML
258256
added: v7.6.0

doc/api/errors.md

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -864,18 +864,6 @@ provided.
864864
Encoding provided to `TextDecoder()` API was not one of the
865865
[WHATWG Supported Encodings][].
866866

867-
<a id="ERR_ENTRY_TYPE_MISMATCH"></a>
868-
#### ERR_ENTRY_TYPE_MISMATCH
869-
870-
> Stability: 1 - Experimental
871-
872-
The `--entry-type=commonjs` flag was used to attempt to execute an `.mjs` file
873-
or a `.js` file where the nearest parent `package.json` contains
874-
`"type": "module"`; or
875-
the `--entry-type=module` flag was used to attempt to execute a `.cjs` file or
876-
a `.js` file where the nearest parent `package.json` either lacks a `"type"`
877-
field or contains `"type": "commonjs"`.
878-
879867
<a id="ERR_FALSY_VALUE_REJECTION"></a>
880868
### ERR_FALSY_VALUE_REJECTION
881869

@@ -1176,6 +1164,14 @@ is set for the `Http2Stream`.
11761164
An option pair is incompatible with each other and can not be used at the same
11771165
time.
11781166

1167+
<a id="ERR_INPUT_TYPE_NOT_ALLOWED"></a>
1168+
#### ERR_INPUT_TYPE_NOT_ALLOWED
1169+
1170+
> Stability: 1 - Experimental
1171+
1172+
The `--input-type` flag was used to attempt to execute a file. This flag can
1173+
only be used with input via `--eval`, `--print` or `STDIN`.
1174+
11791175
<a id="ERR_INSPECTOR_ALREADY_CONNECTED"></a>
11801176
### ERR_INSPECTOR_ALREADY_CONNECTED
11811177

@@ -2222,6 +2218,18 @@ closed.
22222218
These errors have never been released, but had been present on master between
22232219
releases.
22242220

2221+
<a id="ERR_ENTRY_TYPE_MISMATCH"></a>
2222+
#### ERR_ENTRY_TYPE_MISMATCH
2223+
2224+
> Stability: 1 - Experimental
2225+
2226+
The `--entry-type=commonjs` flag was used to attempt to execute an `.mjs` file
2227+
or a `.js` file where the nearest parent `package.json` contains
2228+
`"type": "module"`; or
2229+
the `--entry-type=module` flag was used to attempt to execute a `.cjs` file or
2230+
a `.js` file where the nearest parent `package.json` either lacks a `"type"`
2231+
field or contains `"type": "commonjs"`.
2232+
22252233
<a id="ERR_FS_WATCHER_ALREADY_STARTED"></a>
22262234
#### ERR_FS_WATCHER_ALREADY_STARTED
22272235

doc/api/esm.md

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -30,45 +30,37 @@ specifier resolution, and default behavior.
3030
The `--experimental-modules` flag can be used to enable support for
3131
ECMAScript modules (ES modules).
3232

33-
## Running Node.js with an ECMAScript Module
33+
Once enabled, Node.js will treat the following as ES modules when passed to
34+
`node` as the initial input, or when referenced by `import` statements within
35+
ES module code:
3436

35-
There are a few ways to start Node.js with an ES module as its input.
37+
- Files ending in `.mjs`.
3638

37-
### Initial entry point with an <code>.mjs</code> extension
39+
- Files ending in `.js`, or extensionless files, when the nearest parent
40+
`package.json` file contains a top-level field `"type"` with a value of
41+
`"module"`.
3842

39-
A file ending with `.mjs` passed to Node.js as an initial entry point will be
40-
loaded as an ES module.
43+
- Strings passed in as an argument to `--eval` or `--print`, or piped to
44+
`node` via `STDIN`, with the flag `--input-type=module`.
4145

42-
```sh
43-
node --experimental-modules my-app.mjs
44-
```
45-
46-
### <code>--entry-type=module</code> flag
47-
48-
Files ending with `.js` or `.mjs`, or lacking any extension,
49-
will be loaded as ES modules when the `--entry-type=module` flag is set.
50-
51-
```sh
52-
node --experimental-modules --entry-type=module my-app.js
53-
```
46+
Node.js will treat as CommonJS all other forms of input, such as `.js` files
47+
where the nearest parent `package.json` file contains no top-level `"type"`
48+
field, or string input without the flag `--input-type`. This behavior is to
49+
preserve backward compatibility. However, now that Node.js supports both
50+
CommonJS and ES modules, it is best to be explicit whenever possible. Node.js
51+
will treat the following as CommonJS when passed to `node` as the initial input,
52+
or when referenced by `import` statements within ES module code:
5453

55-
For completeness there is also `--entry-type=commonjs`, for explicitly running
56-
a `.js` file as CommonJS. This is the default behavior if `--entry-type` is
57-
unspecified.
54+
- Files ending in `.cjs`.
5855

59-
The `--entry-type=module` flag can also be used to configure Node.js to treat
60-
as an ES module input sent in via `--eval` or `--print` (or `-e` or `-p`) or
61-
piped to Node.js via `STDIN`.
56+
- Files ending in `.js`, or extensionless files, when the nearest parent
57+
`package.json` file contains a top-level field `"type"` with a value of
58+
`"commonjs"`.
6259

63-
```sh
64-
node --experimental-modules --entry-type=module --eval \
65-
"import { sep } from 'path'; console.log(sep);"
66-
67-
echo "import { sep } from 'path'; console.log(sep);" | \
68-
node --experimental-modules --entry-type=module
69-
```
60+
- Strings passed in as an argument to `--eval` or `--print`, or piped to
61+
`node` via `STDIN`, with the flag `--input-type=commonjs`.
7062

71-
### <code>package.json</code> <code>"type"</code> field
63+
## <code>package.json</code> <code>"type"</code> field
7264

7365
Files ending with `.js` or `.mjs`, or lacking any extension,
7466
will be loaded as ES modules when the nearest parent `package.json` file
@@ -97,6 +89,14 @@ If the volume root is reached and no `package.json` is found,
9789
Node.js defers to the default, a `package.json` with no `"type"`
9890
field.
9991

92+
`import` statements of `.js` and extensionless files are treated as ES modules
93+
if the nearest parent `package.json` contains `"type": "module"`.
94+
95+
```js
96+
// my-app.js, part of the same example as above
97+
import './startup.js'; // Loaded as ES module because of package.json
98+
```
99+
100100
## Package Scope and File Extensions
101101

102102
A folder containing a `package.json` file, and all subfolders below that
@@ -156,6 +156,24 @@ package scope:
156156
extension (since both `.js` and `.cjs` files are treated as CommonJS within a
157157
`"commonjs"` package scope).
158158

159+
## <code>--input-type</code> flag
160+
161+
Strings passed in as an argument to `--eval` or `--print` (or `-e` or `-p`), or
162+
piped to `node` via `STDIN`, will be treated as ES modules when the
163+
`--input-type=module` flag is set.
164+
165+
```sh
166+
node --experimental-modules --input-type=module --eval \
167+
"import { sep } from 'path'; console.log(sep);"
168+
169+
echo "import { sep } from 'path'; console.log(sep);" | \
170+
node --experimental-modules --input-type=module
171+
```
172+
173+
For completeness there is also `--input-type=commonjs`, for explicitly running
174+
string input as CommonJS. This is the default behavior if `--input-type` is
175+
unspecified.
176+
159177
## Package Entry Points
160178

161179
The `package.json` `"main"` field defines the entry point for a package,

doc/node.1

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,6 @@ Enable FIPS-compliant crypto at startup.
119119
Requires Node.js to be built with
120120
.Sy ./configure --openssl-fips .
121121
.
122-
.It Fl -entry-type Ns = Ns Ar type
123-
Set the top-level module resolution type.
124-
.
125122
.It Fl -es-module-specifier-resolution
126123
Select extension resolution algorithm for ES Modules; either 'explicit' (default) or 'node'
127124
.
@@ -167,6 +164,9 @@ Specify ICU data load path.
167164
Overrides
168165
.Ev NODE_ICU_DATA .
169166
.
167+
.It Fl -input-type Ns = Ns Ar type
168+
Set the module resolution type for input via --eval, --print or STDIN.
169+
.
170170
.It Fl -inspect-brk Ns = Ns Ar [host:]port
171171
Activate inspector on
172172
.Ar host:port

lib/internal/errors.js

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -678,24 +678,6 @@ E('ERR_ENCODING_INVALID_ENCODED_DATA', function(encoding, ret) {
678678
}, TypeError);
679679
E('ERR_ENCODING_NOT_SUPPORTED', 'The "%s" encoding is not supported',
680680
RangeError);
681-
E('ERR_ENTRY_TYPE_MISMATCH', (filename, ext, typeFlag, conflict) => {
682-
const typeString =
683-
typeFlag === 'module' ? '--entry-type=module' : '--entry-type=commonjs';
684-
// --entry-type mismatches file extension
685-
if (conflict === 'extension') {
686-
return `Extension ${ext} is not supported for ` +
687-
`${typeString} loading ${filename}`;
688-
}
689-
assert(
690-
conflict === 'scope',
691-
'"conflict" value unknown. Set this argument to "extension" or "scope"'
692-
);
693-
// --entry-type mismatches package.json "type"
694-
return `Cannot use ${typeString} because nearest parent package.json ` +
695-
((typeFlag === 'module') ?
696-
'includes "type": "commonjs"' : 'includes "type": "module",') +
697-
` which controls the type to use for ${filename}`;
698-
}, TypeError);
699681
E('ERR_FALSY_VALUE_REJECTION', function(reason) {
700682
this.reason = reason;
701683
return 'Promise was rejected with falsy value';
@@ -808,6 +790,8 @@ E('ERR_HTTP_TRAILER_INVALID',
808790
'Trailers are invalid with this transfer encoding', Error);
809791
E('ERR_INCOMPATIBLE_OPTION_PAIR',
810792
'Option "%s" can not be used in combination with option "%s"', TypeError);
793+
E('ERR_INPUT_TYPE_NOT_ALLOWED', '--input-type can only be used with string ' +
794+
'input via --eval, --print, or STDIN', Error);
811795
E('ERR_INSPECTOR_ALREADY_CONNECTED', '%s is already connected', Error);
812796
E('ERR_INSPECTOR_CLOSED', 'Session was closed', Error);
813797
E('ERR_INSPECTOR_COMMAND', 'Inspector error %d: %s', Error);

lib/internal/main/check_syntax.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ function checkSyntax(source, filename) {
6161
if (experimentalModules) {
6262
let isModule = false;
6363
if (filename === '[stdin]' || filename === '[eval]') {
64-
isModule = getOptionValue('--entry-type') === 'module';
64+
isModule = getOptionValue('--input-type') === 'module';
6565
} else {
6666
const resolve = require('internal/modules/esm/default_resolve');
6767
const { format } = resolve(pathToFileURL(filename).toString());

lib/internal/main/eval_stdin.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ markBootstrapComplete();
1717

1818
readStdin((code) => {
1919
process._eval = code;
20-
if (require('internal/options').getOptionValue('--entry-type') === 'module')
20+
if (require('internal/options').getOptionValue('--input-type') === 'module')
2121
evalModule(process._eval);
2222
else
2323
evalScript('[stdin]', process._eval, process._breakFirstLine);

lib/internal/main/eval_string.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const source = getOptionValue('--eval');
1414
prepareMainThreadExecution();
1515
addBuiltinLibsToObject(global);
1616
markBootstrapComplete();
17-
if (getOptionValue('--entry-type') === 'module')
17+
if (getOptionValue('--input-type') === 'module')
1818
evalModule(source);
1919
else
2020
evalScript('[eval]', source, process._breakFirstLine);

lib/internal/main/repl.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ const {
1313

1414
prepareMainThreadExecution();
1515

16-
// --entry-type flag not supported in REPL
17-
if (require('internal/options').getOptionValue('--entry-type')) {
18-
console.error('Cannot specify --entry-type for REPL');
19-
process.exit(1);
16+
// --input-type flag not supported in REPL
17+
if (require('internal/options').getOptionValue('--input-type')) {
18+
const { ERR_INPUT_TYPE_NOT_ALLOWED } = require('internal/errors').codes;
19+
// Cannot specify --input-type for REPL.
20+
throw new ERR_INPUT_TYPE_NOT_ALLOWED();
2021
}
2122

2223
const cliRepl = require('internal/repl');

lib/internal/modules/esm/default_resolve.js

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ const { getOptionValue } = require('internal/options');
99
const preserveSymlinks = getOptionValue('--preserve-symlinks');
1010
const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main');
1111
const experimentalJsonModules = getOptionValue('--experimental-json-modules');
12-
const typeFlag = getOptionValue('--entry-type');
12+
const typeFlag = getOptionValue('--input-type');
1313

1414
const { resolve: moduleWrapResolve,
1515
getPackageType } = internalBinding('module_wrap');
1616
const { pathToFileURL, fileURLToPath } = require('internal/url');
17-
const { ERR_ENTRY_TYPE_MISMATCH,
17+
const { ERR_INPUT_TYPE_NOT_ALLOWED,
1818
ERR_UNKNOWN_FILE_EXTENSION } = require('internal/errors').codes;
1919

2020
const {
@@ -25,7 +25,7 @@ const {
2525
const realpathCache = new SafeMap();
2626

2727
// const TYPE_NONE = 0;
28-
const TYPE_COMMONJS = 1;
28+
// const TYPE_COMMONJS = 1;
2929
const TYPE_MODULE = 2;
3030

3131
const extensionFormatMap = {
@@ -86,26 +86,16 @@ function resolve(specifier, parentURL) {
8686
let format = extMap[ext];
8787

8888
if (isMain && typeFlag) {
89-
// Conflict between explicit extension (.mjs, .cjs) and --entry-type
90-
if (ext === '.cjs' && typeFlag === 'module' ||
91-
ext === '.mjs' && typeFlag === 'commonjs') {
92-
throw new ERR_ENTRY_TYPE_MISMATCH(
93-
fileURLToPath(url), ext, typeFlag, 'extension');
94-
}
95-
96-
// Conflict between package scope type and --entry-type
97-
if (ext === '.js') {
98-
if (type === TYPE_MODULE && typeFlag === 'commonjs' ||
99-
type === TYPE_COMMONJS && typeFlag === 'module') {
100-
throw new ERR_ENTRY_TYPE_MISMATCH(
101-
fileURLToPath(url), ext, typeFlag, 'scope');
102-
}
103-
}
89+
// This is the initial entry point to the program, and --input-type has
90+
// been passed as an option; but --input-type can only be used with
91+
// --eval, --print or STDIN string input. It is not allowed with file
92+
// input, to avoid user confusion over how expansive the effect of the
93+
// flag should be (i.e. entry point only, package scope surrounding the
94+
// entry point, etc.).
95+
throw new ERR_INPUT_TYPE_NOT_ALLOWED();
10496
}
10597
if (!format) {
106-
if (isMain && typeFlag)
107-
format = typeFlag;
108-
else if (isMain)
98+
if (isMain)
10999
format = type === TYPE_MODULE ? 'module' : 'commonjs';
110100
else
111101
throw new ERR_UNKNOWN_FILE_EXTENSION(fileURLToPath(url),

src/node_options.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,11 @@ void EnvironmentOptions::CheckOptions(std::vector<std::string>* errors) {
109109

110110
if (!module_type.empty()) {
111111
if (!experimental_modules) {
112-
errors->push_back("--entry-type requires "
112+
errors->push_back("--input-type requires "
113113
"--experimental-modules to be enabled");
114114
}
115115
if (module_type != "commonjs" && module_type != "module") {
116-
errors->push_back("--entry-type must \"module\" or \"commonjs\"");
116+
errors->push_back("--input-type must \"module\" or \"commonjs\"");
117117
}
118118
}
119119

@@ -338,8 +338,8 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
338338
"show stack traces on process warnings",
339339
&EnvironmentOptions::trace_warnings,
340340
kAllowedInEnvironment);
341-
AddOption("--entry-type",
342-
"set module type name of the entry point",
341+
AddOption("--input-type",
342+
"set module type for string input",
343343
&EnvironmentOptions::module_type,
344344
kAllowedInEnvironment);
345345

test/es-module/test-esm-no-extension.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@ const fixtures = require('../common/fixtures');
55
const { spawn } = require('child_process');
66
const assert = require('assert');
77

8-
const entry = fixtures.path('/es-modules/noext-esm');
8+
const entry = fixtures.path('/es-modules/package-type-module/noext-esm');
99

10-
// Run a module that does not have extension
11-
// This is to ensure the --entry-type works as expected
10+
// Run a module that does not have extension.
11+
// This is to ensure that "type": "module" applies to extensionless files.
1212

1313
const child = spawn(process.execPath, [
1414
'--experimental-modules',
15-
'--entry-type=module',
1615
entry
1716
]);
1817

0 commit comments

Comments
 (0)