Skip to content

Commit fc4e413

Browse files
guybedfordMylesBorins
authored andcommitted
module: unflag conditional exports
PR-URL: #31001 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Myles Borins <[email protected]>
1 parent 7ab33f2 commit fc4e413

File tree

8 files changed

+23
-97
lines changed

8 files changed

+23
-97
lines changed

doc/api/cli.md

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -156,15 +156,6 @@ Enable experimental Source Map V3 support for stack traces.
156156
Currently, overriding `Error.prepareStackTrace` is ignored when the
157157
`--enable-source-maps` flag is set.
158158

159-
### `--experimental-conditional-exports`
160-
<!-- YAML
161-
added: v13.2.0
162-
-->
163-
164-
Enable experimental support for the `"require"` and `"node"` conditional
165-
package export resolutions.
166-
See [Conditional Exports][] for more information.
167-
168159
### `--experimental-json-modules`
169160
<!-- YAML
170161
added: v12.9.0
@@ -177,8 +168,7 @@ Enable experimental JSON support for the ES Module loader.
177168
added: v8.5.0
178169
-->
179170

180-
Enable latest experimental modules features (currently
181-
`--experimental-conditional-exports`).
171+
Enable latest experimental modules features (deprecated).
182172

183173
### `--experimental-policy`
184174
<!-- YAML
@@ -1076,7 +1066,6 @@ Node.js options that are allowed are:
10761066
<!-- node-options-node start -->
10771067
* `--enable-fips`
10781068
* `--enable-source-maps`
1079-
* `--experimental-conditional-exports`
10801069
* `--experimental-json-modules`
10811070
* `--experimental-loader`
10821071
* `--experimental-modules`
@@ -1372,7 +1361,6 @@ greater than `4` (its current default value). For more information, see the
13721361
[`tls.DEFAULT_MIN_VERSION`]: tls.html#tls_tls_default_min_version
13731362
[`unhandledRejection`]: process.html#process_event_unhandledrejection
13741363
[Chrome DevTools Protocol]: https://chromedevtools.github.io/devtools-protocol/
1375-
[Conditional Exports]: esm.html#esm_conditional_exports
13761364
[REPL]: repl.html
13771365
[ScriptCoverage]: https://chromedevtools.github.io/devtools-protocol/tot/Profiler#type-ScriptCoverage
13781366
[Source Map]: https://sourcemaps.info/spec.html

doc/api/esm.md

Lines changed: 18 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -349,21 +349,14 @@ The conditions supported in Node.js condition matching:
349349
or ES module file.
350350
* `"import"` - matched when the package is loaded via `import` or
351351
`import()`. Can be any module format, this field does not set the type
352-
interpretation. _This is currently only supported behind the
353-
`--experimental-conditional-exports` flag._
352+
interpretation.
354353
* `"node"` - matched for any Node.js environment. Can be a CommonJS or ES
355-
module file. _This is currently only supported behind the
356-
`--experimental-conditional-exports` flag._
354+
module file.
357355
* `"require"` - matched when the package is loaded via `require()`.
358-
_This is currently only supported behind the
359-
`--experimental-conditional-exports` flag._
360356

361357
Condition matching is applied in object order from first to last within the
362358
`"exports"` object.
363359

364-
> Setting the above conditions for a published package is not recommended until
365-
> conditional exports have been unflagged to avoid breaking changes to packages.
366-
367360
Using the `"require"` condition it is possible to define a package that will
368361
have a different exported value for CommonJS and ES modules, which can be a
369362
hazard in that it can result in having two separate instances of the same
@@ -456,10 +449,10 @@ ignores) the top-level `"module"` field.
456449
Node.js can now run ES module entry points, and a package can contain both
457450
CommonJS and ES module entry points (either via separate specifiers such as
458451
`'pkg'` and `'pkg/es-module'`, or both at the same specifier via [Conditional
459-
Exports][] with the `--experimental-conditional-exports` flag). Unlike in the
460-
scenario where `"module"` is only used by bundlers, or ES module files are
461-
transpiled into CommonJS on the fly before evaluation by Node.js, the files
462-
referenced by the ES module entry point are evaluated as ES modules.
452+
Exports][]). Unlike in the scenario where `"module"` is only used by bundlers,
453+
or ES module files are transpiled into CommonJS on the fly before evaluation by
454+
Node.js, the files referenced by the ES module entry point are evaluated as ES
455+
modules.
463456

