-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
module: fix extension searching for exports #32351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -392,52 +392,7 @@ function findLongestRegisteredExtension(filename) { | |
| return '.js'; | ||
| } | ||
|
|
||
| function resolveBasePath(basePath, exts, isMain, trailingSlash, request) { | ||
| let filename; | ||
|
|
||
| const rc = stat(basePath); | ||
| if (!trailingSlash) { | ||
| if (rc === 0) { // File. | ||
| if (!isMain) { | ||
| if (preserveSymlinks) { | ||
| filename = path.resolve(basePath); | ||
| } else { | ||
| filename = toRealPath(basePath); | ||
| } | ||
| } else if (preserveSymlinksMain) { | ||
| // For the main module, we use the preserveSymlinksMain flag instead | ||
| // mainly for backward compatibility, as the preserveSymlinks flag | ||
| // historically has not applied to the main module. Most likely this | ||
| // was intended to keep .bin/ binaries working, as following those | ||
| // symlinks is usually required for the imports in the corresponding | ||
| // files to resolve; that said, in some use cases following symlinks | ||
| // causes bigger problems which is why the preserveSymlinksMain option | ||
| // is needed. | ||
| filename = path.resolve(basePath); | ||
| } else { | ||
| filename = toRealPath(basePath); | ||
| } | ||
| } | ||
|
|
||
| if (!filename) { | ||
| // Try it with each of the extensions | ||
| if (exts === undefined) | ||
| exts = ObjectKeys(Module._extensions); | ||
| filename = tryExtensions(basePath, exts, isMain); | ||
| } | ||
| } | ||
|
|
||
| if (!filename && rc === 1) { // Directory. | ||
| // try it with each of the extensions at "index" | ||
| if (exts === undefined) | ||
| exts = ObjectKeys(Module._extensions); | ||
| filename = tryPackage(basePath, exts, isMain, request); | ||
| } | ||
|
|
||
| return filename; | ||
| } | ||
|
|
||
| function trySelf(parentPath, isMain, request) { | ||
| function trySelf(parentPath, request) { | ||
| const { data: pkg, path: basePath } = readPackageScope(parentPath) || {}; | ||
| if (!pkg || pkg.exports === undefined) return false; | ||
| if (typeof pkg.name !== 'string') return false; | ||
|
|
@@ -451,20 +406,11 @@ function trySelf(parentPath, isMain, request) { | |
| return false; | ||
| } | ||
|
|
||
| const exts = ObjectKeys(Module._extensions); | ||
| const fromExports = applyExports(basePath, expansion); | ||
| // Use exports | ||
| if (fromExports) { | ||
| let trailingSlash = request.length > 0 && | ||
| request.charCodeAt(request.length - 1) === CHAR_FORWARD_SLASH; | ||
| if (!trailingSlash) { | ||
| trailingSlash = /(?:^|\/)\.?\.$/.test(request); | ||
| } | ||
| return resolveBasePath(fromExports, exts, isMain, trailingSlash, request); | ||
| } else { | ||
| // Use main field | ||
| return tryPackage(basePath, exts, isMain, request); | ||
| return tryFile(fromExports, false); | ||
| } | ||
| assert(false); | ||
| } | ||
|
|
||
| function isConditionalDotExportSugar(exports, basePath) { | ||
|
|
@@ -496,7 +442,7 @@ function applyExports(basePath, expansion) { | |
|
|
||
| let pkgExports = readPackageExports(basePath); | ||
| if (pkgExports === undefined || pkgExports === null) | ||
| return path.resolve(basePath, mappingKey); | ||
| return false; | ||
|
|
||
| if (isConditionalDotExportSugar(pkgExports, basePath)) | ||
| pkgExports = { '.': pkgExports }; | ||
|
|
@@ -532,20 +478,20 @@ function applyExports(basePath, expansion) { | |
| // 1. name/.* | ||
| // 2. @scope/name/.* | ||
| const EXPORTS_PATTERN = /^((?:@[^/\\%]+\/)?[^./\\%][^/\\%]*)(\/.*)?$/; | ||
| function resolveExports(nmPath, request, absoluteRequest) { | ||
| function resolveExports(nmPath, request) { | ||
| // The implementation's behavior is meant to mirror resolution in ESM. | ||
| if (!absoluteRequest) { | ||
| const [, name, expansion = ''] = | ||
| StringPrototypeMatch(request, EXPORTS_PATTERN) || []; | ||
| if (!name) { | ||
| return path.resolve(nmPath, request); | ||
| } | ||
|
|
||
| const basePath = path.resolve(nmPath, name); | ||
| return applyExports(basePath, expansion); | ||
| const [, name, expansion = ''] = | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. using array destructuring means it will break if Symbol.iterator is deleted off of Array.prototype. this one has a lot of places in the codebase to fix, tho, so it’s probably fine to skip for now. |
||
| StringPrototypeMatch(request, EXPORTS_PATTERN) || []; | ||
| if (!name) { | ||
| return false; | ||
| } | ||
|
|
||
| return path.resolve(nmPath, request); | ||
| const basePath = path.resolve(nmPath, name); | ||
| const fromExports = applyExports(basePath, expansion); | ||
| if (!fromExports) { | ||
| return false; | ||
| } | ||
| return tryFile(fromExports, false); | ||
| } | ||
|
|
||
| function isArrayIndex(p) { | ||
|
|
@@ -662,7 +608,15 @@ Module._findPath = function(request, paths, isMain) { | |
| // Don't search further if path doesn't exist | ||
| const curPath = paths[i]; | ||
| if (curPath && stat(curPath) < 1) continue; | ||
| const basePath = resolveExports(curPath, request, absoluteRequest); | ||
|
|
||
| if (!absoluteRequest) { | ||
| const exportsResolved = resolveExports(curPath, request); | ||
| if (exportsResolved) { | ||
| return exportsResolved; | ||
| } | ||
| } | ||
|
|
||
| const basePath = path.resolve(curPath, request); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, although there are a lot of calls to |
||
| let filename; | ||
|
|
||
| const rc = stat(basePath); | ||
|
|
@@ -1005,7 +959,7 @@ Module._resolveFilename = function(request, parent, isMain, options) { | |
| } | ||
|
|
||
| if (parent && parent.filename) { | ||
| const filename = trySelf(parent.filename, isMain, request); | ||
| const filename = trySelf(parent.filename, request); | ||
| if (filename) { | ||
| const cacheKey = request + '\x00' + | ||
| (paths.length === 1 ? paths[0] : paths.join('\x00')); | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.