Skip to content

Commit 21d314e

Browse files
guybedfordBethGriggs
authored andcommitted
module: exports not exported for null resolutions
PR-URL: #32838 Reviewed-By: Jan Krems <jan.krems@gmail.com>
1 parent 4dd3a7d commit 21d314e

File tree

5 files changed

+24
-11
lines changed

5 files changed

+24
-11
lines changed

doc/api/esm.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1661,13 +1661,15 @@ The resolver can throw the following errors:
16611661
> loop on any _Package Path Not Exported_ error.
16621662
> 1. Throw a _Package Path Not Exported_ error.
16631663
> 1. Otherwise, if _target_ is an Array, then
1664-
> 1. If _target.length is zero, throw an _Invalid Package Target_ error.
1664+
> 1. If _target.length is zero, throw a _Package Path Not Exported_ error.
16651665
> 1. For each item _targetValue_ in _target_, do
16661666
> 1. If _targetValue_ is an Array, continue the loop.
16671667
> 1. Return the result of **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_,
16681668
> _targetValue_, _subpath_, _env_), continuing the loop on any
16691669
> _Package Path Not Exported_ or _Invalid Package Target_ error.
16701670
> 1. Throw the last fallback resolution error.
1671+
> 1. Otherwise, if _target_ is _null_, throw a _Package Path Not Exported_
1672+
> error.
16711673
> 1. Otherwise throw an _Invalid Package Target_ error.
16721674
16731675
**ESM_FORMAT**(_url_)

lib/internal/modules/cjs/loader.js

+9-5
Original file line numberDiff line numberDiff line change
@@ -552,21 +552,22 @@ function resolveExportsTarget(baseUrl, target, subpath, mappingKey) {
552552
, 0, -1), mappingKey);
553553
} else if (ArrayIsArray(target)) {
554554
if (target.length === 0)
555-
throw new ERR_INVALID_PACKAGE_TARGET(StringPrototypeSlice(baseUrl.pathname
556-
, 0, -1), mappingKey, subpath, target);
555+
throw new ERR_PACKAGE_PATH_NOT_EXPORTED(
556+
StringPrototypeSlice(baseUrl.pathname, 0, -1), mappingKey + subpath);
557+
let lastException;
557558
for (const targetValue of target) {
558559
try {
559560
return resolveExportsTarget(baseUrl, targetValue, subpath, mappingKey);
560561
} catch (e) {
562+
lastException = e;
561563
if (e.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED' &&
562564
e.code !== 'ERR_INVALID_PACKAGE_TARGET')
563565
throw e;
564566
}
565567
}
566568
// Throw last fallback error
567-
resolveExportsTarget(baseUrl, target[target.length - 1], subpath,
568-
mappingKey);
569-
assert(false);
569+
assert(lastException !== undefined);
570+
throw lastException;
570571
} else if (typeof target === 'object' && target !== null) {
571572
const keys = ObjectKeys(target);
572573
if (keys.some(isArrayIndex)) {
@@ -595,6 +596,9 @@ function resolveExportsTarget(baseUrl, target, subpath, mappingKey) {
595596
}
596597
throw new ERR_PACKAGE_PATH_NOT_EXPORTED(
597598
StringPrototypeSlice(baseUrl.pathname, 0, -1), mappingKey + subpath);
599+
} else if (target === null) {
600+
throw new ERR_PACKAGE_PATH_NOT_EXPORTED(
601+
StringPrototypeSlice(baseUrl.pathname, 0, -1), mappingKey + subpath);
598602
}
599603
throw new ERR_INVALID_PACKAGE_TARGET(
600604
StringPrototypeSlice(baseUrl.pathname, 0, -1), mappingKey, subpath, target);

lib/internal/modules/esm/resolve.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const {
1616
StringPrototypeStartsWith,
1717
StringPrototypeSubstr,
1818
} = primordials;
19-
19+
const assert = require('internal/assert');
2020
const internalFS = require('internal/fs/utils');
2121
const { NativeModule } = require('internal/bootstrap/loaders');
2222
const {
@@ -345,7 +345,7 @@ function resolveExportsTarget(
345345
return finalizeResolution(resolved, base);
346346
} else if (ArrayIsArray(target)) {
347347
if (target.length === 0)
348-
throwExportsInvalid(packageSubpath, target, packageJSONUrl, base);
348+
throwExportsNotFound(packageSubpath, packageJSONUrl, base);
349349

350350
let lastException;
351351
for (let i = 0; i < target.length; i++) {
@@ -366,6 +366,7 @@ function resolveExportsTarget(
366366

367367
return finalizeResolution(resolved, base);
368368
}
369+
assert(lastException !== undefined);
369370
throw lastException;
370371
} else if (typeof target === 'object' && target !== null) {
371372
const keys = ObjectGetOwnPropertyNames(target);
@@ -392,6 +393,8 @@ function resolveExportsTarget(
392393
}
393394
}
394395
throwExportsNotFound(packageSubpath, packageJSONUrl, base);
396+
} else if (target === null) {
397+
throwExportsNotFound(packageSubpath, packageJSONUrl, base);
395398
}
396399
throwExportsInvalid(packageSubpath, target, packageJSONUrl, base);
397400
}

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js';
6464
// Conditional exports with no match are "not exported" errors
6565
['pkgexports/invalid1', './invalid1'],
6666
['pkgexports/invalid4', './invalid4'],
67+
// Null mapping
68+
['pkgexports/null', './null'],
69+
['pkgexports/null/subpath', './null/subpath'],
70+
// Empty fallback
71+
['pkgexports/nofallback1', './nofallback1'],
6772
]);
6873

6974
const invalidExports = new Map([
@@ -74,13 +79,11 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js';
7479
['pkgexports/belowdir/pkgexports/asdf.js', './belowdir/'],
7580
// This target file steps below the package
7681
['pkgexports/belowfile', './belowfile'],
77-
// Invalid target handling
78-
['pkgexports/null', './null'],
82+
// Invalid targets
7983
['pkgexports/invalid2', './invalid2'],
8084
['pkgexports/invalid3', './invalid3'],
8185
['pkgexports/invalid5', 'invalid5'],
8286
// Missing / invalid fallbacks
83-
['pkgexports/nofallback1', './nofallback1'],
8487
['pkgexports/nofallback2', './nofallback2'],
8588
// Reaching into nested node_modules
8689
['pkgexports/nodemodules', './nodemodules'],

test/fixtures/node_modules/pkgexports/package.json

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)