summaryrefslogtreecommitdiff
path: root/ext/node/analyze.rs
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2023-11-07 09:56:06 -0500
committerGitHub <noreply@github.com>2023-11-07 09:56:06 -0500
commit9201198efd6fb116585d4c26111669f4c1006e5d (patch)
tree746b2283da7edb457cea5eced2bc6cd7b42b8067 /ext/node/analyze.rs
parent50e4806a2db66be289aa123a0bfd8dd8688712ba (diff)
fix(node): inspect ancestor directories when resolving cjs re-exports during analysis (#21104)
If a CJS re-export can't be resolved, it will check the ancestor directories, which is more similar to what `require` does at runtime.
Diffstat (limited to 'ext/node/analyze.rs')
-rw-r--r--ext/node/analyze.rs48
1 files changed, 32 insertions, 16 deletions
diff --git a/ext/node/analyze.rs b/ext/node/analyze.rs
index c9b23211e..994295578 100644
--- a/ext/node/analyze.rs
+++ b/ext/node/analyze.rs
@@ -193,7 +193,6 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
}
// We've got a bare specifier or maybe bare_specifier/blah.js"
-
let (package_specifier, package_subpath) =
parse_specifier(specifier).unwrap();
@@ -205,14 +204,13 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
)?;
let package_json_path = module_dir.join("package.json");
- if self.fs.exists_sync(&package_json_path) {
- let package_json = PackageJson::load(
- &*self.fs,
- &*self.npm_resolver,
- permissions,
- package_json_path.clone(),
- )?;
-
+ let package_json = PackageJson::load(
+ &*self.fs,
+ &*self.npm_resolver,
+ permissions,
+ package_json_path.clone(),
+ )?;
+ if package_json.exists {
if let Some(exports) = &package_json.exports {
return self.node_resolver.package_exports_resolve(
&package_json_path,
@@ -232,13 +230,13 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
if self.fs.is_dir_sync(&d) {
// subdir might have a package.json that specifies the entrypoint
let package_json_path = d.join("package.json");
- if self.fs.exists_sync(&package_json_path) {
- let package_json = PackageJson::load(
- &*self.fs,
- &*self.npm_resolver,
- permissions,
- package_json_path,
- )?;
+ let package_json = PackageJson::load(
+ &*self.fs,
+ &*self.npm_resolver,
+ permissions,
+ package_json_path,
+ )?;
+ if package_json.exists {
if let Some(main) = package_json.main(NodeModuleKind::Cjs) {
return Ok(d.join(main).clean());
}
@@ -253,6 +251,24 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
return Ok(module_dir.join("index.js").clean());
}
}
+
+ // as a fallback, attempt to resolve it via the ancestor directories
+ let mut last = referrer_path.as_path();
+ while let Some(parent) = last.parent() {
+ if !self.npm_resolver.in_npm_package_at_dir_path(parent) {
+ break;
+ }
+ let path = if parent.ends_with("node_modules") {
+ parent.join(specifier)
+ } else {
+ parent.join("node_modules").join(specifier)
+ };
+ if let Ok(path) = self.file_extension_probe(path, &referrer_path) {
+ return Ok(path);
+ }
+ last = parent;
+ }
+
Err(not_found(specifier, &referrer_path))
}