Skip to content

Commit 616a4ee

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 fae517a commit 616a4ee

File tree

9 files changed

+20
-100
lines changed

9 files changed

+20
-100
lines changed

doc/api/cli.md

-11
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: REPLACEME
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
@@ -1098,7 +1089,6 @@ Node.js options that are allowed are:
10981089
<!-- node-options-node start -->
10991090
* `--enable-fips`
11001091
* `--enable-source-maps`
1101-
* `--experimental-conditional-exports`
11021092
* `--experimental-json-modules`
11031093
* `--experimental-loader`
11041094
* `--experimental-modules`
@@ -1395,7 +1385,6 @@ greater than `4` (its current default value). For more information, see the
13951385
[`tls.DEFAULT_MIN_VERSION`]: tls.html#tls_tls_default_min_version
13961386
[`unhandledRejection`]: process.html#process_event_unhandledrejection
13971387
[Chrome DevTools Protocol]: https://chromedevtools.github.io/devtools-protocol/
1398-
[Conditional Exports]: esm.html#esm_conditional_exports
13991388
[REPL]: repl.html
14001389
[ScriptCoverage]: https://chromedevtools.github.io/devtools-protocol/tot/Profiler#type-ScriptCoverage
14011390
[Source Map]: https://sourcemaps.info/spec.html

doc/api/esm.md

+18-41
Original file line numberDiff line numberDiff line change
@@ -355,21 +355,14 @@ The conditions supported in Node.js condition matching:
355355
or ES module file.
356356
* `"import"` - matched when the package is loaded via `import` or
357357
`import()`. Can be any module format, this field does not set the type
358-
interpretation. _This is currently only supported behind the
359-
`--experimental-conditional-exports` flag._
358+
interpretation.
360359
* `"node"` - matched for any Node.js environment. Can be a CommonJS or ES
361-
module file. _This is currently only supported behind the
362-
`--experimental-conditional-exports` flag._
360+
module file.
363361
* `"require"` - matched when the package is loaded via `require()`.
364-
_This is currently only supported behind the
365-
`--experimental-conditional-exports` flag._
366362

367363
Condition matching is applied in object order from first to last within the
368364
`"exports"` object.
369365

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

470463
#### Dual Package Hazard
471464

@@ -524,13 +517,8 @@ following conditions:
524517

525518
Write the package in CommonJS or transpile ES module sources into CommonJS, and
526519
create an ES module wrapper file that defines the named exports. Using
527-
[Conditional Exports][] via the `--experimental-conditional-exports` flag, the
528-
ES module wrapper is used for `import` and the CommonJS entry point for
529-
`require`.
530-
531-
> Note: While `--experimental-conditional-exports` is flagged, a package
532-
> using this pattern will throw when loaded unless package consumers use the
533-
> `--experimental-conditional-exports` flag.
520+
[Conditional Exports][], the ES module wrapper is used for `import` and the
521+
CommonJS entry point for `require`.
534522

535523
<!-- eslint-skip -->
536524
```js
@@ -586,13 +574,13 @@ This approach is appropriate for any of the following use cases:
586574
* The package stores internal state, and the package author would prefer not to
587575
refactor the package to isolate its state management. See the next section.
588576

589-
A variant of this approach not requiring `--experimental-conditional-exports`
590-
for consumers could be to add an export, e.g. `"./module"`, to point to an
591-
all-ES module-syntax version of the package. This could be used via `import
592-
'pkg/module'` by users who are certain that the CommonJS version will not be
593-
loaded anywhere in the application, such as by dependencies; or if the CommonJS
594-
version can be loaded but doesn’t affect the ES module version (for example,
595-
because the package is stateless):
577+
A variant of this approach not requiring conditional exports for consumers could
578+
be to add an export, e.g. `"./module"`, to point to an all-ES module-syntax
579+
version of the package. This could be used via `import 'pkg/module'` by users
580+
who are certain that the CommonJS version will not be loaded anywhere in the
581+
application, such as by dependencies; or if the CommonJS version can be loaded
582+
but doesn’t affect the ES module version (for example, because the package is
583+
stateless):
596584

597585
<!-- eslint-skip -->
598586
```js
@@ -607,16 +595,10 @@ because the package is stateless):
607595
}
608596
```
609597

610-
If the `--experimental-conditional-exports` flag is dropped and therefore
611-
[Conditional Exports][] become available without a flag, this variant could be
612-
easily updated to use conditional exports by adding conditions to the `"."`
613-
path; while keeping `"./module"` for backward compatibility.
614-
615598
##### Approach #2: Isolate State
616599

617600
The most straightforward `package.json` would be one that defines the separate
618-
CommonJS and ES module entry points directly (requires
619-
`--experimental-conditional-exports`):
601+
CommonJS and ES module entry points directly:
620602

621603
<!-- eslint-skip -->
622604
```js
@@ -701,8 +683,8 @@ Even with isolated state, there is still the cost of possible extra code
701683
execution between the CommonJS and ES module versions of a package.
702684