464457
#### Dual Package Hazard
465458

@@ -518,13 +511,8 @@ following conditions:
518511

519512
Write the package in CommonJS or transpile ES module sources into CommonJS, and
520513
create an ES module wrapper file that defines the named exports. Using
521-
[Conditional Exports][] via the `--experimental-conditional-exports` flag, the
522-
ES module wrapper is used for `import` and the CommonJS entry point for
523-
`require`.
524-
525-
> Note: While `--experimental-conditional-exports` is flagged, a package
526-
> using this pattern will throw when loaded unless package consumers use the
527-
> `--experimental-conditional-exports` flag.
514+
[Conditional Exports][], the ES module wrapper is used for `import` and the
515+
CommonJS entry point for `require`.
528516

529517
<!-- eslint-skip -->
530518
```js
@@ -580,13 +568,13 @@ This approach is appropriate for any of the following use cases:
580568
* The package stores internal state, and the package author would prefer not to
581569
refactor the package to isolate its state management. See the next section.
582570

583-
A variant of this approach not requiring `--experimental-conditional-exports`
584-
for consumers could be to add an export, e.g. `"./module"`, to point to an
585-
all-ES module-syntax version of the package. This could be used via `import
586-
'pkg/module'` by users who are certain that the CommonJS version will not be
587-
loaded anywhere in the application, such as by dependencies; or if the CommonJS
588-
version can be loaded but doesn’t affect the ES module version (for example,
589-
because the package is stateless):
571+
A variant of this approach not requiring conditional exports for consumers could
572+
be to add an export, e.g. `"./module"`, to point to an all-ES module-syntax
573+
version of the package. This could be used via `import 'pkg/module'` by users
574+
who are certain that the CommonJS version will not be loaded anywhere in the
575+
application, such as by dependencies; or if the CommonJS version can be loaded
576+
but doesn’t affect the ES module version (for example, because the package is
577+
stateless):
590578

591579
<!-- eslint-skip -->
592580
```js
@@ -601,16 +589,10 @@ because the package is stateless):
601589
}
602590
```
603591

604-
If the `--experimental-conditional-exports` flag is dropped and therefore
605-
[Conditional Exports][] become available without a flag, this variant could be
606-
easily updated to use conditional exports by adding conditions to the `"."`
607-
path; while keeping `"./module"` for backward compatibility.
608-
609592
##### Approach #2: Isolate State
610593

611594
The most straightforward `package.json` would be one that defines the separate
612-
CommonJS and ES module entry points directly (requires
613-
`--experimental-conditional-exports`):
595+
CommonJS and ES module entry points directly:
614596

615597
<!-- eslint-skip -->
616598
```js
@@ -695,8 +677,8 @@ Even with isolated state, there is still the cost of possible extra code
695677
execution between the CommonJS and ES module versions of a package.
696678

697679
As with the previous approach, a variant of this approach not requiring
698-
`--experimental-conditional-exports` for consumers could be to add an export,
699-
e.g. `"./module"`, to point to an all-ES module-syntax version of the package:
680+
conditional exports for consumers could be to add an export, e.g.
681+
`"./module"`, to point to an all-ES module-syntax version of the package:
700682

701683
<!-- eslint-skip -->
702684
```js
@@ -711,11 +693,6 @@ e.g. `"./module"`, to point to an all-ES module-syntax version of the package:
711693
}
712694
```
713695

714-
If the `--experimental-conditional-exports` flag is dropped and therefore
715-
[Conditional Exports][] become available without a flag, this variant could be
716-
easily updated to use conditional exports by adding conditions to the `"."`
717-
path; while keeping `"./module"` for backward compatibility.
718-
719696
## `import` Specifiers
720697

721698
### Terminology

doc/node.1

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,6 @@ Requires Node.js to be built with
113113
.It Fl -enable-source-maps
114114
Enable experimental Source Map V3 support for stack traces.
115115
.
116-
.It Fl -experimental-conditional-exports
117-
Enable experimental support for "require" and "node" conditional export targets.
118-
.
119116
.It Fl -experimental-json-modules
120117
Enable experimental JSON interop support for the ES Module loader.
121118
.

