Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Bedford <guybedford@gmail.com>2021-09-15 12:52:40 +0300
committerGuy Bedford <guybedford@gmail.com>2021-09-22 09:15:02 +0300
commit36e2ffe6dc379043be96ebfd889ccd1a3e38aa84 (patch)
treec74fbdbc8087c962037944d107812e5653f53b99
parent0991dfceceede0b0ad47abf866e571dd5164d231 (diff)
module: subpath folder mappings EOL
PR-URL: https://github.com/nodejs/node/pull/40121 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Bradley Farias <bradley.meck@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
-rw-r--r--doc/api/deprecations.md10
-rw-r--r--doc/api/esm.md82
-rw-r--r--doc/api/packages.md45
-rw-r--r--lib/internal/modules/cjs/loader.js16
-rw-r--r--lib/internal/modules/esm/resolve.js93
-rw-r--r--test/es-module/test-esm-exports-deprecations.mjs5
-rw-r--r--test/es-module/test-esm-exports.mjs15
-rw-r--r--test/es-module/test-esm-imports.mjs4
-rw-r--r--test/es-module/test-esm-local-deprecations.mjs37
-rw-r--r--test/fixtures/es-modules/pkgimports/package.json2
-rw-r--r--test/fixtures/node_modules/pkgexports/package.json9
11 files changed, 81 insertions, 237 deletions
diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md
index 593413efc01..fabf91eef56 100644
--- a/doc/api/deprecations.md
+++ b/doc/api/deprecations.md
@@ -2707,6 +2707,9 @@ Use `fs.rm(path, { recursive: true, force: true })`,
### DEP0148: Folder mappings in `"exports"` (trailing `"/"`)
<!-- YAML
changes:
+ - version: REPLACEME
+ pr-url: https://github.com/nodejs/node/pull/40121
+ description: End-of-Life.
- version: v16.0.0
pr-url: https://github.com/nodejs/node/pull/37215
description: Runtime deprecation.
@@ -2720,9 +2723,9 @@ changes:
Type: Runtime
-Using a trailing `"/"` to define
-[subpath folder mappings][] in the [subpath exports][] or
-[subpath imports][] fields is deprecated. Use [subpath patterns][] instead.
+Using a trailing `"/"` to define subpath folder mappings in the
+[subpath exports][] or [subpath imports][] fields is deprecated. Use
+[subpath patterns][] instead.
### DEP0149: `http.IncomingMessage#connection`
<!-- YAML
@@ -2965,6 +2968,5 @@ for package `"exports"` and `"imports"` pattern resolutions.
[legacy `urlObject`]: url.md#legacy-urlobject
[static methods of `crypto.Certificate()`]: crypto.md#class-certificate
[subpath exports]: packages.md#subpath-exports
-[subpath folder mappings]: packages.md#subpath-folder-mappings
[subpath imports]: packages.md#subpath-imports
[subpath patterns]: packages.md#subpath-patterns
diff --git a/doc/api/esm.md b/doc/api/esm.md
index e8afc730b43..32beab664dc 100644
--- a/doc/api/esm.md
+++ b/doc/api/esm.md
@@ -1068,9 +1068,8 @@ The resolver can throw the following errors:
> 1. Set _resolved_ to the URL resolution of _specifier_ relative to
> _parentURL_.
> 1. Otherwise, if _specifier_ starts with _"#"_, then
-> 1. Set _resolved_ to the destructured value of the result of
-> **PACKAGE_IMPORTS_RESOLVE**(_specifier_, _parentURL_,
-> _defaultConditions_).
+> 1. Set _resolved_ to the result of **PACKAGE_IMPORTS_RESOLVE**(_specifier_,
+> _parentURL_, _defaultConditions_).
> 1. Otherwise,
> 1. Note: _specifier_ is now a bare specifier.
> 1. Set _resolved_ the result of
@@ -1103,7 +1102,7 @@ The resolver can throw the following errors:
> 1. If _packageName_ starts with _"."_ or contains _"\\"_ or _"%"_, then
> 1. Throw an _Invalid Module Specifier_ error.
> 1. Let _packageSubpath_ be _"."_ concatenated with the substring of
-> _packageSpecifier_ from the position at the length of _packageName_.
+> _packageSpecifier_ from the position at the length of _packageName_.
> 1. Let _selfUrl_ be the result of
> **PACKAGE_SELF_RESOLVE**(_packageName_, _packageSubpath_, _parentURL_).
> 1. If _selfUrl_ is not **undefined**, return _selfUrl_.
@@ -1121,11 +1120,10 @@ The resolver can throw the following errors:
> 1. If _pjson_ is not **null** and _pjson_._exports_ is not **null** or
> **undefined**, then
> 1. Let _exports_ be _pjson.exports_.
-> 1. Return the _resolved_ destructured value of the result of
-> **PACKAGE_EXPORTS_RESOLVE**(_packageURL_, _packageSubpath_,
-> _pjson.exports_, _defaultConditions_).
+> 1. Return the result of **PACKAGE_EXPORTS_RESOLVE**(_packageURL_,
+> _packageSubpath_, _pjson.exports_, _defaultConditions_).
> 1. Otherwise, if _packageSubpath_ is equal to _"."_, then
-> 1. Return the result applying the legacy **LOAD_AS_DIRECTORY**
+> 1. Return the result of applying the legacy **LOAD_AS_DIRECTORY**
> CommonJS resolver to _packageURL_, throwing a _Module Not Found_
> error for no resolution.
> 1. Otherwise,
@@ -1142,13 +1140,14 @@ The resolver can throw the following errors:
> **undefined**, then
> 1. Return **undefined**.
> 1. If _pjson.name_ is equal to _packageName_, then
-> 1. Return the _resolved_ destructured value of the result of
-> **PACKAGE_EXPORTS_RESOLVE**(_packageURL_, _subpath_, _pjson.exports_,
-> _defaultConditions_).
+> 1. Return the result of **PACKAGE_EXPORTS_RESOLVE**(_packageURL_,
+> _subpath_, _pjson.exports_, _defaultConditions_).
> 1. Otherwise, return **undefined**.
**PACKAGE_EXPORTS_RESOLVE**(_packageURL_, _subpath_, _exports_, _conditions_)
+> 1. If _subpath_ ends in _"/"_, then
+> 1. Throw an _Invalid Module Specifier_ error.
> 1. If _exports_ is an Object with both a key starting with _"."_ and a key not
> starting with _"."_, throw an _Invalid Package Configuration_ error.
> 1. If _subpath_ is equal to _"."_, then
@@ -1162,53 +1161,45 @@ The resolver can throw the following errors:
> 1. Let _resolved_ be the result of **PACKAGE_TARGET_RESOLVE**(
> _packageURL_, _mainExport_, _""_, **false**, **false**,
> _conditions_).
-> 1. If _resolved_ is not **null** or **undefined**, then
-> 1. Return _resolved_.
+> 1. If _resolved_ is not **null** or **undefined**, return _resolved_.
> 1. Otherwise, if _exports_ is an Object and all keys of _exports_ start with
> _"."_, then
> 1. Let _matchKey_ be the string _"./"_ concatenated with _subpath_.
-> 1. Let _resolvedMatch_ be result of **PACKAGE_IMPORTS_EXPORTS_RESOLVE**(
+> 1. Let _resolved_ be the result of **PACKAGE_IMPORTS_EXPORTS_RESOLVE**(
> _matchKey_, _exports_, _packageURL_, **false**, _conditions_).
-> 1. If _resolvedMatch_._resolve_ is not **null** or **undefined**, then
-> 1. Return _resolvedMatch_.
+> 1. If _resolved_ is not **null** or **undefined**, return _resolved_.
> 1. Throw a _Package Path Not Exported_ error.
**PACKAGE_IMPORTS_RESOLVE**(_specifier_, _parentURL_, _conditions_)
> 1. Assert: _specifier_ begins with _"#"_.
-> 1. If _specifier_ is exactly equal to _"#"_ or starts with _"#/"_, then
+> 1. If _specifier_ is exactly equal to _"#"_, starts with _"#/"_, or ends in
+> _"/"_, then
> 1. Throw an _Invalid Module Specifier_ error.
> 1. Let _packageURL_ be the result of **READ_PACKAGE_SCOPE**(_parentURL_).
> 1. If _packageURL_ is not **null**, then
> 1. Let _pjson_ be the result of **READ_PACKAGE_JSON**(_packageURL_).
> 1. If _pjson.imports_ is a non-null Object, then
-> 1. Let _resolvedMatch_ be the result of
-> **PACKAGE_IMPORTS_EXPORTS_RESOLVE**(_specifier_, _pjson.imports_,
-> _packageURL_, **true**, _conditions_).
-> 1. If _resolvedMatch_._resolve_ is not **null** or **undefined**, then
-> 1. Return _resolvedMatch_.
+> 1. Let _resolved_ be the result of **PACKAGE_IMPORTS_EXPORTS_RESOLVE**(
+> _specifier_, _pjson.imports_, _packageURL_, **true**, _conditions_).
+> 1. If _resolved_ is not **null** or **undefined**, return _resolved_.
> 1. Throw a _Package Import Not Defined_ error.
**PACKAGE_IMPORTS_EXPORTS_RESOLVE**(_matchKey_, _matchObj_, _packageURL_,
_isImports_, _conditions_)
-> 1. If _matchKey_ is a key of _matchObj_ and does not end in _"/"_ or contain
-> _"*"_, then
+> 1. Assert: _matchKey_ does not end in _"/"_.
+> 1. If _matchKey_ is a key of _matchObj_ and does not contain _"*"_, then
> 1. Let _target_ be the value of _matchObj_\[_matchKey_\].
-> 1. Let _resolved_ be the result of **PACKAGE_TARGET_RESOLVE**(
-> _packageURL_, _target_, _""_, **false**, _isImports_, _conditions_).
-> 1. Return the object _{ resolved, exact: **true** }_.
-> 1. Let _expansionKeys_ be the list of keys of _matchObj_ either ending in
-> _"/"_ or containing only a single _"*"_, sorted by the sorting function
-> **PATTERN_KEY_COMPARE** which orders in descending order of specificity.
+> 1. Return the result of **PACKAGE_TARGET_RESOLVE**(_packageURL_, _target_,
+> _""_, **false**, _isImports_, _conditions_).
+> 1. Let _expansionKeys_ be the list of keys of _matchObj_ containing only a
+> single _"*"_, sorted by the sorting function **PATTERN_KEY_COMPARE** which
+> orders in descending order of specificity.
> 1. For each key _expansionKey_ in _expansionKeys_, do
-> 1. Let _patternBase_ be **null**.
-> 1. If _expansionKey_ contains _"*"_, set _patternBase_ to the substring of
-> _expansionKey_ up to but excluding the first _"*"_ character.
-> 1. If _patternBase_ is not **null** and _matchKey_ starts with but is not
-> equal to _patternBase_, then
-> 1. If _matchKey_ ends with _"/"_, throw an _Invalid Module Specifier_
-> error.
+> 1. Let _patternBase_ be the substring of _expansionKey_ up to but excluding
+> the first _"*"_ character.
+> 1. If _matchKey_ starts with but is not equal to _patternBase_, then
> 1. Let _patternTrailer_ be the substring of _expansionKey_ from the
> index after the first _"*"_ character.
> 1. If _patternTrailer_ has zero length, or if _matchKey_ ends with
@@ -1218,20 +1209,9 @@ _isImports_, _conditions_)
> 1. Let _subpath_ be the substring of _matchKey_ starting at the
> index of the length of _patternBase_ up to the length of
> _matchKey_ minus the length of _patternTrailer_.
-> 1. Let _resolved_ be the result of **PACKAGE_TARGET_RESOLVE**(
-> _packageURL_, _target_, _subpath_, **true**, _isImports_,
-> _conditions_).
-> 1. Return the object _{ resolved, exact: **true** }_.
-> 1. Otherwise if _patternBase_ is **null** and _matchKey_ starts with
-> _expansionKey_, then
-> 1. Let _target_ be the value of _matchObj_\[_expansionKey_\].
-> 1. Let _subpath_ be the substring of _matchKey_ starting at the
-> index of the length of _expansionKey_.
-> 1. Let _resolved_ be the result of **PACKAGE_TARGET_RESOLVE**(
-> _packageURL_, _target_, _subpath_, **false**, _isImports_,
-> _conditions_).
-> 1. Return the object _{ resolved, exact: **false** }_.
-> 1. Return the object _{ resolved: **null**, exact: **true** }_.
+> 1. Return the result of **PACKAGE_TARGET_RESOLVE**(_packageURL_,
+> _target_, _subpath_, **true**, _isImports_, _conditions_).
+> 1. Return **null**.
**PATTERN_KEY_COMPARE**(_keyA_, _keyB_)
diff --git a/doc/api/packages.md b/doc/api/packages.md
index e584eaf182b..30ff370d9d9 100644
--- a/doc/api/packages.md
+++ b/doc/api/packages.md
@@ -422,50 +422,6 @@ import featureX from 'es-module-package/features/x';
// Loads ./node_modules/es-module-package/src/features/x.js
```
-### Subpath folder mappings
-<!-- YAML
-changes:
- - version: v16.0.0
- pr-url: https://github.com/nodejs/node/pull/37215
- description: Runtime deprecation.
- - version: v15.1.0
- pr-url: https://github.com/nodejs/node/pull/35747
- description: Runtime deprecation for self-referencing imports.
- - version:
- - v14.13.0
- - v12.20.0
- pr-url: https://github.com/nodejs/node/pull/34718
- description: Documentation-only deprecation.
--->
-
-> Stability: 0 - Deprecated: Use subpath patterns instead.
-
-Before subpath patterns were supported, a trailing `"/"` suffix was used to
-support folder mappings:
-
-```json
-{
- "exports": {
- "./features/": "./features/"
- }
-}
-```
-
-_This feature will be removed in a future release._
-
-Instead, use direct [subpath patterns][]:
-
-```json
-{
- "exports": {
- "./features/*": "./features/*.js"
- }
-}
-```
-
-The benefit of patterns over folder exports is that packages can always be
-imported by consumers without subpath file extensions being necessary.
-
### Exports sugar
<!-- YAML
added: v12.11.0
@@ -1270,7 +1226,6 @@ This field defines [subpath imports][] for the current package.
[self-reference]: #self-referencing-a-package-using-its-name
[subpath exports]: #subpath-exports
[subpath imports]: #subpath-imports
-[subpath patterns]: #subpath-patterns
[supported package managers]: corepack.md#supported-package-managers
[the dual CommonJS/ES module packages section]: #dual-commonjses-module-packages
[the full specifier path]: esm.md#mandatory-file-extensions
diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js
index b8eff044062..622805ea78f 100644
--- a/lib/internal/modules/cjs/loader.js
+++ b/lib/internal/modules/cjs/loader.js
@@ -457,7 +457,7 @@ function trySelf(parentPath, request) {
try {
return finalizeEsmResolution(packageExportsResolve(
pathToFileURL(pkgPath + '/package.json'), expansion, pkg,
- pathToFileURL(parentPath), cjsConditions), request, parentPath, pkgPath);
+ pathToFileURL(parentPath), cjsConditions), parentPath, pkgPath);
} catch (e) {
if (e.code === 'ERR_MODULE_NOT_FOUND')
throw createEsmNotFoundErr(request, pkgPath + '/package.json');
@@ -481,7 +481,7 @@ function resolveExports(nmPath, request) {
try {
return finalizeEsmResolution(packageExportsResolve(
pathToFileURL(pkgPath + '/package.json'), '.' + expansion, pkg, null,
- cjsConditions), request, null, pkgPath);
+ cjsConditions), null, pkgPath);
} catch (e) {
if (e.code === 'ERR_MODULE_NOT_FOUND')
throw createEsmNotFoundErr(request, pkgPath + '/package.json');
@@ -894,7 +894,7 @@ Module._resolveFilename = function(request, parent, isMain, options) {
try {
return finalizeEsmResolution(
packageImportsResolve(request, pathToFileURL(parent.filename),
- cjsConditions), request, parent.filename,
+ cjsConditions), parent.filename,
pkg.path);
} catch (e) {
if (e.code === 'ERR_MODULE_NOT_FOUND')
@@ -936,18 +936,12 @@ Module._resolveFilename = function(request, parent, isMain, options) {
throw err;
};
-function finalizeEsmResolution(match, request, parentPath, pkgPath) {
- const { resolved, exact } = match;
+function finalizeEsmResolution(resolved, parentPath, pkgPath) {
if (RegExpPrototypeTest(encodedSepRegEx, resolved))
throw new ERR_INVALID_MODULE_SPECIFIER(
resolved, 'must not include encoded "/" or "\\" characters', parentPath);
const filename = fileURLToPath(resolved);
- let actual = tryFile(filename);
- if (!exact && !actual) {
- const exts = ObjectKeys(Module._extensions);
- actual = tryExtensions(filename, exts, false) ||
- tryPackage(filename, exts, false, request);
- }
+ const actual = tryFile(filename);
if (actual)
return actual;
const err = createEsmNotFoundErr(filename,
diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js
index dcb7d10a479..1a28f994ec6 100644
--- a/lib/internal/modules/esm/resolve.js
+++ b/lib/internal/modules/esm/resolve.js
@@ -19,6 +19,7 @@ const {
StringPrototypeIncludes,
StringPrototypeIndexOf,
StringPrototypeLastIndexOf,
+ StringPrototypeReplace,
StringPrototypeSlice,
StringPrototypeSplit,
StringPrototypeStartsWith,
@@ -82,38 +83,15 @@ const DEFAULT_CONDITIONS_SET = new SafeSet(DEFAULT_CONDITIONS);
const emittedPackageWarnings = new SafeSet();
-/**
- * @param {string} match
- * @param {URL} pjsonUrl
- * @param {boolean} isExports
- * @param {string | URL | undefined} base
- * @returns {void}
- */
-function emitFolderMapDeprecation(match, pjsonUrl, isExports, base) {
+function emitTrailingSlashPatternDeprecation(match, pjsonUrl, base) {
const pjsonPath = fileURLToPath(pjsonUrl);
-
if (emittedPackageWarnings.has(pjsonPath + '|' + match))
return;
emittedPackageWarnings.add(pjsonPath + '|' + match);
process.emitWarning(
- `Use of deprecated folder mapping "${match}" in the ${isExports ?
- '"exports"' : '"imports"'} field module resolution of the package at ${
- pjsonPath}${base ? ` imported from ${fileURLToPath(base)}` : ''}.\n` +
- `Update this package.json to use a subpath pattern like "${match}*".`,
- 'DeprecationWarning',
- 'DEP0148'
- );
-}
-
-function emitTrailingSlashPatternDeprecation(match, pjsonUrl, isExports, base) {
- const pjsonPath = fileURLToPath(pjsonUrl);
- if (emittedPackageWarnings.has(pjsonPath + '|' + match))
- return;
- emittedPackageWarnings.add(pjsonPath + '|' + match);
- process.emitWarning(
- `Use of deprecated trailing slash pattern mapping "${match}" in the ${
- isExports ? '"exports"' : '"imports"'} field module resolution of the ` +
- `package at ${pjsonPath}${base ? ` imported from ${fileURLToPath(base)}` :
+ `Use of deprecated trailing slash pattern mapping "${match}" in the ` +
+ `"exports" field module resolution of the package at ${pjsonPath}${
+ base ? ` imported from ${fileURLToPath(base)}` :
''}. Mapping specifiers ending in "/" is no longer supported.`,
'DeprecationWarning',
'DEP0155'
@@ -504,8 +482,11 @@ function resolvePackageTargetString(
if (subpath === '') return resolved;
- if (RegExpPrototypeTest(invalidSegmentRegEx, subpath))
- throwInvalidSubpath(match + subpath, packageJSONUrl, internal, base);
+ if (RegExpPrototypeTest(invalidSegmentRegEx, subpath)) {
+ const request = pattern ?
+ StringPrototypeReplace(match, '*', () => subpath) : match + subpath;
+ throwInvalidSubpath(request, packageJSONUrl, internal, base);
+ }
if (pattern)
return new URL(RegExpPrototypeSymbolReplace(patternRegEx, resolved.href,
@@ -641,7 +622,7 @@ function packageExportsResolve(
);
if (resolved === null || resolved === undefined)
throwExportsNotFound(packageSubpath, packageJSONUrl, base);
- return { resolved, exact: true };
+ return resolved;
}
let bestMatch = '';
@@ -653,9 +634,15 @@ function packageExportsResolve(
if (patternIndex !== -1 &&
StringPrototypeStartsWith(packageSubpath,
StringPrototypeSlice(key, 0, patternIndex))) {
+ // When this reaches EOL, this can throw at the top of the whole function:
+ //
+ // if (StringPrototypeEndsWith(packageSubpath, '/'))
+ // throwInvalidSubpath(packageSubpath)
+ //
+ // To match "imports" and the spec.
if (StringPrototypeEndsWith(packageSubpath, '/'))
emitTrailingSlashPatternDeprecation(packageSubpath, packageJSONUrl,
- true, base);
+ base);
const patternTrailer = StringPrototypeSlice(key, patternIndex + 1);
if (packageSubpath.length >= key.length &&
StringPrototypeEndsWith(packageSubpath, patternTrailer) &&
@@ -666,25 +653,17 @@ function packageExportsResolve(
packageSubpath, patternIndex,
packageSubpath.length - patternTrailer.length);
}
- } else if (key[key.length - 1] === '/' &&
- StringPrototypeStartsWith(packageSubpath, key) &&
- patternKeyCompare(bestMatch, key) === 1) {
- bestMatch = key;
- bestMatchSubpath = StringPrototypeSlice(packageSubpath, key.length);
}
}
if (bestMatch) {
const target = exports[bestMatch];
- const pattern = StringPrototypeIncludes(bestMatch, '*');
const resolved = resolvePackageTarget(packageJSONUrl, target,
bestMatchSubpath, bestMatch, base,
- pattern, false, conditions);
+ true, false, conditions);
if (resolved === null || resolved === undefined)
throwExportsNotFound(packageSubpath, packageJSONUrl, base);
- if (!pattern)
- emitFolderMapDeprecation(bestMatch, packageJSONUrl, true, base);
- return { resolved, exact: pattern };
+ return resolved;
}
throwExportsNotFound(packageSubpath, packageJSONUrl, base);
@@ -711,7 +690,8 @@ function patternKeyCompare(a, b) {
* @returns
*/
function packageImportsResolve(name, base, conditions) {
- if (name === '#' || StringPrototypeStartsWith(name, '#/')) {
+ if (name === '#' || StringPrototypeStartsWith(name, '#/') ||
+ StringPrototypeEndsWith(name, '/')) {
const reason = 'is not a valid internal imports specifier name';
throw new ERR_INVALID_MODULE_SPECIFIER(name, reason, fileURLToPath(base));
}
@@ -722,13 +702,12 @@ function packageImportsResolve(name, base, conditions) {
const imports = packageConfig.imports;
if (imports) {
if (ObjectPrototypeHasOwnProperty(imports, name) &&
- !StringPrototypeIncludes(name, '*') &&
- !StringPrototypeEndsWith(name, '/')) {
+ !StringPrototypeIncludes(name, '*')) {
const resolved = resolvePackageTarget(
packageJSONUrl, imports[name], '', name, base, false, true, conditions
);
- if (resolved !== null)
- return { resolved, exact: true };
+ if (resolved !== null && resolved !== undefined)
+ return resolved;
} else {
let bestMatch = '';
let bestMatchSubpath;
@@ -749,26 +728,16 @@ function packageImportsResolve(name, base, conditions) {
bestMatchSubpath = StringPrototypeSlice(
name, patternIndex, name.length - patternTrailer.length);
}
- } else if (key[key.length - 1] === '/' &&
- StringPrototypeStartsWith(name, key) &&
- patternKeyCompare(bestMatch, key) === 1) {
- bestMatch = key;
- bestMatchSubpath = StringPrototypeSlice(name, key.length);
}
}
if (bestMatch) {
const target = imports[bestMatch];
- const pattern = StringPrototypeIncludes(bestMatch, '*');
const resolved = resolvePackageTarget(packageJSONUrl, target,
bestMatchSubpath, bestMatch,
- base, pattern, true,
- conditions);
- if (resolved !== null) {
- if (!pattern)
- emitFolderMapDeprecation(bestMatch, packageJSONUrl, false, base);
- return { resolved, exact: pattern };
- }
+ base, true, true, conditions);
+ if (resolved !== null && resolved !== undefined)
+ return resolved;
}
}
}
@@ -845,7 +814,7 @@ function packageResolve(specifier, base, conditions) {
packageConfig.exports !== undefined && packageConfig.exports !== null) {
return packageExportsResolve(
packageJSONUrl, packageSubpath, packageConfig, base, conditions
- ).resolved;
+ );
}
}
@@ -870,7 +839,7 @@ function packageResolve(specifier, base, conditions) {
if (packageConfig.exports !== undefined && packageConfig.exports !== null)
return packageExportsResolve(
packageJSONUrl, packageSubpath, packageConfig, base, conditions
- ).resolved;
+ );
if (packageSubpath === '.')
return legacyMainResolve(packageJSONUrl, packageConfig, base);
return new URL(packageSubpath, packageJSONUrl);
@@ -919,7 +888,7 @@ function moduleResolve(specifier, base, conditions) {
if (shouldBeTreatedAsRelativeOrAbsolutePath(specifier)) {
resolved = new URL(specifier, base);
} else if (specifier[0] === '#') {
- ({ resolved } = packageImportsResolve(specifier, base, conditions));
+ resolved = packageImportsResolve(specifier, base, conditions);
} else {
try {
resolved = new URL(specifier);
diff --git a/test/es-module/test-esm-exports-deprecations.mjs b/test/es-module/test-esm-exports-deprecations.mjs
index fd92dd3d78d..5523af286bc 100644
--- a/test/es-module/test-esm-exports-deprecations.mjs
+++ b/test/es-module/test-esm-exports-deprecations.mjs
@@ -3,12 +3,7 @@ import assert from 'assert';
let curWarning = 0;
const expectedWarnings = [
- '"./sub/"',
- '"./fallbackdir/"',
'"./trailing-pattern-slash/"',
- '"./subpath/"',
- '"./subpath/dir1/"',
- '"./subpath/dir2/"',
'no_exports',
'default_index',
];
diff --git a/test/es-module/test-esm-exports.mjs b/test/es-module/test-esm-exports.mjs
index 11323351b65..e6182a16e73 100644
--- a/test/es-module/test-esm-exports.mjs
+++ b/test/es-module/test-esm-exports.mjs
@@ -11,8 +11,6 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js';
const validSpecifiers = new Map([
// A simple mapping of a path.
['pkgexports/valid-cjs', { default: 'asdf' }],
- // A directory mapping, pointing to the package root.
- ['pkgexports/sub/asdf.js', { default: 'asdf' }],
// A mapping pointing to a file that needs special encoding (%20) in URLs.
['pkgexports/space', { default: 'encoded path' }],
// Verifying that normal packages still work with exports turned on.
@@ -47,15 +45,7 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js';
{ default: 'trailing-pattern-slash' }],
]);
- if (isRequire) {
- validSpecifiers.set('pkgexports/subpath/file', { default: 'file' });
- validSpecifiers.set('pkgexports/subpath/dir1', { default: 'main' });
- // Deprecated:
- validSpecifiers.set('pkgexports/subpath/dir1/', { default: 'main' });
- validSpecifiers.set('pkgexports/subpath/dir2', { default: 'index' });
- // Deprecated:
- validSpecifiers.set('pkgexports/subpath/dir2/', { default: 'index' });
- } else {
+ if (!isRequire) {
// No exports or main field
validSpecifiers.set('no_exports', { default: 'index' });
// Main field without extension
@@ -93,8 +83,6 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js';
]);
const invalidExports = new Map([
- // Directory mappings require a trailing / to work
- ['pkgexports/missingtrailer/x', './missingtrailer/'],
// This path steps back inside the package but goes through an exports
// target that escapes the package, so we still catch that as invalid
['pkgexports/belowdir/pkgexports/asdf.js', './belowdir/'],
@@ -171,7 +159,6 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js';
strictEqual(err.code, 'ERR_UNSUPPORTED_DIR_IMPORT');
assertStartsWith(err.message, 'Directory import');
};
- notFoundExports.set('pkgexports/subpath/file', 'pkgexports/subpath/file');
loadFixture('pkgexports/subpath/dir1').catch(mustCall(onDirectoryImport));
loadFixture('pkgexports/subpath/dir2').catch(mustCall(onDirectoryImport));
}
diff --git a/test/es-module/test-esm-imports.mjs b/test/es-module/test-esm-imports.mjs
index 577e33b60d0..9dc78199012 100644
--- a/test/es-module/test-esm-imports.mjs
+++ b/test/es-module/test-esm-imports.mjs
@@ -34,8 +34,6 @@ const { requireImport, importImport } = importer;
}
const invalidImportTargets = new Set([
- // External subpath import without trailing slash
- ['#external/invalidsubpath/x', '#external/invalidsubpath/'],
// Target steps below the package base
['#belowbase', '#belowbase'],
// Target is a URL
@@ -73,6 +71,8 @@ const { requireImport, importImport } = importer;
}
const undefinedImports = new Set([
+ // EOL subpaths
+ '#external/invalidsubpath/x',
// Missing import
'#missing',
// Explicit null import
diff --git a/test/es-module/test-esm-local-deprecations.mjs b/test/es-module/test-esm-local-deprecations.mjs
deleted file mode 100644
index a9030b40912..00000000000
--- a/test/es-module/test-esm-local-deprecations.mjs
+++ /dev/null
@@ -1,37 +0,0 @@
-import '../common/index.mjs';
-import assert from 'assert';
-import fixtures from '../common/fixtures.js';
-import { pathToFileURL } from 'url';
-
-const selfDeprecatedFolders =
- fixtures.path('/es-modules/self-deprecated-folders/main.js');
-
-const deprecatedFoldersIgnore =
- fixtures.path('/es-modules/deprecated-folders-ignore/main.js');
-
-const deprecatedTrailingSlashPattern =
- fixtures.path('/es-modules/pattern-trailing-slash.mjs');
-
-const expectedWarnings = [
- '"./" in the "exports" field',
- '"#self/" in the "imports" field',
- '"./folder/" in the "exports" field',
- '"./trailing-pattern-slash/" in the "exports" field',
-];
-
-process.addListener('warning', (warning) => {
- if (warning.stack.includes(expectedWarnings[0])) {
- expectedWarnings.shift();
- }
-});
-
-process.on('exit', () => {
- assert.deepStrictEqual(expectedWarnings, []);
-});
-
-(async () => {
- await import(pathToFileURL(selfDeprecatedFolders));
- await import(pathToFileURL(deprecatedFoldersIgnore));
- await import(pathToFileURL(deprecatedTrailingSlashPattern));
-})()
-.catch((err) => console.error(err));
diff --git a/test/fixtures/es-modules/pkgimports/package.json b/test/fixtures/es-modules/pkgimports/package.json
index 299ce9c197b..cebe36b350f 100644
--- a/test/fixtures/es-modules/pkgimports/package.json
+++ b/test/fixtures/es-modules/pkgimports/package.json
@@ -22,7 +22,7 @@
},
"default": "./test.js"
},
- "#subpath/nullshadow/": [null],
+ "#subpath/nullshadow/*": [null],
"#": "./test.js",
"#/initialslash": "./test.js",
"#notfound": "./notfound.js",
diff --git a/test/fixtures/node_modules/pkgexports/package.json b/test/fixtures/node_modules/pkgexports/package.json
index fe46111f793..b686257875b 100644
--- a/test/fixtures/node_modules/pkgexports/package.json
+++ b/test/fixtures/node_modules/pkgexports/package.json
@@ -4,10 +4,9 @@
"./hole": "./lib/hole.js",
"./space": "./sp%20ce.js",
"./valid-cjs": "./asdf.js",
- "./sub/": "./",
- "./belowdir/": "../belowdir/",
+ "./sub/*": "./*",
+ "./belowdir/*": "../belowdir/*",
"./belowfile": "../belowfile",
- "./missingtrailer/": ".",
"./null": null,
"./null/": null,
"./invalid1": {},
@@ -15,7 +14,7 @@
"./invalid3": "",
"./invalid4": {},
"./invalid5": "invalid5.js",
- "./fallbackdir/": [[], null, {}, "builtin:x/", "./fallbackfile", "./"],
+ "./fallbackdir/*": [[], null, {}, "builtin:x/*", "./*"],
"./fallbackfile": [[], null, {}, "builtin:x", "./asdf.js"],
"./nofallback1": [],
"./nofallback2": [null, {}, "builtin:x"],
@@ -58,7 +57,7 @@
"./a/*": "./subpath/*.js",
"./a/b/": "./nomatch/",
"./a/b*": "./subpath*.js",
- "./subpath/": "./subpath/",
+ "./subpath/*": "./subpath/*",
"./subpath/sub-*": "./subpath/dir1/*.js",
"./subpath/sub-*.js": "./subpath/dir1/*.js",
"./features/*": "./subpath/*/*.js",