Skip to content

Commit 96e46d3

Browse files
GeoffreyBoothMylesBorins
authored andcommitted
esm: replace --entry-type with --input-type
New flag is for string input only PR-URL: #27184 Reviewed-By: Jan Krems <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Joyee Cheung <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Myles Borins <[email protected]>
1 parent f85ef97 commit 96e46d3

17 files changed

+119
-130
lines changed

doc/api/cli.md

+11-13
Original file line numberDiff line numberDiff line change
@@ -134,19 +134,6 @@ added: v6.0.0
134134
Enable FIPS-compliant crypto at startup. (Requires Node.js to be built with
135135
`./configure --openssl-fips`.)
136136

137-
### `--entry-type=type`
138-
<!-- YAML
139-
added: REPLACEME
140-
-->
141-
142-
Used with `--experimental-modules`, this configures Node.js to interpret the
143-
initial entry point as CommonJS or as an ES module.
144-
145-
Valid values are `"commonjs"` and `"module"`. The default is to infer from
146-
the file extension and the `"type"` field in the nearest parent `package.json`.
147-
148-
Works for executing a file as well as `--eval`, `--print`, `STDIN`.
149-
150137
### `--es-module-specifier-resolution=mode`
151138
<!-- YAML
152139
added: REPLACEME
@@ -261,6 +248,17 @@ added: v0.11.15
261248

262249
Specify ICU data load path. (Overrides `NODE_ICU_DATA`.)
263250

251+
### `--input-type=type`
252+
<!-- YAML
253+
added: REPLACEME
254+
-->
255+
256+
Used with `--experimental-modules`, this configures Node.js to interpret string
257+
input as CommonJS or as an ES module. String input is input via `--eval`,
258+
`--print`, or `STDIN`.
259+
260+
Valid values are `"commonjs"` and `"module"`. The default is `"commonjs"`.
261+
264262
### `--inspect-brk[=[host:]port]`
265263
<!-- YAML
266264
added: v7.6.0

doc/api/errors.md

+20-12
Original file line numberDiff line numberDiff line change
@@ -854,18 +854,6 @@ provided.
854854
Encoding provided to `TextDecoder()` API was not one of the
855855
[WHATWG Supported Encodings][].
856856

857-
<a id="ERR_ENTRY_TYPE_MISMATCH"></a>
858-
#### ERR_ENTRY_TYPE_MISMATCH
859-
860-
> Stability: 1 - Experimental
861-
862-
The `--entry-type=commonjs` flag was used to attempt to execute an `.mjs` file
863-
or a `.js` file where the nearest parent `package.json` contains
864-
`"type": "module"`; or
865-
the `--entry-type=module` flag was used to attempt to execute a `.cjs` file or
866-
a `.js` file where the nearest parent `package.json` either lacks a `"type"`
867-
field or contains `"type": "commonjs"`.
868-
869857
<a id="ERR_FALSY_VALUE_REJECTION"></a>
870858
### ERR_FALSY_VALUE_REJECTION
871859

@@ -1166,6 +1154,14 @@ is set for the `Http2Stream`.
11661154
An option pair is incompatible with each other and can not be used at the same
11671155
time.
11681156

1157+
<a id="ERR_INPUT_TYPE_NOT_ALLOWED"></a>
1158+
### ERR_INPUT_TYPE_NOT_ALLOWED
1159+
1160+
> Stability: 1 - Experimental
1161+
1162+
The `--input-type` flag was used to attempt to execute a file. This flag can
1163+
only be used with input via `--eval`, `--print` or `STDIN`.
1164+
11691165
<a id="ERR_INSPECTOR_ALREADY_CONNECTED"></a>
11701166
### ERR_INSPECTOR_ALREADY_CONNECTED
11711167

@@ -2223,6 +2219,18 @@ closed.
22232219
These errors have never been released, but had been present on master between
22242220
releases.
22252221

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

doc/api/esm.md

+49-31
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

+3-3
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
.
@@ -170,6 +167,9 @@ Specify ICU data load path.
170167
Overrides
171168
.Ev NODE_ICU_DATA .
172169
.
170+
.It Fl -input-type Ns = Ns Ar type
171+
Set the module resolution type for input via --eval, --print or STDIN.
172+
.
173173
.It Fl -inspect-brk Ns = Ns Ar [host:]port
174174
Activate inspector on
175175
.Ar host:port

lib/internal/errors.js

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

lib/internal/main/check_syntax.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ function checkSyntax(source, filename) {
6060
if (experimentalModules) {
6161
let isModule = false;
6262
if (filename === '[stdin]' || filename === '[eval]') {
63-
isModule = getOptionValue('--entry-type') === 'module';
63+
isModule = getOptionValue('--input-type') === 'module';
6464
} else {
6565
const resolve = require('internal/modules/esm/default_resolve');
6666
const { format } = resolve(pathToFileURL(filename).toString());

lib/internal/main/eval_stdin.js

+1-1
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

+1-1
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

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ const console = require('internal/console/global');
1515

1616
prepareMainThreadExecution();
1717

18-
// --entry-type flag not supported in REPL
19-
if (require('internal/options').getOptionValue('--entry-type')) {
18+
// --input-type flag not supported in REPL
19+
if (require('internal/options').getOptionValue('--input-type')) {
2020
// If we can't write to stderr, we'd like to make this a noop,
2121
// so use console.error.
22-
console.error('Cannot specify --entry-type for REPL');
22+
console.error('Cannot specify --input-type for REPL');
2323
process.exit(1);
2424
}
2525

lib/internal/modules/esm/default_resolve.js

+11-21
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

+6-6
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 be \"module\" or \"commonjs\"");
116+
errors->push_back("--input-type must be \"module\" or \"commonjs\"");
117117
}
118118
}
119119

@@ -289,15 +289,15 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
289289
"(default: llhttp).",
290290
&EnvironmentOptions::http_parser,
291291
kAllowedInEnvironment);
292+
AddOption("--input-type",
293+
"set module type for string input",
294+
&EnvironmentOptions::module_type,
295+
kAllowedInEnvironment);
292296
AddOption("--loader",
293297
"(with --experimental-modules) use the specified file as a "
294298
"custom loader",
295299
&EnvironmentOptions::userland_loader,
296300
kAllowedInEnvironment);
297-
AddOption("--entry-type",
298-
"set module type name of the entry point",
299-
&EnvironmentOptions::module_type,
300-
kAllowedInEnvironment);
301301
AddOption("--es-module-specifier-resolution",
302302
"Select extension resolution algorithm for es modules; "
303303
"either 'explicit' (default) or 'node'",

0 commit comments

Comments
 (0)