703685
As with the previous approach, a variant of this approach not requiring
704-
`--experimental-conditional-exports` for consumers could be to add an export,
705-
e.g. `"./module"`, to point to an all-ES module-syntax version of the package:
686+
conditional exports for consumers could be to add an export, e.g.
687+
`"./module"`, to point to an all-ES module-syntax version of the package:
706688

707689
<!-- eslint-skip -->
708690
```js
@@ -717,11 +699,6 @@ e.g. `"./module"`, to point to an all-ES module-syntax version of the package:
717699
}
718700
```
719701

720-
If the `--experimental-conditional-exports` flag is dropped and therefore
721-
[Conditional Exports][] become available without a flag, this variant could be
722-
easily updated to use conditional exports by adding conditions to the `"."`
723-
path; while keeping `"./module"` for backward compatibility.
724-
725702
## `import` Specifiers
726703

727704
### Terminology

doc/node.1

-3
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

-7
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,6 @@ const enableSourceMaps = getOptionValue('--enable-source-maps');
7070
const preserveSymlinks = getOptionValue('--preserve-symlinks');
7171
const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main');
7272
const experimentalModules = getOptionValue('--experimental-modules');
73-
const experimentalConditionalExports =
74-
getOptionValue('--experimental-conditional-exports');
7573
const manifest = getOptionValue('--experimental-policy') ?
7674
require('internal/process/policy').manifest :
7775
null;
@@ -434,9 +432,6 @@ function resolveBasePath(basePath, exts, isMain, trailingSlash, request) {
434432
}
435433

436434
function trySelf(parentPath, isMain, request) {
437-
if (!experimentalConditionalExports) {
438-
return false;
439-
}
440435
const { data: pkg, path: basePath } = readPackageScope(parentPath) || {};
441436
if (!pkg || 'exports' in pkg === false) return false;
442437
if (typeof pkg.name !== 'string') return false;
@@ -609,8 +604,6 @@ function resolveExportsTarget(pkgPath, target, subpath, basePath, mappingKey) {
609604
switch (p) {
610605
case 'node':
611606
case 'require':
612-
if (!experimentalConditionalExports)
613-
continue;
614607
try {
615608
emitExperimentalWarning('Conditional exports');
616609
const result = resolveExportsTarget(pkgPath, target[p], subpath,

src/module_wrap.cc

-1
Original file line numberDiff line numberDiff line change
@@ -992,7 +992,6 @@ Maybe<URL> ResolveExportsTarget(Environment* env,
992992
key->ToString(context).ToLocalChecked());
993993
std::string key_str(*key_utf8, key_utf8.length());
994994
if (key_str == "node" || key_str == "import") {
995-
if (!env->options()->experimental_conditional_exports) continue;
996995
matched = true;
997996
conditionalTarget = target_obj->Get(context, key).ToLocalChecked();
998997
Maybe<URL> resolved = ResolveExportsTarget(env, pjson_url,

src/node_options.cc

-4
Original file line numberDiff line numberDiff line change
@@ -360,10 +360,6 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
360360
"experimental ES Module support and caching modules",
361361
&EnvironmentOptions::experimental_modules,
362362
kAllowedInEnvironment);
363-
AddOption("--experimental-conditional-exports",
364-
"experimental support for conditional exports targets",
365-
&EnvironmentOptions::experimental_conditional_exports,
366-
kAllowedInEnvironment);
367363
AddOption("--experimental-wasm-modules",
368364
"experimental ES Module support for webassembly modules",
369365
&EnvironmentOptions::experimental_wasm_modules,

src/node_options.h

-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ 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;
106105
bool experimental_modules = false;
107106
std::string experimental_specifier_resolution;

src/util-inl.h

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
2626

27+
#include <cmath>
2728
#include <cstring>
2829
#include "util.h"
2930

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

+1-32
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
// Flags: --experimental-modules --experimental-conditional-exports
1+
// Flags: --experimental-modules
22

33
import { mustCall } from '../common/index.mjs';
4-
import { path } from '../common/fixtures.mjs';
54
import { ok, deepStrictEqual, strictEqual } from 'assert';
6-
import { spawn } from 'child_process';
75

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

0 commit comments

Comments
 (0)