Skip to content

Commit

Permalink
module: exports not exported for null resolutions
Browse files Browse the repository at this point in the history
PR-URL: #32838
Reviewed-By: Jan Krems <jan.krems@gmail.com>
  • Loading branch information
guybedford authored and targos committed May 13, 2020
1 parent 3dc3772 commit 1811a10
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 11 deletions.
4 changes: 3 additions & 1 deletion doc/api/esm.md
Expand Up @@ -1671,13 +1671,15 @@ The resolver can throw the following errors:
> loop on any _Package Path Not Exported_ error.
> 1. Throw a _Package Path Not Exported_ error.
> 1. Otherwise, if _target_ is an Array, then
> 1. If _target.length is zero, throw an _Invalid Package Target_ error.
> 1. If _target.length is zero, throw a _Package Path Not Exported_ error.
> 1. For each item _targetValue_ in _target_, do
> 1. If _targetValue_ is an Array, continue the loop.
> 1. Return the result of **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_,
> _targetValue_, _subpath_, _env_), continuing the loop on any
> _Package Path Not Exported_ or _Invalid Package Target_ error.
> 1. Throw the last fallback resolution error.
> 1. Otherwise, if _target_ is _null_, throw a _Package Path Not Exported_
> error.
> 1. Otherwise throw an _Invalid Package Target_ error.
**ESM_FORMAT**(_url_)
Expand Down
14 changes: 9 additions & 5 deletions lib/internal/modules/cjs/loader.js
Expand Up @@ -553,21 +553,22 @@ function resolveExportsTarget(baseUrl, target, subpath, mappingKey) {
, 0, -1), mappingKey);
} else if (ArrayIsArray(target)) {
if (target.length === 0)
throw new ERR_INVALID_PACKAGE_TARGET(StringPrototypeSlice(baseUrl.pathname
, 0, -1), mappingKey, subpath, target);
throw new ERR_PACKAGE_PATH_NOT_EXPORTED(
StringPrototypeSlice(baseUrl.pathname, 0, -1), mappingKey + subpath);
let lastException;
for (const targetValue of target) {
try {
return resolveExportsTarget(baseUrl, targetValue, subpath, mappingKey);
} catch (e) {
lastException = e;
if (e.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED' &&
e.code !== 'ERR_INVALID_PACKAGE_TARGET')
throw e;
}
}
// Throw last fallback error
resolveExportsTarget(baseUrl, target[target.length - 1], subpath,
mappingKey);
assert(false);
assert(lastException !== undefined);
throw lastException;
} else if (typeof target === 'object' && target !== null) {
const keys = ObjectKeys(target);
if (keys.some(isArrayIndex)) {
Expand Down Expand Up @@ -596,6 +597,9 @@ function resolveExportsTarget(baseUrl, target, subpath, mappingKey) {
}
throw new ERR_PACKAGE_PATH_NOT_EXPORTED(
StringPrototypeSlice(baseUrl.pathname, 0, -1), mappingKey + subpath);
} else if (target === null) {
throw new ERR_PACKAGE_PATH_NOT_EXPORTED(
StringPrototypeSlice(baseUrl.pathname, 0, -1), mappingKey + subpath);
}
throw new ERR_INVALID_PACKAGE_TARGET(
StringPrototypeSlice(baseUrl.pathname, 0, -1), mappingKey, subpath, target);
Expand Down
7 changes: 5 additions & 2 deletions lib/internal/modules/esm/resolve.js
Expand Up @@ -16,7 +16,7 @@ const {
StringPrototypeStartsWith,
StringPrototypeSubstr,
} = primordials;

const assert = require('internal/assert');
const internalFS = require('internal/fs/utils');
const { NativeModule } = require('internal/bootstrap/loaders');
const {
Expand Down Expand Up @@ -345,7 +345,7 @@ function resolveExportsTarget(
return finalizeResolution(resolved, base);
} else if (ArrayIsArray(target)) {
if (target.length === 0)
throwExportsInvalid(packageSubpath, target, packageJSONUrl, base);
throwExportsNotFound(packageSubpath, packageJSONUrl, base);

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

return finalizeResolution(resolved, base);
}
assert(lastException !== undefined);
throw lastException;
} else if (typeof target === 'object' && target !== null) {
const keys = ObjectGetOwnPropertyNames(target);
Expand All @@ -392,6 +393,8 @@ function resolveExportsTarget(
}
}
throwExportsNotFound(packageSubpath, packageJSONUrl, base);
} else if (target === null) {
throwExportsNotFound(packageSubpath, packageJSONUrl, base);
}
throwExportsInvalid(packageSubpath, target, packageJSONUrl, base);
}
Expand Down
9 changes: 6 additions & 3 deletions test/es-module/test-esm-exports.mjs
Expand Up @@ -65,6 +65,11 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js';
// Conditional exports with no match are "not exported" errors
['pkgexports/invalid1', './invalid1'],
['pkgexports/invalid4', './invalid4'],
// Null mapping
['pkgexports/null', './null'],
['pkgexports/null/subpath', './null/subpath'],
// Empty fallback
['pkgexports/nofallback1', './nofallback1'],
]);

const invalidExports = new Map([
Expand All @@ -75,13 +80,11 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js';
['pkgexports/belowdir/pkgexports/asdf.js', './belowdir/'],
// This target file steps below the package
['pkgexports/belowfile', './belowfile'],
// Invalid target handling
['pkgexports/null', './null'],
// Invalid targets
['pkgexports/invalid2', './invalid2'],
['pkgexports/invalid3', './invalid3'],
['pkgexports/invalid5', 'invalid5'],
// Missing / invalid fallbacks
['pkgexports/nofallback1', './nofallback1'],
['pkgexports/nofallback2', './nofallback2'],
// Reaching into nested node_modules
['pkgexports/nodemodules', './nodemodules'],
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/node_modules/pkgexports/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 1811a10

Please sign in to comment.