diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2022-09-12 15:47:54 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-12 15:47:54 -0400 |
commit | 98454c1eb802b91a8c77dd97888a8994c85dfa46 (patch) | |
tree | 851f7590f14a2f54db5ef306e884cc2c64bf6f07 /cli/node/mod.rs | |
parent | a3a4760831e14307a9499d4e410cf1653b416dc1 (diff) |
fix(npm): support cjs resolution of package subpath with package.json (#15855)
Diffstat (limited to 'cli/node/mod.rs')
-rw-r--r-- | cli/node/mod.rs | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/cli/node/mod.rs b/cli/node/mod.rs index 75fdfcd7d..690a21181 100644 --- a/cli/node/mod.rs +++ b/cli/node/mod.rs @@ -9,6 +9,7 @@ use crate::deno_std::CURRENT_STD_URL; use deno_ast::CjsAnalysis; use deno_ast::MediaType; use deno_ast::ModuleSpecifier; +use deno_core::anyhow::anyhow; use deno_core::anyhow::bail; use deno_core::anyhow::Context; use deno_core::error::generic_error; @@ -534,9 +535,7 @@ fn package_config_resolve( referrer_kind: NodeModuleKind, ) -> Result<PathBuf, AnyError> { let package_json_path = package_dir.join("package.json"); - let referrer = - ModuleSpecifier::from_directory_path(package_json_path.parent().unwrap()) - .unwrap(); + let referrer = ModuleSpecifier::from_directory_path(package_dir).unwrap(); let package_config = PackageJson::load(npm_resolver, package_json_path.clone())?; if let Some(exports) = &package_config.exports { @@ -770,7 +769,16 @@ pub fn translate_cjs_to_esm( let reexport_specifier = ModuleSpecifier::from_file_path(&resolved_reexport).unwrap(); // Second, read the source code from disk - let reexport_file = file_fetcher.get_source(&reexport_specifier).unwrap(); + let reexport_file = file_fetcher + .get_source(&reexport_specifier) + .ok_or_else(|| { + anyhow!( + "Could not find '{}' ({}) referenced from {}", + reexport, + reexport_specifier, + referrer + ) + })?; { let analysis = perform_cjs_analysis( @@ -873,11 +881,21 @@ fn resolve( let d = module_dir.join(package_subpath); if let Ok(m) = d.metadata() { if m.is_dir() { + // subdir might have a package.json that specifies the entrypoint + let package_json_path = d.join("package.json"); + if package_json_path.exists() { + let package_json = + PackageJson::load(npm_resolver, package_json_path)?; + if let Some(main) = package_json.main(NodeModuleKind::Cjs) { + return Ok(d.join(main).clean()); + } + } + return Ok(d.join("index.js").clean()); } } return file_extension_probe(d, &referrer_path); - } else if let Some(main) = package_json.main { + } else if let Some(main) = package_json.main(NodeModuleKind::Cjs) { return Ok(module_dir.join(main).clean()); } else { return Ok(module_dir.join("index.js").clean()); @@ -895,7 +913,7 @@ fn parse_specifier(specifier: &str) -> Option<(String, String)> { } else if specifier.starts_with('@') { // is_scoped = true; if let Some(index) = separator_index { - separator_index = specifier[index + 1..].find('/'); + separator_index = specifier[index + 1..].find('/').map(|i| i + index + 1); } else { valid_package_name = false; } @@ -1027,4 +1045,12 @@ mod tests { ] ) } + + #[test] + fn test_parse_specifier() { + assert_eq!( + parse_specifier("@some-package/core/actions"), + Some(("@some-package/core".to_string(), "./actions".to_string())) + ); + } } |