lib/internal/modules/cjs/loader.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,6 @@ const { getOptionValue } = require('internal/options');
7272
const enableSourceMaps = getOptionValue('--enable-source-maps');
7373
const preserveSymlinks = getOptionValue('--preserve-symlinks');
7474
const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main');
75-
const experimentalConditionalExports =
76-
getOptionValue('--experimental-conditional-exports');
7775
const manifest = getOptionValue('--experimental-policy') ?
7876
require('internal/process/policy').manifest :
7977
null;
@@ -436,9 +434,6 @@ function resolveBasePath(basePath, exts, isMain, trailingSlash, request) {
436434
}
437435

438436
function trySelf(parentPath, isMain, request) {
439-
if (!experimentalConditionalExports) {
440-
return false;
441-
}
442437
const { data: pkg, path: basePath } = readPackageScope(parentPath) || {};
443438
if (!pkg || 'exports' in pkg === false) return false;
444439
if (typeof pkg.name !== 'string') return false;
@@ -611,8 +606,6 @@ function resolveExportsTarget(pkgPath, target, subpath, basePath, mappingKey) {
611606
switch (p) {
612607
case 'node':
613608
case 'require':
614-
if (!experimentalConditionalExports)
615-
continue;
616609
try {
617610
emitExperimentalWarning('Conditional exports');
618611
const result = resolveExportsTarget(pkgPath, target[p], subpath,

src/module_wrap.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,6 @@ Maybe<URL> ResolveExportsTarget(Environment* env,
10201020
key->ToString(context).ToLocalChecked());
10211021
std::string key_str(*key_utf8, key_utf8.length());
10221022
if (key_str == "node" || key_str == "import") {
1023-
if (!env->options()->experimental_conditional_exports) continue;
10241023
matched = true;
10251024
conditionalTarget = target_obj->Get(context, key).ToLocalChecked();
10261025
Maybe<URL> resolved = ResolveExportsTarget(env, pjson_url,

src/node_options.cc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -325,10 +325,9 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
325325
&EnvironmentOptions::userland_loader,
326326
kAllowedInEnvironment);
327327
AddAlias("--loader", "--experimental-loader");
328-
AddAlias("--experimental-modules", "--experimental-conditional-exports");
329-
AddOption("--experimental-conditional-exports",
330-
"experimental support for conditional exports targets",
331-
&EnvironmentOptions::experimental_conditional_exports,
328+
AddOption("--experimental-modules",
329+
"experimental modules features",
330+
&EnvironmentOptions::experimental_modules,
332331
kAllowedInEnvironment);
333332
AddOption("--experimental-wasm-modules",
334333
"experimental ES Module support for webassembly modules",

src/node_options.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ class EnvironmentOptions : public Options {
101101
public:
102102
bool abort_on_uncaught_exception = false;
103103
bool enable_source_maps = false;
104-
bool experimental_conditional_exports = false;
105104
bool experimental_json_modules = false;
105+
bool experimental_modules = false;
106106
std::string experimental_specifier_resolution;
107107
std::string es_module_specifier_resolution;
108108
bool experimental_wasm_modules = false;

test/es-module/test-esm-exports.mjs

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Flags: --experimental-modules
22
import { mustCall } from '../common/index.mjs';
3-
import { path } from '../common/fixtures.mjs';
43
import { ok, deepStrictEqual, strictEqual } from 'assert';
5-
import { spawn } from 'child_process';
64

75
import { requireFixture, importFixture } from '../fixtures/pkgexports.mjs';
86
import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js';
@@ -168,28 +166,3 @@ function assertIncludes(actual, expected) {
168166
ok(actual.toString().indexOf(expected) !== -1,
169167
`${JSON.stringify(actual)} includes ${JSON.stringify(expected)}`);
170168
}
171-
172-
// Test warning message
173-
[
174-
[
175-
'--experimental-conditional-exports',
176-
'/es-modules/conditional-exports.js',
177-
'Conditional exports',
178-
]
179-
].forEach(([flag, file, message]) => {
180-
const child = spawn(process.execPath, [flag, path(file)]);
181-
182-
let stderr = '';
183-
child.stderr.setEncoding('utf8');
184-
child.stderr.on('data', (data) => {
185-
stderr += data;
186-
});
187-
child.on('close', (code, signal) => {
188-
strictEqual(code, 0);
189-
strictEqual(signal, null);
190-
ok(stderr.toString().includes(
191-
`ExperimentalWarning: ${message} is an experimental feature. ` +
192-
'This feature could change at any time'
193-
));
194-
});
195-
});

0 commit comments

Comments
 (0)