mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
module: share CJS/ESM resolver fns, refactoring
PR-URL: https://github.com/nodejs/node/pull/34744 Reviewed-By: Jan Krems <jan.krems@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
295
doc/api/esm.md
295
doc/api/esm.md
@@ -1631,7 +1631,7 @@ future updates.
|
||||
In the following algorithms, all subroutine errors are propagated as errors
|
||||
of these top-level routines unless stated otherwise.
|
||||
|
||||
_defaultEnv_ is the conditional environment name priority array,
|
||||
_defaultConditions_ is the conditional environment name array,
|
||||
`["node", "import"]`.
|
||||
|
||||
The resolver can throw the following errors:
|
||||
@@ -1651,40 +1651,41 @@ The resolver can throw the following errors:
|
||||
|
||||
**ESM_RESOLVE**(_specifier_, _parentURL_)
|
||||
|
||||
> 1. Let _resolvedURL_ be **undefined**.
|
||||
> 1. Let _resolved_ be **undefined**.
|
||||
> 1. If _specifier_ is a valid URL, then
|
||||
> 1. Set _resolvedURL_ to the result of parsing and reserializing
|
||||
> 1. Set _resolved_ to the result of parsing and reserializing
|
||||
> _specifier_ as a URL.
|
||||
> 1. Otherwise, if _specifier_ starts with _"/"_, _"./"_ or _"../"_, then
|
||||
> 1. Set _resolvedURL_ to the URL resolution of _specifier_ relative to
|
||||
> 1. Set _resolved_ to the URL resolution of _specifier_ relative to
|
||||
> _parentURL_.
|
||||
> 1. Otherwise, if _specifier_ starts with _"#"_, then
|
||||
> 1. Set _resolvedURL_ to the result of
|
||||
> **PACKAGE_INTERNAL_RESOLVE**(_specifier_, _parentURL_).
|
||||
> 1. If _resolvedURL_ is **null** or **undefined**, throw a
|
||||
> _Package Import Not Defined_ error.
|
||||
> 1. Set _resolved_ to the destructured value of the result of
|
||||
> **PACKAGE_IMPORTS_RESOLVE**(_specifier_, _parentURL_,
|
||||
> _defaultConditions_).
|
||||
> 1. Otherwise,
|
||||
> 1. Note: _specifier_ is now a bare specifier.
|
||||
> 1. Set _resolvedURL_ the result of
|
||||
> 1. Set _resolved_ the result of
|
||||
> **PACKAGE_RESOLVE**(_specifier_, _parentURL_).
|
||||
> 1. If _resolvedURL_ contains any percent encodings of _"/"_ or _"\\"_ (_"%2f"_
|
||||
> 1. If _resolved_ contains any percent encodings of _"/"_ or _"\\"_ (_"%2f"_
|
||||
> and _"%5C"_ respectively), then
|
||||
> 1. Throw an _Invalid Module Specifier_ error.
|
||||
> 1. If the file at _resolvedURL_ is a directory, then
|
||||
> 1. If the file at _resolved_ is a directory, then
|
||||
> 1. Throw an _Unsupported Directory Import_ error.
|
||||
> 1. If the file at _resolvedURL_ does not exist, then
|
||||
> 1. If the file at _resolved_ does not exist, then
|
||||
> 1. Throw a _Module Not Found_ error.
|
||||
> 1. Set _resolvedURL_ to the real path of _resolvedURL_.
|
||||
> 1. Let _format_ be the result of **ESM_FORMAT**(_resolvedURL_).
|
||||
> 1. Load _resolvedURL_ as module format, _format_.
|
||||
> 1. Return _resolvedURL_.
|
||||
> 1. Set _resolved_ to the real path of _resolved_.
|
||||
> 1. Let _format_ be the result of **ESM_FORMAT**(_resolved_).
|
||||
> 1. Load _resolved_ as module format, _format_.
|
||||
> 1. Return _resolved_.
|
||||
|
||||
**PACKAGE_RESOLVE**(_packageSpecifier_, _parentURL_)
|
||||
|
||||
> 1. Let _packageName_ be *undefined*.
|
||||
> 1. Let _packageSubpath_ be *undefined*.
|
||||
> 1. Let _packageName_ be **undefined**.
|
||||
> 1. If _packageSpecifier_ is an empty string, then
|
||||
> 1. Throw an _Invalid Module Specifier_ error.
|
||||
> 1. If _packageSpecifier_ does not start with _"@"_, then
|
||||
> 1. Set _packageName_ to the substring of _packageSpecifier_ until the first
|
||||
> _"/"_ separator or the end of the string.
|
||||
> 1. Otherwise,
|
||||
> 1. If _packageSpecifier_ does not contain a _"/"_ separator, then
|
||||
> 1. Throw an _Invalid Module Specifier_ error.
|
||||
@@ -1692,18 +1693,12 @@ The resolver can throw the following errors:
|
||||
> until the second _"/"_ separator or the end of the string.
|
||||
> 1. If _packageName_ starts with _"."_ or contains _"\\"_ or _"%"_, then
|
||||
> 1. Throw an _Invalid Module Specifier_ error.
|
||||
> 1. Let _packageSubpath_ be _undefined_.
|
||||
> 1. If the length of _packageSpecifier_ is greater than the length of
|
||||
> _packageName_, then
|
||||
> 1. Set _packageSubpath_ to _"."_ concatenated with the substring of
|
||||
> 1. Let _packageSubpath_ be _"."_ concatenated with the substring of
|
||||
> _packageSpecifier_ from the position at the length of _packageName_.
|
||||
> 1. If _packageSubpath_ contains any _"."_ or _".."_ segments or percent
|
||||
> encoded strings for _"/"_ or _"\\"_, then
|
||||
> 1. Throw an _Invalid Module Specifier_ error.
|
||||
> 1. Let _selfUrl_ be the result of
|
||||
> **SELF_REFERENCE_RESOLVE**(_packageName_, _packageSubpath_, _parentURL_).
|
||||
> 1. If _selfUrl_ isn't empty, return _selfUrl_.
|
||||
> 1. If _packageSubpath_ is _undefined_ and _packageName_ is a Node.js builtin
|
||||
> **PACKAGE_SELF_RESOLVE**(_packageName_, _packageSubpath_, _parentURL_).
|
||||
> 1. If _selfUrl_ is not **undefined**, return _selfUrl_.
|
||||
> 1. If _packageSubpath_ is _"."_ and _packageName_ is a Node.js builtin
|
||||
> module, then
|
||||
> 1. Return the string _"nodejs:"_ concatenated with _packageSpecifier_.
|
||||
> 1. While _parentURL_ is not the file system root,
|
||||
@@ -1714,142 +1709,61 @@ The resolver can throw the following errors:
|
||||
> 1. Set _parentURL_ to the parent URL path of _parentURL_.
|
||||
> 1. Continue the next loop iteration.
|
||||
> 1. Let _pjson_ be the result of **READ_PACKAGE_JSON**(_packageURL_).
|
||||
> 1. If _packageSubpath_ is equal to _"./"_, then
|
||||
> 1. Return _packageURL_ + _"/"_.
|
||||
> 1. If _packageSubpath_ is _undefined__, then
|
||||
> 1. Return the result of **PACKAGE_MAIN_RESOLVE**(_packageURL_,
|
||||
> _pjson_).
|
||||
> 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. Otherwise, if _packageSubpath_ is equal to _"."_, then
|
||||
> 1. Return the result applying the legacy **LOAD_AS_DIRECTORY**
|
||||
> CommonJS resolver to _packageURL_, throwing a _Module Not Found_
|
||||
> error for no resolution.
|
||||
> 1. Otherwise,
|
||||
> 1. If _pjson_ is not **null** and _pjson_ has an _"exports"_ key, then
|
||||
> 1. Let _exports_ be _pjson.exports_.
|
||||
> 1. If _exports_ is not **null** or **undefined**, then
|
||||
> 1. Let _resolved_ be the result of **PACKAGE_EXPORTS_RESOLVE**(
|
||||
> _packageURL_, _packageSubpath_, _pjson.exports_).
|
||||
> 1. If _resolved_ is **null** or **undefined**, throw a
|
||||
> _Package Path Not Exported_ error.
|
||||
> 1. Return _resolved_.
|
||||
> 1. Return the URL resolution of _packageSubpath_ in _packageURL_.
|
||||
> 1. Throw a _Module Not Found_ error.
|
||||
|
||||
**SELF_REFERENCE_RESOLVE**(_packageName_, _packageSubpath_, _parentURL_)
|
||||
**PACKAGE_SELF_RESOLVE**(_packageName_, _packageSubpath_, _parentURL_)
|
||||
|
||||
> 1. Let _packageURL_ be the result of **READ_PACKAGE_SCOPE**(_parentURL_).
|
||||
> 1. If _packageURL_ is **null**, then
|
||||
> 1. Return **undefined**.
|
||||
> 1. Let _pjson_ be the result of **READ_PACKAGE_JSON**(_packageURL_).
|
||||
> 1. If _pjson_ does not include an _"exports"_ property, then
|
||||
> 1. If _pjson_ is **null** or if _pjson_._exports_ is **null** or
|
||||
> **undefined**, then
|
||||
> 1. Return **undefined**.
|
||||
> 1. If _pjson.name_ is equal to _packageName_, then
|
||||
> 1. If _packageSubpath_ is equal to _"./"_, then
|
||||
> 1. Return _packageURL_ + _"/"_.
|
||||
> 1. If _packageSubpath_ is _undefined_, then
|
||||
> 1. Return the result of **PACKAGE_MAIN_RESOLVE**(_packageURL_, _pjson_).
|
||||
> 1. Otherwise,
|
||||
> 1. If _pjson_ is not **null** and _pjson_ has an _"exports"_ key, then
|
||||
> 1. Let _exports_ be _pjson.exports_.
|
||||
> 1. If _exports_ is not **null** or **undefined**, then
|
||||
> 1. Let _resolved_ be the result of **PACKAGE_EXPORTS_RESOLVE**(
|
||||
> _packageURL_, _subpath_, _pjson.exports_).
|
||||
> 1. If _resolved_ is **null** or **undefined**, throw a
|
||||
> _Package Path Not Exported_ error.
|
||||
> 1. Return _resolved_.
|
||||
> 1. Return the URL resolution of _subpath_ in _packageURL_.
|
||||
> 1. Return the _resolved_ destructured value of the result of
|
||||
> **PACKAGE_EXPORTS_RESOLVE**(_packageURL_, _subpath_, _pjson.exports_,
|
||||
> _defaultConditions_).
|
||||
> 1. Otherwise, return **undefined**.
|
||||
|
||||
**PACKAGE_MAIN_RESOLVE**(_packageURL_, _pjson_)
|
||||
**PACKAGE_EXPORTS_RESOLVE**(_packageURL_, _subpath_, _exports_, _conditions_)
|
||||
|
||||
> 1. If _pjson_ is **null**, then
|
||||
> 1. Throw a _Module Not Found_ error.
|
||||
> 1. If _pjson.exports_ is not **null** or **undefined**, then
|
||||
> 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 _pjson.exports_ is a String or Array, or an Object containing no
|
||||
> keys starting with _"."_, then
|
||||
> 1. Let _resolved_ be the result of **PACKAGE_TARGET_RESOLVE**(
|
||||
> _packageURL_, _pjson.exports_, _""_, **false**, _defaultEnv_).
|
||||
> 1. If _resolved_ is **null** or **undefined**, throw a
|
||||
> _Package Path Not Exported_ error.
|
||||
> 1. Return _resolved_.
|
||||
> 1. If _pjson.exports_ is an Object containing a _"."_ property, then
|
||||
> 1. Let _mainExport_ be the _"."_ property in _pjson.exports_.
|
||||
> 1. Let _resolved_ be the result of **PACKAGE_TARGET_RESOLVE**(
|
||||
> _packageURL_, _mainExport_, _""_, **false**, _defaultEnv_).
|
||||
> 1. If _resolved_ is **null** or **undefined**, throw a
|
||||
> _Package Path Not Exported_ error.
|
||||
> 1. Return _resolved_.
|
||||
> 1. Throw a _Package Path Not Exported_ error.
|
||||
> 1. Let _legacyMainURL_ be the result applying the legacy
|
||||
> **LOAD_AS_DIRECTORY** CommonJS resolver to _packageURL_, throwing a
|
||||
> _Module Not Found_ error for no resolution.
|
||||
> 1. Return _legacyMainURL_.
|
||||
|
||||
**PACKAGE_EXPORTS_RESOLVE**(_packageURL_, _packagePath_, _exports_)
|
||||
> 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 _exports_ is an Object and all keys of _exports_ start with _"."_, then
|
||||
> 1. Set _packagePath_ to _"./"_ concatenated with _packagePath_.
|
||||
> 1. If _packagePath_ is a key of _exports_, then
|
||||
> 1. Let _target_ be the value of _exports\[packagePath\]_.
|
||||
> 1. Return **PACKAGE_TARGET_RESOLVE**(_packageURL_, _target_,
|
||||
> _""_, **false**, _defaultEnv_).
|
||||
> 1. Let _directoryKeys_ be the list of keys of _exports_ ending in
|
||||
> _"/"_, sorted by length descending.
|
||||
> 1. For each key _directory_ in _directoryKeys_, do
|
||||
> 1. If _packagePath_ starts with _directory_, then
|
||||
> 1. Let _target_ be the value of _exports\[directory\]_.
|
||||
> 1. Let _subpath_ be the substring of _target_ starting at the index
|
||||
> of the length of _directory_.
|
||||
> 1. Return **PACKAGE_TARGET_RESOLVE**(_packageURL_, _target_,
|
||||
> _subpath_, **false**, _defaultEnv_).
|
||||
> 1. Return **null**.
|
||||
|
||||
**PACKAGE_TARGET_RESOLVE**(_packageURL_, _target_, _subpath_, _internal_, _env_)
|
||||
|
||||
> 1. If _target_ is a String, then
|
||||
> 1. If _target_ contains any _"node_modules"_ segments including
|
||||
> _"node_modules"_ percent-encoding, throw an _Invalid Package Target_
|
||||
> error.
|
||||
> 1. If _subpath_ has non-zero length and _target_ does not end with _"/"_,
|
||||
> throw an _Invalid Module Specifier_ error.
|
||||
> 1. If _target_ does not start with _"./"_, then
|
||||
> 1. If _target_ does not start with _"../"_ or _"/"_ and is not a valid
|
||||
> URL, then
|
||||
> 1. If _internal_ is **true**, return **PACKAGE_RESOLVE**(
|
||||
> _target_ + _subpath_, _packageURL_ + _"/"_)_.
|
||||
> 1. Otherwise throw an _Invalid Package Target_ error.
|
||||
> 1. Let _resolvedTarget_ be the URL resolution of the concatenation of
|
||||
> _packageURL_ and _target_.
|
||||
> 1. If _resolvedTarget_ is not contained in _packageURL_, throw an
|
||||
> _Invalid Package Target_ error.
|
||||
> 1. Let _resolved_ be the URL resolution of the concatenation of
|
||||
> _subpath_ and _resolvedTarget_.
|
||||
> 1. If _resolved_ is not contained in _resolvedTarget_, throw an
|
||||
> _Invalid Module Specifier_ error.
|
||||
> 1. Return _resolved_.
|
||||
> 1. Otherwise, if _target_ is a non-null Object, then
|
||||
> 1. If _exports_ contains any index property keys, as defined in ECMA-262
|
||||
> [6.1.7 Array Index][], throw an _Invalid Package Configuration_ error.
|
||||
> 1. For each property _p_ of _target_, in object insertion order as,
|
||||
> 1. If _p_ equals _"default"_ or _env_ contains an entry for _p_, then
|
||||
> 1. Let _targetValue_ be the value of the _p_ property in _target_.
|
||||
> 1. Let _resolved_ be the result of **PACKAGE_TARGET_RESOLVE**(
|
||||
> _packageURL_, _targetValue_, _subpath_, _internal_, _env_)
|
||||
> 1. If _resolved_ is equal to **undefined**, continue the loop.
|
||||
> 1. Return _resolved_.
|
||||
> 1. Return **undefined**.
|
||||
> 1. Otherwise, if _target_ is an Array, then
|
||||
> 1. If _target.length is zero, return **null**.
|
||||
> 1. For each item _targetValue_ in _target_, do
|
||||
> 1. If _subpath_ is equal to _"."_, then
|
||||
> 1. Let _mainExport_ be **undefined**.
|
||||
> 1. If _exports_ is a String or Array, or an Object containing no keys
|
||||
> starting with _"."_, then
|
||||
> 1. Set _mainExport_ to _exports_.
|
||||
> 1. Otherwise if _exports_ is an Object containing a _"."_ property, then
|
||||
> 1. Set _mainExport_ to _exports_\[_"."_\].
|
||||
> 1. If _mainExport_ is not **undefined**, then
|
||||
> 1. Let _resolved_ be the result of **PACKAGE_TARGET_RESOLVE**(
|
||||
> _packageURL_, _targetValue_, _subpath_, _internal_, _env_),
|
||||
> continuing the loop on any _Invalid Package Target_ error.
|
||||
> 1. If _resolved_ is **undefined**, continue the loop.
|
||||
> 1. Return _resolved_.
|
||||
> 1. Return or throw the last fallback resolution **null** return or error.
|
||||
> 1. Otherwise, if _target_ is _null_, return **null**.
|
||||
> 1. Otherwise throw an _Invalid Package Target_ error.
|
||||
> _packageURL_, _mainExport_, _""_, **false**, _conditions_).
|
||||
> 1. If _resolved_ is not **null** or **undefined**, then
|
||||
> 1. 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**(
|
||||
> _matchKey_, _exports_, _packageURL_, **false**, _conditions_).
|
||||
> 1. If _resolvedMatch_._resolve_ is not **null** or **undefined**, then
|
||||
> 1. Return _resolvedMatch_.
|
||||
> 1. Throw a _Package Path Not Exported_ error.
|
||||
|
||||
**PACKAGE_INTERNAL_RESOLVE**(_specifier_, _parentURL_)
|
||||
**PACKAGE_IMPORTS_RESOLVE**(_specifier_, _parentURL_, _conditions_)
|
||||
|
||||
> 1. Assert: _specifier_ begins with _"#"_.
|
||||
> 1. If _specifier_ is exactly equal to _"#"_ or starts with _"#/"_, then
|
||||
@@ -1857,22 +1771,79 @@ The resolver can throw the following errors:
|
||||
> 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 _imports_ be _pjson.imports_.
|
||||
> 1. If _specifier_ is a key of _imports_, then
|
||||
> 1. Let _target_ be the value of _imports\[specifier\]_.
|
||||
> 1. Return **PACKAGE_TARGET_RESOLVE**(_packageURL_, _target_,
|
||||
> _""_, **true**, _defaultEnv_).
|
||||
> 1. Let _directoryKeys_ be the list of keys of _imports_ ending in
|
||||
> _"/"_, sorted by length descending.
|
||||
> 1. For each key _directory_ in _directoryKeys_, do
|
||||
> 1. If _specifier_ starts with _directory_, then
|
||||
> 1. Let _target_ be the value of _imports\[directory\]_.
|
||||
> 1. Let _subpath_ be the substring of _target_ starting at the
|
||||
> index of the length of _directory_.
|
||||
> 1. Return **PACKAGE_TARGET_RESOLVE**(_packageURL_, _target_,
|
||||
> _subpath_, **true**, _defaultEnv_).
|
||||
> 1. Return **null**.
|
||||
> 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. 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 _"*"_, then
|
||||
> 1. Let _target_ be the value of _matchObj_\[_matchKey_\].
|
||||
> 1. Let _resolved_ be the result of **PACKAGE_TARGET_RESOLVE**(
|
||||
> _packageURL_, _target_, _""_, _isImports_, _conditions_).
|
||||
> 1. Return the object _{ resolved, exact: **true** }_.
|
||||
> 1. Let _expansionKeys_ be the list of keys of _matchObj_ ending in _"/"_,
|
||||
> sorted by length descending.
|
||||
> 1. For each key _expansionKey_ in _expansionKeys_, do
|
||||
> 1. If _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_, _isImports_, _conditions_).
|
||||
> 1. Return the object _{ resolved, exact: **false** }_.
|
||||
> 1. Return the object _{ resolved: **null**, exact: **true** }_.
|
||||
|
||||
**PACKAGE_TARGET_RESOLVE**(_packageURL_, _target_, _subpath_, _internal_,
|
||||
_conditions_)
|
||||
|
||||
> 1. If _target_ is a String, then
|
||||
> 1. If _subpath_ has non-zero length and _target_ does not end with _"/"_,
|
||||
> throw an _Invalid Module Specifier_ error.
|
||||
> 1. If _target_ does not start with _"./"_, then
|
||||
> 1. If _internal_ is **true** and _target_ does not start with _"../"_ or
|
||||
> _"/"_ and is not a valid URL, then
|
||||
> 1. Return **PACKAGE_RESOLVE**(_target_ + _subpath_,
|
||||
> _packageURL_ + _"/"_)_.
|
||||
> 1. Otherwise, throw an _Invalid Package Target_ error.
|
||||
> 1. If _target_ split on _"/"_ or _"\\"_ contains any _"."_, _".."_ or
|
||||
> _"node_modules"_ segments after the first segment, throw an
|
||||
> _Invalid Module Specifier_ error.
|
||||
> 1. Let _resolvedTarget_ be the URL resolution of the concatenation of
|
||||
> _packageURL_ and _target_.
|
||||
> 1. Assert: _resolvedTarget_ is contained in _packageURL_.
|
||||
> 1. If _subpath_ split on _"/"_ or _"\\"_ contains any _"."_, _".."_ or
|
||||
> _"node_modules"_ segments, throw an _Invalid Module Specifier_ error.
|
||||
> 1. Return the URL resolution of the concatenation of _subpath_ and
|
||||
> _resolvedTarget_.
|
||||
> 1. Otherwise, if _target_ is a non-null Object, then
|
||||
> 1. If _exports_ contains any index property keys, as defined in ECMA-262
|
||||
> [6.1.7 Array Index][], throw an _Invalid Package Configuration_ error.
|
||||
> 1. For each property _p_ of _target_, in object insertion order as,
|
||||
> 1. If _p_ equals _"default"_ or _conditions_ contains an entry for _p_,
|
||||
> then
|
||||
> 1. Let _targetValue_ be the value of the _p_ property in _target_.
|
||||
> 1. Let _resolved_ be the result of **PACKAGE_TARGET_RESOLVE**(
|
||||
> _packageURL_, _targetValue_, _subpath_, _internal_, _conditions_).
|
||||
> 1. If _resolved_ is equal to **undefined**, continue the loop.
|
||||
> 1. Return _resolved_.
|
||||
> 1. Return **undefined**.
|
||||
> 1. Otherwise, if _target_ is an Array, then
|
||||
> 1. If _target.length is zero, return **null**.
|
||||
> 1. For each item _targetValue_ in _target_, do
|
||||
> 1. Let _resolved_ be the result of **PACKAGE_TARGET_RESOLVE**(
|
||||
> _packageURL_, _targetValue_, _subpath_, _internal_, _conditions_),
|
||||
> continuing the loop on any _Invalid Package Target_ error.
|
||||
> 1. If _resolved_ is **undefined**, continue the loop.
|
||||
> 1. Return _resolved_.
|
||||
> 1. Return or throw the last fallback resolution **null** return or error.
|
||||
> 1. Otherwise, if _target_ is _null_, return **null**.
|
||||
> 1. Otherwise throw an _Invalid Package Target_ error.
|
||||
|
||||
**ESM_FORMAT**(_url_)
|
||||
|
||||
|
||||
@@ -161,10 +161,10 @@ require(X) from module at path Y
|
||||
b. LOAD_AS_DIRECTORY(Y + X)
|
||||
c. THROW "not found"
|
||||
4. If X begins with '#'
|
||||
a. LOAD_INTERAL_IMPORT(X, Y)
|
||||
4. LOAD_SELF_REFERENCE(X, Y)
|
||||
5. LOAD_NODE_MODULES(X, dirname(Y))
|
||||
6. THROW "not found"
|
||||
a. LOAD_PACKAGE_IMPORTS(X, dirname(Y))
|
||||
5. LOAD_PACKAGE_SELF(X, dirname(Y))
|
||||
6. LOAD_NODE_MODULES(X, dirname(Y))
|
||||
7. THROW "not found"
|
||||
|
||||
LOAD_AS_FILE(X)
|
||||
1. If X is a file, load X as its file extension format. STOP
|
||||
@@ -191,7 +191,7 @@ LOAD_AS_DIRECTORY(X)
|
||||
LOAD_NODE_MODULES(X, START)
|
||||
1. let DIRS = NODE_MODULES_PATHS(START)
|
||||
2. for each DIR in DIRS:
|
||||
a. LOAD_PACKAGE_EXPORTS(DIR, X)
|
||||
a. LOAD_PACKAGE_EXPORTS(X, DIR)
|
||||
b. LOAD_AS_FILE(DIR/X)
|
||||
c. LOAD_AS_DIRECTORY(DIR/X)
|
||||
|
||||
@@ -206,47 +206,45 @@ NODE_MODULES_PATHS(START)
|
||||
d. let I = I - 1
|
||||
5. return DIRS
|
||||
|
||||
LOAD_SELF_REFERENCE(X, START)
|
||||
1. Find the closest package scope to START.
|
||||
LOAD_PACKAGE_IMPORTS(X, DIR)
|
||||
1. Find the closest package scope SCOPE to DIR.
|
||||
2. If no scope was found, return.
|
||||
3. If the `package.json` has no "exports", return.
|
||||
4. If the name in `package.json` is a prefix of X, then
|
||||
a. Load the remainder of X relative to this package as if it was
|
||||
loaded via `LOAD_NODE_MODULES` with a name in `package.json`.
|
||||
3. If the SCOPE/package.json "imports" is null or undefined, return.
|
||||
4. let MATCH = PACKAGE_IMPORTS_RESOLVE(X, pathToFileURL(SCOPE),
|
||||
["node", "require"]) defined in the ESM resolver.
|
||||
5. RESOLVE_ESM_MATCH(MATCH).
|
||||
|
||||
LOAD_PACKAGE_EXPORTS(DIR, X)
|
||||
1. Try to interpret X as a combination of name and subpath where the name
|
||||
LOAD_PACKAGE_EXPORTS(X, DIR)
|
||||
1. Try to interpret X as a combination of NAME and SUBPATH where the name
|
||||
may have a @scope/ prefix and the subpath begins with a slash (`/`).
|
||||
2. If X does not match this pattern or DIR/name/package.json is not a file,
|
||||
2. If X does not match this pattern or DIR/NAME/package.json is not a file,
|
||||
return.
|
||||
3. Parse DIR/name/package.json, and look for "exports" field.
|
||||
3. Parse DIR/NAME/package.json, and look for "exports" field.
|
||||
4. If "exports" is null or undefined, return.
|
||||
5. If "exports" is an object with some keys starting with "." and some keys
|
||||
not starting with ".", throw "invalid config".
|
||||
6. If "exports" is a string, or object with no keys starting with ".", treat
|
||||
it as having that value as its "." object property.
|
||||
7. If subpath is "." and "exports" does not have a "." entry, return.
|
||||
8. Find the longest key in "exports" that the subpath starts with.
|
||||
9. If no such key can be found, throw "not found".
|
||||
10. let RESOLVED =
|
||||
fileURLToPath(PACKAGE_EXPORTS_TARGET_RESOLVE(pathToFileURL(DIR/name),
|
||||
exports[key], subpath.slice(key.length), ["node", "require"])), as defined
|
||||
in the ESM resolver.
|
||||
11. If key ends with "/":
|
||||
a. LOAD_AS_FILE(RESOLVED)
|
||||
b. LOAD_AS_DIRECTORY(RESOLVED)
|
||||
12. Otherwise
|
||||
a. If RESOLVED is a file, load it as its file extension format. STOP
|
||||
13. Throw "not found"
|
||||
5. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(DIR/NAME), "." + SUBPATH,
|
||||
`package.json` "exports", ["node", "require"]) defined in the ESM resolver.
|
||||
6. RESOLVE_ESM_MATCH(MATCH)
|
||||
|
||||
LOAD_INTERNAL_IMPORT(X, START)
|
||||
1. Find the closest package scope to START.
|
||||
2. If no scope was found or the `package.json` has no "imports", return.
|
||||
3. let RESOLVED =
|
||||
fileURLToPath(PACKAGE_INTERNAL_RESOLVE(X, pathToFileURL(START)), as defined
|
||||
in the ESM resolver.
|
||||
4. If RESOLVED is not a valid file, throw "not found"
|
||||
5. Load RESOLVED as its file extension format. STOP
|
||||
LOAD_PACKAGE_SELF(X, DIR)
|
||||
1. Find the closest package scope SCOPE to DIR.
|
||||
2. If no scope was found, return.
|
||||
3. If the SCOPE/package.json "exports" is null or undefined, return.
|
||||
4. If the SCOPE/package.json "name" is not the first segment of X, return.
|
||||
5. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(SCOPE),
|
||||
"." + X.slice("name".length), `package.json` "exports", ["node", "require"])
|
||||
defined in the ESM resolver.
|
||||
6. RESOLVE_ESM_MATCH(MATCH)
|
||||
|
||||
RESOLVE_ESM_MATCH(MATCH)
|
||||
1. let { RESOLVED, EXACT } = MATCH
|
||||
2. let RESOLVED_PATH = fileURLToPath(RESOLVED)
|
||||
3. If EXACT is true,
|
||||
a. If the file at RESOLVED_PATH exists, load RESOLVED_PATH as its extension
|
||||
format. STOP
|
||||
4. Otherwise, if EXACT is false,
|
||||
a. LOAD_AS_FILE(RESOLVED_PATH)
|
||||
b. LOAD_AS_DIRECTORY(RESOLVED_PATH)
|
||||
5. THROW "not found"
|
||||
```
|
||||
|
||||
## Caching
|
||||
|
||||
@@ -26,8 +26,6 @@ const {
|
||||
WeakMap,
|
||||
} = primordials;
|
||||
|
||||
const sep = process.platform === 'win32' ? '\\' : '/';
|
||||
|
||||
const messages = new Map();
|
||||
const codes = {};
|
||||
|
||||
@@ -1120,10 +1118,9 @@ E('ERR_INVALID_OPT_VALUE', (name, value) =>
|
||||
RangeError);
|
||||
E('ERR_INVALID_OPT_VALUE_ENCODING',
|
||||
'The value "%s" is invalid for option "encoding"', TypeError);
|
||||
E('ERR_INVALID_PACKAGE_CONFIG', (path, message, hasMessage = true) => {
|
||||
if (hasMessage)
|
||||
return `Invalid package config ${path}${sep}package.json, ${message}`;
|
||||
return `Invalid JSON in ${path} imported from ${message}`;
|
||||
E('ERR_INVALID_PACKAGE_CONFIG', (path, base, message) => {
|
||||
return `Invalid package config ${path}${base ? ` imported from ${base}` :
|
||||
''}${message ? `. ${message}` : ''}`;
|
||||
}, Error);
|
||||
E('ERR_INVALID_PACKAGE_TARGET',
|
||||
(pkgPath, key, target, isImport = false, base = undefined) => {
|
||||
|
||||
@@ -33,13 +33,11 @@ const {
|
||||
Error,
|
||||
JSONParse,
|
||||
Map,
|
||||
Number,
|
||||
ObjectCreate,
|
||||
ObjectDefineProperty,
|
||||
ObjectFreeze,
|
||||
ObjectGetOwnPropertyDescriptor,
|
||||
ObjectGetPrototypeOf,
|
||||
ObjectIs,
|
||||
ObjectKeys,
|
||||
ObjectPrototypeHasOwnProperty,
|
||||
ObjectSetPrototypeOf,
|
||||
@@ -49,7 +47,6 @@ const {
|
||||
SafeWeakMap,
|
||||
SafeSet,
|
||||
String,
|
||||
StringPrototypeIndexOf,
|
||||
StringPrototypeMatch,
|
||||
StringPrototypeSlice,
|
||||
StringPrototypeStartsWith,
|
||||
@@ -94,10 +91,7 @@ let hasLoadedAnyUserCJSModule = false;
|
||||
const {
|
||||
ERR_INVALID_ARG_VALUE,
|
||||
ERR_INVALID_OPT_VALUE,
|
||||
ERR_INVALID_PACKAGE_CONFIG,
|
||||
ERR_INVALID_PACKAGE_TARGET,
|
||||
ERR_INVALID_MODULE_SPECIFIER,
|
||||
ERR_PACKAGE_PATH_NOT_EXPORTED,
|
||||
ERR_REQUIRE_ESM
|
||||
} = require('internal/errors').codes;
|
||||
const { validateString } = require('internal/validators');
|
||||
@@ -117,7 +111,8 @@ const asyncESM = require('internal/process/esm_loader');
|
||||
const { kEvaluated } = internalBinding('module_wrap');
|
||||
const {
|
||||
encodedSepRegEx,
|
||||
packageInternalResolve
|
||||
packageExportsResolve,
|
||||
packageImportsResolve
|
||||
} = require('internal/modules/esm/resolve');
|
||||
|
||||
const isWindows = process.platform === 'win32';
|
||||
@@ -319,18 +314,8 @@ function readPackageScope(checkPath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function readPackageMain(requestPath) {
|
||||
const pkg = readPackage(requestPath);
|
||||
return pkg ? pkg.main : undefined;
|
||||
}
|
||||
|
||||
function readPackageExports(requestPath) {
|
||||
const pkg = readPackage(requestPath);
|
||||
return pkg ? pkg.exports : undefined;
|
||||
}
|
||||
|
||||
function tryPackage(requestPath, exts, isMain, originalPath) {
|
||||
const pkg = readPackageMain(requestPath);
|
||||
const pkg = readPackage(requestPath)?.main;
|
||||
|
||||
if (!pkg) {
|
||||
return tryExtensions(path.resolve(requestPath, 'index'), exts, isMain);
|
||||
@@ -435,108 +420,28 @@ function trySelfParentPath(parent) {
|
||||
function trySelf(parentPath, request) {
|
||||
if (!parentPath) return false;
|
||||
|
||||
const { data: pkg, path: basePath } = readPackageScope(parentPath) || {};
|
||||
const { data: pkg, path: pkgPath } = readPackageScope(parentPath) || {};
|
||||
if (!pkg || pkg.exports === undefined) return false;
|
||||
if (typeof pkg.name !== 'string') return false;
|
||||
|
||||
let expansion;
|
||||
if (request === pkg.name) {
|
||||
expansion = '';
|
||||
expansion = '.';
|
||||
} else if (StringPrototypeStartsWith(request, `${pkg.name}/`)) {
|
||||
expansion = StringPrototypeSlice(request, pkg.name.length);
|
||||
expansion = '.' + StringPrototypeSlice(request, pkg.name.length);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
const fromExports = applyExports(basePath, expansion);
|
||||
if (fromExports) {
|
||||
return tryFile(fromExports, false);
|
||||
try {
|
||||
return finalizeEsmResolution(packageExportsResolve(
|
||||
pathToFileURL(pkgPath + '/package.json'), expansion, pkg,
|
||||
pathToFileURL(parentPath), cjsConditions), request, parentPath, pkgPath);
|
||||
} catch (e) {
|
||||
if (e.code === 'ERR_MODULE_NOT_FOUND')
|
||||
throw createEsmNotFoundErr(request, pkgPath + '/package.json');
|
||||
throw e;
|
||||
}
|
||||
assert(fromExports !== false);
|
||||
}
|
||||
|
||||
function isConditionalDotExportSugar(exports, basePath) {
|
||||
if (typeof exports === 'string')
|
||||
return true;
|
||||
if (ArrayIsArray(exports))
|
||||
return true;
|
||||
if (typeof exports !== 'object')
|
||||
return false;
|
||||
let isConditional = false;
|
||||
let firstCheck = true;
|
||||
for (const key of ObjectKeys(exports)) {
|
||||
const curIsConditional = key[0] !== '.';
|
||||
if (firstCheck) {
|
||||
firstCheck = false;
|
||||
isConditional = curIsConditional;
|
||||
} else if (isConditional !== curIsConditional) {
|
||||
throw new ERR_INVALID_PACKAGE_CONFIG(basePath, '"exports" cannot ' +
|
||||
'contain some keys starting with \'.\' and some not. The exports ' +
|
||||
'object must either be an object of package subpath keys or an ' +
|
||||
'object of main entry condition name keys only.');
|
||||
}
|
||||
}
|
||||
return isConditional;
|
||||
}
|
||||
|
||||
function applyExports(basePath, expansion) {
|
||||
const mappingKey = `.${expansion}`;
|
||||
|
||||
let pkgExports = readPackageExports(basePath);
|
||||
if (pkgExports === undefined || pkgExports === null)
|
||||
return false;
|
||||
|
||||
if (isConditionalDotExportSugar(pkgExports, basePath))
|
||||
pkgExports = { '.': pkgExports };
|
||||
|
||||
if (typeof pkgExports === 'object') {
|
||||
if (ObjectPrototypeHasOwnProperty(pkgExports, mappingKey)) {
|
||||
const mapping = pkgExports[mappingKey];
|
||||
const resolved = resolveExportsTarget(
|
||||
pathToFileURL(basePath + '/'), mapping, '', mappingKey);
|
||||
if (resolved === null || resolved === undefined)
|
||||
throw new ERR_PACKAGE_PATH_NOT_EXPORTED(
|
||||
basePath, mappingKey);
|
||||
return resolved;
|
||||
}
|
||||
|
||||
let dirMatch = '';
|
||||
for (const candidateKey of ObjectKeys(pkgExports)) {
|
||||
if (candidateKey[candidateKey.length - 1] !== '/') continue;
|
||||
if (candidateKey.length > dirMatch.length &&
|
||||
StringPrototypeStartsWith(mappingKey, candidateKey)) {
|
||||
dirMatch = candidateKey;
|
||||
}
|
||||
}
|
||||
|
||||
if (dirMatch !== '') {
|
||||
const mapping = pkgExports[dirMatch];
|
||||
const subpath = StringPrototypeSlice(mappingKey, dirMatch.length);
|
||||
const resolved = resolveExportsTarget(pathToFileURL(basePath + '/'),
|
||||
mapping, subpath, mappingKey);
|
||||
if (resolved === null || resolved === undefined)
|
||||
throw new ERR_PACKAGE_PATH_NOT_EXPORTED(
|
||||
basePath, mappingKey + subpath);
|
||||
// Extension searching for folder exports only
|
||||
const rc = stat(resolved);
|
||||
if (rc === 0) return resolved;
|
||||
if (!(RegExpPrototypeTest(trailingSlashRegex, resolved))) {
|
||||
const exts = ObjectKeys(Module._extensions);
|
||||
const filename = tryExtensions(resolved, exts, false);
|
||||
if (filename) return filename;
|
||||
}
|
||||
if (rc === 1) {
|
||||
const exts = ObjectKeys(Module._extensions);
|
||||
const filename = tryPackage(resolved, exts, false,
|
||||
basePath + expansion);
|
||||
if (filename) return filename;
|
||||
}
|
||||
// Undefined means not found
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ERR_PACKAGE_PATH_NOT_EXPORTED(basePath, mappingKey);
|
||||
}
|
||||
|
||||
// This only applies to requests of a specific form:
|
||||
@@ -547,107 +452,21 @@ function resolveExports(nmPath, request) {
|
||||
// The implementation's behavior is meant to mirror resolution in ESM.
|
||||
const [, name, expansion = ''] =
|
||||
StringPrototypeMatch(request, EXPORTS_PATTERN) || [];
|
||||
if (!name) {
|
||||
return false;
|
||||
if (!name)
|
||||
return;
|
||||
const pkgPath = path.resolve(nmPath, name);
|
||||
const pkg = readPackage(pkgPath);
|
||||
if (pkg && pkg.exports !== null && pkg.exports !== undefined) {
|
||||
try {
|
||||
return finalizeEsmResolution(packageExportsResolve(
|
||||
pathToFileURL(pkgPath + '/package.json'), '.' + expansion, pkg, null,
|
||||
cjsConditions), request, null, pkgPath);
|
||||
} catch (e) {
|
||||
if (e.code === 'ERR_MODULE_NOT_FOUND')
|
||||
throw createEsmNotFoundErr(request, pkgPath + '/package.json');
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
const basePath = path.resolve(nmPath, name);
|
||||
const fromExports = applyExports(basePath, expansion);
|
||||
if (fromExports) {
|
||||
return tryFile(fromExports, false);
|
||||
}
|
||||
return fromExports;
|
||||
}
|
||||
|
||||
function isArrayIndex(p) {
|
||||
assert(typeof p === 'string');
|
||||
const n = Number(p);
|
||||
if (String(n) !== p)
|
||||
return false;
|
||||
if (ObjectIs(n, +0))
|
||||
return true;
|
||||
if (!Number.isInteger(n))
|
||||
return false;
|
||||
return n >= 0 && n < (2 ** 32) - 1;
|
||||
}
|
||||
|
||||
function resolveExportsTarget(baseUrl, target, subpath, mappingKey) {
|
||||
if (typeof target === 'string') {
|
||||
let resolvedTarget, resolvedTargetPath;
|
||||
const pkgPathPath = baseUrl.pathname;
|
||||
if (StringPrototypeStartsWith(target, './')) {
|
||||
resolvedTarget = new URL(target, baseUrl);
|
||||
resolvedTargetPath = resolvedTarget.pathname;
|
||||
if (!StringPrototypeStartsWith(resolvedTargetPath, pkgPathPath) ||
|
||||
StringPrototypeIndexOf(resolvedTargetPath, '/node_modules/',
|
||||
pkgPathPath.length - 1) !== -1)
|
||||
resolvedTarget = undefined;
|
||||
}
|
||||
if (subpath.length > 0 && target[target.length - 1] !== '/')
|
||||
resolvedTarget = undefined;
|
||||
if (resolvedTarget === undefined)
|
||||
throw new ERR_INVALID_PACKAGE_TARGET(baseUrl.pathname, mappingKey,
|
||||
target);
|
||||
const resolved = new URL(subpath, resolvedTarget);
|
||||
const resolvedPath = resolved.pathname;
|
||||
if (StringPrototypeStartsWith(resolvedPath, resolvedTargetPath) &&
|
||||
StringPrototypeIndexOf(resolvedPath, '/node_modules/',
|
||||
pkgPathPath.length - 1) === -1) {
|
||||
if (StringPrototypeMatch(resolvedPath, encodedSepRegEx))
|
||||
throw new ERR_INVALID_MODULE_SPECIFIER(
|
||||
resolvedPath, 'must not include encoded "/" or "\\" characters',
|
||||
fileURLToPath(baseUrl));
|
||||
return fileURLToPath(resolved);
|
||||
}
|
||||
const reason = 'request is not a valid subpath for the "exports" ' +
|
||||
`resolution of ${baseUrl.pathname}package.json`;
|
||||
throw new ERR_INVALID_MODULE_SPECIFIER(mappingKey + subpath, reason);
|
||||
} else if (ArrayIsArray(target)) {
|
||||
if (target.length === 0)
|
||||
return null;
|
||||
let lastException;
|
||||
for (const targetValue of target) {
|
||||
let resolved;
|
||||
try {
|
||||
resolved = resolveExportsTarget(baseUrl, targetValue, subpath,
|
||||
mappingKey);
|
||||
} catch (e) {
|
||||
lastException = e;
|
||||
if (e.code !== 'ERR_INVALID_PACKAGE_TARGET')
|
||||
throw e;
|
||||
}
|
||||
if (resolved === undefined)
|
||||
continue;
|
||||
if (resolved === null) {
|
||||
lastException = null;
|
||||
continue;
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
// Throw last fallback error
|
||||
if (lastException === undefined || lastException === null)
|
||||
return lastException;
|
||||
throw lastException;
|
||||
} else if (typeof target === 'object' && target !== null) {
|
||||
const keys = ObjectKeys(target);
|
||||
if (keys.some(isArrayIndex)) {
|
||||
throw new ERR_INVALID_PACKAGE_CONFIG(baseUrl, '"exports" cannot ' +
|
||||
'contain numeric property keys.');
|
||||
}
|
||||
for (const p of keys) {
|
||||
if (cjsConditions.has(p) || p === 'default') {
|
||||
const resolved = resolveExportsTarget(baseUrl, target[p], subpath,
|
||||
mappingKey);
|
||||
if (resolved === undefined)
|
||||
continue;
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
} else if (target === null) {
|
||||
return null;
|
||||
}
|
||||
throw new ERR_INVALID_PACKAGE_TARGET(baseUrl.pathname, mappingKey, target);
|
||||
}
|
||||
|
||||
const trailingSlashRegex = /(?:^|\/)\.?\.$/;
|
||||
@@ -680,12 +499,8 @@ Module._findPath = function(request, paths, isMain) {
|
||||
|
||||
if (!absoluteRequest) {
|
||||
const exportsResolved = resolveExports(curPath, request);
|
||||
// Undefined means not found, false means no exports
|
||||
if (exportsResolved === undefined)
|
||||
break;
|
||||
if (exportsResolved) {
|
||||
if (exportsResolved)
|
||||
return exportsResolved;
|
||||
}
|
||||
}
|
||||
|
||||
const basePath = path.resolve(curPath, request);
|
||||
@@ -1050,19 +865,14 @@ Module._resolveFilename = function(request, parent, isMain, options) {
|
||||
if (pkg.data && pkg.data.imports !== null &&
|
||||
pkg.data.imports !== undefined) {
|
||||
try {
|
||||
const resolved = packageInternalResolve(
|
||||
request, pathToFileURL(parent.filename), cjsConditions);
|
||||
return fileURLToPath(resolved);
|
||||
} catch (err) {
|
||||
if (err.code === 'ERR_MODULE_NOT_FOUND') {
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
const err = new Error(`Cannot find module '${request}'`);
|
||||
err.code = 'MODULE_NOT_FOUND';
|
||||
err.path = path.resolve(pkg.path, 'package.json');
|
||||
// TODO(BridgeAR): Add the requireStack as well.
|
||||
throw err;
|
||||
}
|
||||
throw err;
|
||||
return finalizeEsmResolution(
|
||||
packageImportsResolve(request, pathToFileURL(parent.filename),
|
||||
cjsConditions), request, parent.filename,
|
||||
pkg.path);
|
||||
} catch (e) {
|
||||
if (e.code === 'ERR_MODULE_NOT_FOUND')
|
||||
throw createEsmNotFoundErr(request);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1098,6 +908,34 @@ Module._resolveFilename = function(request, parent, isMain, options) {
|
||||
throw err;
|
||||
};
|
||||
|
||||
function finalizeEsmResolution(match, request, parentPath, pkgPath) {
|
||||
const { resolved, exact } = match;
|
||||
if (StringPrototypeMatch(resolved, encodedSepRegEx))
|
||||
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);
|
||||
}
|
||||
if (actual)
|
||||
return actual;
|
||||
const err = createEsmNotFoundErr(filename,
|
||||
path.resolve(pkgPath, 'package.json'));
|
||||
throw err;
|
||||
}
|
||||
|
||||
function createEsmNotFoundErr(request, path) {
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
const err = new Error(`Cannot find module '${request}'`);
|
||||
err.code = 'MODULE_NOT_FOUND';
|
||||
if (path)
|
||||
err.path = path;
|
||||
// TODO(BridgeAR): Add the requireStack as well.
|
||||
return err;
|
||||
}
|
||||
|
||||
// Given a file name, pass it to the proper extension handler.
|
||||
Module.prototype.load = function(filename) {
|
||||
|
||||
@@ -15,7 +15,6 @@ const {
|
||||
SafeSet,
|
||||
String,
|
||||
StringPrototypeEndsWith,
|
||||
StringPrototypeIncludes,
|
||||
StringPrototypeIndexOf,
|
||||
StringPrototypeReplace,
|
||||
StringPrototypeSlice,
|
||||
@@ -78,14 +77,6 @@ function tryStatSync(path) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* '/foo/package.json' -> '/foo'
|
||||
*/
|
||||
function removePackageJsonFromPath(path) {
|
||||
return StringPrototypeSlice(path, 0, path.length - 13);
|
||||
}
|
||||
|
||||
function getPackageConfig(path) {
|
||||
const existing = packageJSONCache.get(path);
|
||||
if (existing !== undefined) {
|
||||
@@ -110,8 +101,7 @@ function getPackageConfig(path) {
|
||||
try {
|
||||
packageJSON = JSONParse(source);
|
||||
} catch (error) {
|
||||
const errorPath = removePackageJsonFromPath(path);
|
||||
throw new ERR_INVALID_PACKAGE_CONFIG(errorPath, error.message, true);
|
||||
throw new ERR_INVALID_PACKAGE_CONFIG(path, null, error.message);
|
||||
}
|
||||
|
||||
let { imports, main, name, type } = packageJSON;
|
||||
@@ -177,7 +167,7 @@ function fileExists(url) {
|
||||
return tryStatSync(fileURLToPath(url)).isFile();
|
||||
}
|
||||
|
||||
function legacyMainResolve(packageJSONUrl, packageConfig) {
|
||||
function legacyMainResolve(packageJSONUrl, packageConfig, base) {
|
||||
let guess;
|
||||
if (packageConfig.main !== undefined) {
|
||||
// Note: fs check redundances will be handled by Descriptor cache here.
|
||||
@@ -222,7 +212,8 @@ function legacyMainResolve(packageJSONUrl, packageConfig) {
|
||||
return guess;
|
||||
}
|
||||
// Not found.
|
||||
return undefined;
|
||||
throw new ERR_MODULE_NOT_FOUND(
|
||||
fileURLToPath(new URL('.', packageJSONUrl)), fileURLToPath(base));
|
||||
}
|
||||
|
||||
function resolveExtensionsWithTryExactName(search) {
|
||||
@@ -246,35 +237,34 @@ function resolveIndex(search) {
|
||||
|
||||
const encodedSepRegEx = /%2F|%2C/i;
|
||||
function finalizeResolution(resolved, base) {
|
||||
if (getOptionValue('--experimental-specifier-resolution') === 'node') {
|
||||
let file = resolveExtensionsWithTryExactName(resolved);
|
||||
if (file !== undefined) return file;
|
||||
if (!StringPrototypeEndsWith(resolved.pathname, '/')) {
|
||||
file = resolveIndex(new URL(`${resolved.pathname}/`, base));
|
||||
} else {
|
||||
file = resolveIndex(resolved);
|
||||
}
|
||||
if (file !== undefined) return file;
|
||||
throw new ERR_MODULE_NOT_FOUND(
|
||||
resolved.pathname, fileURLToPath(base), 'module');
|
||||
}
|
||||
|
||||
if (RegExpPrototypeTest(encodedSepRegEx, resolved.pathname))
|
||||
throw new ERR_INVALID_MODULE_SPECIFIER(
|
||||
resolved.pathname, 'must not include encoded "/" or "\\" characters',
|
||||
fileURLToPath(base));
|
||||
|
||||
const path = fileURLToPath(resolved);
|
||||
const stats = tryStatSync(path);
|
||||
if (getOptionValue('--experimental-specifier-resolution') === 'node') {
|
||||
let file = resolveExtensionsWithTryExactName(resolved);
|
||||
if (file !== undefined) return file;
|
||||
if (!StringPrototypeEndsWith(path, '/')) {
|
||||
file = resolveIndex(new URL(`${resolved}/`));
|
||||
if (file !== undefined) return file;
|
||||
} else {
|
||||
return resolveIndex(resolved) || resolved;
|
||||
}
|
||||
throw new ERR_MODULE_NOT_FOUND(
|
||||
resolved.pathname, fileURLToPath(base), 'module');
|
||||
}
|
||||
|
||||
const stats = tryStatSync(StringPrototypeEndsWith(path, '/') ?
|
||||
StringPrototypeSlice(path, -1) : path);
|
||||
if (stats.isDirectory()) {
|
||||
const err = new ERR_UNSUPPORTED_DIR_IMPORT(
|
||||
path || resolved.pathname, fileURLToPath(base));
|
||||
const err = new ERR_UNSUPPORTED_DIR_IMPORT(path, fileURLToPath(base));
|
||||
err.url = String(resolved);
|
||||
throw err;
|
||||
} else if (!stats.isFile()) {
|
||||
throw new ERR_MODULE_NOT_FOUND(
|
||||
path || resolved.pathname, fileURLToPath(base), 'module');
|
||||
path || resolved.pathname, base && fileURLToPath(base), 'module');
|
||||
}
|
||||
|
||||
return resolved;
|
||||
@@ -288,14 +278,15 @@ function throwImportNotDefined(specifier, packageJSONUrl, base) {
|
||||
|
||||
function throwExportsNotFound(subpath, packageJSONUrl, base) {
|
||||
throw new ERR_PACKAGE_PATH_NOT_EXPORTED(
|
||||
fileURLToPath(new URL('.', packageJSONUrl)), subpath, fileURLToPath(base));
|
||||
fileURLToPath(new URL('.', packageJSONUrl)), subpath,
|
||||
base && fileURLToPath(base));
|
||||
}
|
||||
|
||||
function throwInvalidSubpath(subpath, packageJSONUrl, internal, base) {
|
||||
const reason = `request is not a valid subpath for the "${internal ?
|
||||
'imports' : 'exports'}" resolution of ${fileURLToPath(packageJSONUrl)}${
|
||||
base ? ` imported from ${base}` : ''}`;
|
||||
throw new ERR_INVALID_MODULE_SPECIFIER(subpath, reason, fileURLToPath(base));
|
||||
'imports' : 'exports'}" resolution of ${fileURLToPath(packageJSONUrl)}`;
|
||||
throw new ERR_INVALID_MODULE_SPECIFIER(subpath, reason,
|
||||
base && fileURLToPath(base));
|
||||
}
|
||||
|
||||
function throwInvalidPackageTarget(
|
||||
@@ -307,44 +298,46 @@ function throwInvalidPackageTarget(
|
||||
}
|
||||
throw new ERR_INVALID_PACKAGE_TARGET(
|
||||
fileURLToPath(new URL('.', packageJSONUrl)), subpath, target,
|
||||
internal, fileURLToPath(base));
|
||||
internal, base && fileURLToPath(base));
|
||||
}
|
||||
|
||||
const invalidSegmentRegEx = /(^|\\|\/)(\.\.?|node_modules)(\\|\/|$)/;
|
||||
|
||||
function resolvePackageTargetString(
|
||||
target, subpath, match, packageJSONUrl, base, internal, conditions) {
|
||||
if (subpath !== '' && target[target.length - 1] !== '/')
|
||||
throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base);
|
||||
|
||||
if (!target.startsWith('./')) {
|
||||
if (internal && !target.startsWith('../') && !target.startsWith('/')) {
|
||||
if (!StringPrototypeStartsWith(target, './')) {
|
||||
if (internal && !StringPrototypeStartsWith(target, '../') &&
|
||||
!StringPrototypeStartsWith(target, '/')) {
|
||||
let isURL = false;
|
||||
try {
|
||||
new URL(target);
|
||||
isURL = true;
|
||||
} catch {}
|
||||
if (!isURL)
|
||||
return packageResolve(target + subpath, base, conditions);
|
||||
return packageResolve(target + subpath, packageJSONUrl, conditions);
|
||||
}
|
||||
throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base);
|
||||
}
|
||||
|
||||
if (RegExpPrototypeTest(invalidSegmentRegEx, StringPrototypeSlice(target, 2)))
|
||||
throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base);
|
||||
|
||||
const resolved = new URL(target, packageJSONUrl);
|
||||
const resolvedPath = resolved.pathname;
|
||||
const packagePath = new URL('.', packageJSONUrl).pathname;
|
||||
|
||||
if (!StringPrototypeStartsWith(resolvedPath, packagePath) ||
|
||||
StringPrototypeIncludes(
|
||||
resolvedPath, '/node_modules/', packagePath.length - 1))
|
||||
if (!StringPrototypeStartsWith(resolvedPath, packagePath))
|
||||
throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base);
|
||||
|
||||
if (subpath === '') return resolved;
|
||||
const subpathResolved = new URL(subpath, resolved);
|
||||
const subpathResolvedPath = subpathResolved.pathname;
|
||||
if (!StringPrototypeStartsWith(subpathResolvedPath, resolvedPath) ||
|
||||
StringPrototypeIncludes(subpathResolvedPath,
|
||||
'/node_modules/', packagePath.length - 1))
|
||||
|
||||
if (RegExpPrototypeTest(invalidSegmentRegEx, subpath))
|
||||
throwInvalidSubpath(match + subpath, packageJSONUrl, internal, base);
|
||||
return subpathResolved;
|
||||
|
||||
return new URL(subpath, resolved);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -357,12 +350,12 @@ function isArrayIndex(key) {
|
||||
return keyNum >= 0 && keyNum < 0xFFFF_FFFF;
|
||||
}
|
||||
|
||||
function resolvePackageTarget(
|
||||
packageJSONUrl, target, subpath, packageSubpath, base, internal, conditions) {
|
||||
function resolvePackageTarget(packageJSONUrl, target, subpath, packageSubpath,
|
||||
base, internal, conditions) {
|
||||
if (typeof target === 'string') {
|
||||
return finalizeResolution(resolvePackageTargetString(
|
||||
return resolvePackageTargetString(
|
||||
target, subpath, packageSubpath, packageJSONUrl, base, internal,
|
||||
conditions), base);
|
||||
conditions);
|
||||
} else if (ArrayIsArray(target)) {
|
||||
if (target.length === 0)
|
||||
return null;
|
||||
@@ -387,7 +380,7 @@ function resolvePackageTarget(
|
||||
lastException = null;
|
||||
continue;
|
||||
}
|
||||
return finalizeResolution(resolved, base);
|
||||
return resolved;
|
||||
}
|
||||
if (lastException === undefined || lastException === null)
|
||||
return lastException;
|
||||
@@ -398,8 +391,8 @@ function resolvePackageTarget(
|
||||
const key = keys[i];
|
||||
if (isArrayIndex(key)) {
|
||||
throw new ERR_INVALID_PACKAGE_CONFIG(
|
||||
fileURLToPath(packageJSONUrl),
|
||||
'"exports" cannot contain numeric property keys');
|
||||
fileURLToPath(packageJSONUrl), base,
|
||||
'"exports" cannot contain numeric property keys.');
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
@@ -436,7 +429,7 @@ function isConditionalExportsMainSugar(exports, packageJSONUrl, base) {
|
||||
isConditionalSugar = curIsConditionalSugar;
|
||||
} else if (isConditionalSugar !== curIsConditionalSugar) {
|
||||
throw new ERR_INVALID_PACKAGE_CONFIG(
|
||||
fileURLToPath(packageJSONUrl),
|
||||
fileURLToPath(packageJSONUrl), base,
|
||||
'"exports" cannot contain some keys starting with \'.\' and some not.' +
|
||||
' The exports object must either be an object of package subpath keys' +
|
||||
' or an object of main entry condition name keys only.');
|
||||
@@ -445,44 +438,6 @@ function isConditionalExportsMainSugar(exports, packageJSONUrl, base) {
|
||||
return isConditionalSugar;
|
||||
}
|
||||
|
||||
function packageMainResolve(packageJSONUrl, packageConfig, base, conditions) {
|
||||
if (packageConfig.exists) {
|
||||
const exports = packageConfig.exports;
|
||||
if (exports !== undefined) {
|
||||
if (isConditionalExportsMainSugar(exports, packageJSONUrl, base)) {
|
||||
const resolved = resolvePackageTarget(packageJSONUrl, exports, '', '',
|
||||
base, false, conditions);
|
||||
if (resolved === null || resolved === undefined)
|
||||
throwExportsNotFound('.', packageJSONUrl, base);
|
||||
return resolved;
|
||||
} else if (typeof exports === 'object' && exports !== null) {
|
||||
const target = exports['.'];
|
||||
if (target !== undefined) {
|
||||
const resolved = resolvePackageTarget(packageJSONUrl, target, '', '',
|
||||
base, false, conditions);
|
||||
if (resolved === null || resolved === undefined)
|
||||
throwExportsNotFound('.', packageJSONUrl, base);
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ERR_PACKAGE_PATH_NOT_EXPORTED(packageJSONUrl, '.');
|
||||
}
|
||||
if (getOptionValue('--experimental-specifier-resolution') === 'node') {
|
||||
if (packageConfig.main !== undefined) {
|
||||
return finalizeResolution(
|
||||
new URL(packageConfig.main, packageJSONUrl), base);
|
||||
}
|
||||
return finalizeResolution(
|
||||
new URL('index', packageJSONUrl), base);
|
||||
}
|
||||
return legacyMainResolve(packageJSONUrl, packageConfig);
|
||||
}
|
||||
|
||||
throw new ERR_MODULE_NOT_FOUND(
|
||||
fileURLToPath(new URL('.', packageJSONUrl)), fileURLToPath(base));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {URL} packageJSONUrl
|
||||
* @param {string} packageSubpath
|
||||
@@ -493,28 +448,27 @@ function packageMainResolve(packageJSONUrl, packageConfig, base, conditions) {
|
||||
*/
|
||||
function packageExportsResolve(
|
||||
packageJSONUrl, packageSubpath, packageConfig, base, conditions) {
|
||||
const exports = packageConfig.exports;
|
||||
if (exports === undefined ||
|
||||
isConditionalExportsMainSugar(exports, packageJSONUrl, base)) {
|
||||
throwExportsNotFound(packageSubpath, packageJSONUrl, base);
|
||||
}
|
||||
let exports = packageConfig.exports;
|
||||
if (isConditionalExportsMainSugar(exports, packageJSONUrl, base))
|
||||
exports = { '.': exports };
|
||||
|
||||
if (ObjectPrototypeHasOwnProperty(exports, packageSubpath)) {
|
||||
const target = exports[packageSubpath];
|
||||
const resolved = resolvePackageTarget(
|
||||
packageJSONUrl, target, '', packageSubpath, base, false, conditions);
|
||||
packageJSONUrl, target, '', packageSubpath, base, false, conditions
|
||||
);
|
||||
if (resolved === null || resolved === undefined)
|
||||
throwExportsNotFound(packageSubpath, packageJSONUrl, base);
|
||||
return finalizeResolution(resolved, base);
|
||||
return { resolved, exact: true };
|
||||
}
|
||||
|
||||
let bestMatch = '';
|
||||
const keys = ObjectGetOwnPropertyNames(exports);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i];
|
||||
if (key[key.length - 1] !== '/') continue;
|
||||
if (StringPrototypeStartsWith(packageSubpath, key) &&
|
||||
key.length > bestMatch.length) {
|
||||
if (key[key.length - 1] === '/' &&
|
||||
StringPrototypeStartsWith(packageSubpath, key) &&
|
||||
key.length > bestMatch.length) {
|
||||
bestMatch = key;
|
||||
}
|
||||
}
|
||||
@@ -522,18 +476,18 @@ function packageExportsResolve(
|
||||
if (bestMatch) {
|
||||
const target = exports[bestMatch];
|
||||
const subpath = StringPrototypeSubstr(packageSubpath, bestMatch.length);
|
||||
const resolved = resolvePackageTarget(
|
||||
packageJSONUrl, target, subpath, bestMatch, base, false, conditions);
|
||||
const resolved = resolvePackageTarget(packageJSONUrl, target, subpath,
|
||||
bestMatch, base, false, conditions);
|
||||
if (resolved === null || resolved === undefined)
|
||||
throwExportsNotFound(packageSubpath, packageJSONUrl, base);
|
||||
return finalizeResolution(resolved, base);
|
||||
return { resolved, exact: false };
|
||||
}
|
||||
|
||||
throwExportsNotFound(packageSubpath, packageJSONUrl, base);
|
||||
}
|
||||
|
||||
function packageInternalResolve(name, base, conditions) {
|
||||
if (name === '#' || name.startsWith('#/')) {
|
||||
function packageImportsResolve(name, base, conditions) {
|
||||
if (name === '#' || StringPrototypeStartsWith(name, '#/')) {
|
||||
const reason = 'is not a valid internal imports specifier name';
|
||||
throw new ERR_INVALID_MODULE_SPECIFIER(name, reason, fileURLToPath(base));
|
||||
}
|
||||
@@ -545,17 +499,18 @@ function packageInternalResolve(name, base, conditions) {
|
||||
if (imports) {
|
||||
if (ObjectPrototypeHasOwnProperty(imports, name)) {
|
||||
const resolved = resolvePackageTarget(
|
||||
packageJSONUrl, imports[name], '', name, base, true, conditions);
|
||||
packageJSONUrl, imports[name], '', name, base, true, conditions
|
||||
);
|
||||
if (resolved !== null)
|
||||
return finalizeResolution(resolved, base);
|
||||
return { resolved, exact: true };
|
||||
} else {
|
||||
let bestMatch = '';
|
||||
const keys = ObjectGetOwnPropertyNames(imports);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i];
|
||||
if (key[key.length - 1] !== '/') continue;
|
||||
if (StringPrototypeStartsWith(name, key) &&
|
||||
key.length > bestMatch.length) {
|
||||
if (key[key.length - 1] === '/' &&
|
||||
StringPrototypeStartsWith(name, key) &&
|
||||
key.length > bestMatch.length) {
|
||||
bestMatch = key;
|
||||
}
|
||||
}
|
||||
@@ -564,10 +519,9 @@ function packageInternalResolve(name, base, conditions) {
|
||||
const target = imports[bestMatch];
|
||||
const subpath = StringPrototypeSubstr(name, bestMatch.length);
|
||||
const resolved = resolvePackageTarget(
|
||||
packageJSONUrl, target, subpath, bestMatch, base, true,
|
||||
conditions);
|
||||
packageJSONUrl, target, subpath, bestMatch, base, true, conditions);
|
||||
if (resolved !== null)
|
||||
return finalizeResolution(resolved, base);
|
||||
return { resolved, exact: false };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -617,23 +571,18 @@ function packageResolve(specifier, base, conditions) {
|
||||
specifier, 'is not a valid package name', fileURLToPath(base));
|
||||
}
|
||||
|
||||
const packageSubpath = separatorIndex === -1 ?
|
||||
'' : '.' + StringPrototypeSlice(specifier, separatorIndex);
|
||||
const packageSubpath = '.' + (separatorIndex === -1 ? '' :
|
||||
StringPrototypeSlice(specifier, separatorIndex));
|
||||
|
||||
// ResolveSelf
|
||||
const packageConfig = getPackageScopeConfig(base, base);
|
||||
if (packageConfig.exists) {
|
||||
const packageJSONUrl = pathToFileURL(packageConfig.pjsonPath);
|
||||
if (packageConfig.name === packageName &&
|
||||
packageConfig.exports !== undefined) {
|
||||
if (packageSubpath === './') {
|
||||
return new URL('./', packageJSONUrl);
|
||||
} else if (packageSubpath === '') {
|
||||
return packageMainResolve(packageJSONUrl, packageConfig, base,
|
||||
conditions);
|
||||
}
|
||||
packageConfig.exports !== undefined && packageConfig.exports !== null) {
|
||||
return packageExportsResolve(
|
||||
packageJSONUrl, packageSubpath, packageConfig, base, conditions);
|
||||
packageJSONUrl, packageSubpath, packageConfig, base, conditions
|
||||
).resolved;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -642,7 +591,8 @@ function packageResolve(specifier, base, conditions) {
|
||||
let packageJSONPath = fileURLToPath(packageJSONUrl);
|
||||
let lastPath;
|
||||
do {
|
||||
const stat = tryStatSync(removePackageJsonFromPath(packageJSONPath));
|
||||
const stat = tryStatSync(StringPrototypeSlice(packageJSONPath, 0,
|
||||
packageJSONPath.length - 13));
|
||||
if (!stat.isDirectory()) {
|
||||
lastPath = packageJSONPath;
|
||||
packageJSONUrl = new URL((isScoped ?
|
||||
@@ -654,17 +604,13 @@ function packageResolve(specifier, base, conditions) {
|
||||
|
||||
// Package match.
|
||||
const packageConfig = getPackageConfig(packageJSONPath, base);
|
||||
if (packageSubpath === './') {
|
||||
return new URL('./', packageJSONUrl);
|
||||
} else if (packageSubpath === '') {
|
||||
return packageMainResolve(packageJSONUrl, packageConfig, base,
|
||||
conditions);
|
||||
} else if (packageConfig.exports !== undefined) {
|
||||
if (packageConfig.exports !== undefined && packageConfig.exports !== null)
|
||||
return packageExportsResolve(
|
||||
packageJSONUrl, packageSubpath, packageConfig, base, conditions);
|
||||
}
|
||||
return finalizeResolution(
|
||||
new URL(packageSubpath, packageJSONUrl), base);
|
||||
packageJSONUrl, packageSubpath, packageConfig, base, conditions
|
||||
).resolved;
|
||||
if (packageSubpath === '.')
|
||||
return legacyMainResolve(packageJSONUrl, packageConfig, base);
|
||||
return new URL(packageSubpath, packageJSONUrl);
|
||||
// Cross-platform root check.
|
||||
} while (packageJSONPath.length !== lastPath.length);
|
||||
|
||||
@@ -706,12 +652,12 @@ function moduleResolve(specifier, base, conditions) {
|
||||
if (shouldBeTreatedAsRelativeOrAbsolutePath(specifier)) {
|
||||
resolved = new URL(specifier, base);
|
||||
} else if (specifier[0] === '#') {
|
||||
resolved = packageInternalResolve(specifier, base, conditions);
|
||||
({ resolved } = packageImportsResolve(specifier, base, conditions));
|
||||
} else {
|
||||
try {
|
||||
resolved = new URL(specifier);
|
||||
} catch {
|
||||
return packageResolve(specifier, base, conditions);
|
||||
resolved = packageResolve(specifier, base, conditions);
|
||||
}
|
||||
}
|
||||
return finalizeResolution(resolved, base);
|
||||
@@ -847,5 +793,6 @@ module.exports = {
|
||||
defaultResolve,
|
||||
encodedSepRegEx,
|
||||
getPackageType,
|
||||
packageInternalResolve
|
||||
packageExportsResolve,
|
||||
packageImportsResolve
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { mustCall } from '../common/index.mjs';
|
||||
import { ok, deepStrictEqual, strictEqual } from 'assert';
|
||||
import { sep } from 'path';
|
||||
|
||||
import { requireFixture, importFixture } from '../fixtures/pkgexports.mjs';
|
||||
import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js';
|
||||
@@ -135,9 +136,9 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js';
|
||||
|
||||
const notFoundExports = new Map([
|
||||
// Non-existing file
|
||||
['pkgexports/sub/not-a-file.js', 'pkgexports/sub/not-a-file.js'],
|
||||
['pkgexports/sub/not-a-file.js', `pkgexports${sep}not-a-file.js`],
|
||||
// No extension lookups
|
||||
['pkgexports/no-ext', 'pkgexports/no-ext'],
|
||||
['pkgexports/no-ext', `pkgexports${sep}asdf`],
|
||||
]);
|
||||
|
||||
if (!isRequire) {
|
||||
@@ -153,10 +154,8 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js';
|
||||
for (const [specifier, request] of notFoundExports) {
|
||||
loadFixture(specifier).catch(mustCall((err) => {
|
||||
strictEqual(err.code, (isRequire ? '' : 'ERR_') + 'MODULE_NOT_FOUND');
|
||||
// ESM returns a full file path
|
||||
assertStartsWith(err.message, isRequire ?
|
||||
`Cannot find module '${request}'` :
|
||||
'Cannot find module');
|
||||
assertIncludes(err.message, request);
|
||||
assertStartsWith(err.message, 'Cannot find module');
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ child.on('close', mustCall((code, signal) => {
|
||||
stderr.includes(
|
||||
[
|
||||
'[ERR_INVALID_PACKAGE_CONFIG]: ',
|
||||
`Invalid package config ${invalidJson}, `,
|
||||
`Invalid package config ${invalidJson}. `,
|
||||
`Unexpected token } in JSON at position ${isWindows ? 16 : 14}`
|
||||
].join(''),
|
||||
),
|
||||
|
||||
@@ -6,7 +6,6 @@ Error [ERR_MODULE_NOT_FOUND]: Cannot find module '*test*fixtures*node_modules*so
|
||||
Did you mean to import some_module/obj.js?
|
||||
at new NodeError (internal/errors.js:*:*)
|
||||
at finalizeResolution (internal/modules/esm/resolve.js:*:*)
|
||||
at packageResolve (internal/modules/esm/resolve.js:*:*)
|
||||
at moduleResolve (internal/modules/esm/resolve.js:*:*)
|
||||
at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:*:*)
|
||||
at Loader.resolve (internal/modules/esm/loader.js:*:*)
|
||||
|
||||
Reference in New Issue
Block a user