From 186b52731c6bb326c4d32905c5e732d082e83465 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Tue, 19 Nov 2024 09:57:12 -0500 Subject: [PATCH] fix(node): handle resolving ".//" in npm packages (#26920) The issue was this package had an import like: `".//index.js"` and we resolved that as specified, but node normalizes it to `"./index.js"` so we have to copy node. --- cli/module_loader.rs | 15 --------------- resolvers/node/resolution.rs | 13 ++++++++++++- .../specifier-two-slashes/1.0.0/index.js | 2 ++ .../specifier-two-slashes/1.0.0/other.js | 3 +++ .../specifier-two-slashes/1.0.0/package.json | 6 ++++++ .../npm/specifier_two_slashes/__test__.jsonc | 4 ++++ tests/specs/npm/specifier_two_slashes/main.ts | 3 +++ 7 files changed, 30 insertions(+), 16 deletions(-) create mode 100644 tests/registry/npm/@denotest/specifier-two-slashes/1.0.0/index.js create mode 100644 tests/registry/npm/@denotest/specifier-two-slashes/1.0.0/other.js create mode 100644 tests/registry/npm/@denotest/specifier-two-slashes/1.0.0/package.json create mode 100644 tests/specs/npm/specifier_two_slashes/__test__.jsonc create mode 100644 tests/specs/npm/specifier_two_slashes/main.ts diff --git a/cli/module_loader.rs b/cli/module_loader.rs index b9adfe642c..60de808b2d 100644 --- a/cli/module_loader.rs +++ b/cli/module_loader.rs @@ -474,21 +474,6 @@ impl raw_specifier: &str, referrer: &ModuleSpecifier, ) -> Result { - if self.shared.in_npm_pkg_checker.in_npm_package(referrer) { - return Ok( - self - .shared - .node_resolver - .resolve( - raw_specifier, - referrer, - self.shared.cjs_tracker.get_referrer_kind(referrer), - NodeResolutionMode::Execution, - )? - .into_url(), - ); - } - let graph = self.graph_container.graph(); let resolution = match graph.get(referrer) { Some(Module::Js(module)) => module diff --git a/resolvers/node/resolution.rs b/resolvers/node/resolution.rs index 673a61abe6..c2ec25aca4 100644 --- a/resolvers/node/resolution.rs +++ b/resolvers/node/resolution.rs @@ -202,7 +202,7 @@ impl NodeResolver { mode: NodeResolutionMode, ) -> Result { if should_be_treated_as_relative_or_absolute_path(specifier) { - Ok(referrer.join(specifier).map_err(|err| { + Ok(node_join_url(referrer, specifier).map_err(|err| { NodeResolveRelativeJoinError { path: specifier.to_string(), base: referrer.clone(), @@ -1763,6 +1763,17 @@ fn get_module_name_from_builtin_node_module_specifier( Some(specifier) } +/// Node is more lenient joining paths than the url crate is, +/// so this function handles that. +fn node_join_url(url: &Url, path: &str) -> Result { + if let Some(suffix) = path.strip_prefix(".//") { + // specifier had two leading slashes + url.join(&format!("./{}", suffix)) + } else { + url.join(path) + } +} + #[cfg(test)] mod tests { use serde_json::json; diff --git a/tests/registry/npm/@denotest/specifier-two-slashes/1.0.0/index.js b/tests/registry/npm/@denotest/specifier-two-slashes/1.0.0/index.js new file mode 100644 index 0000000000..aca5ca1b8e --- /dev/null +++ b/tests/registry/npm/@denotest/specifier-two-slashes/1.0.0/index.js @@ -0,0 +1,2 @@ +// node.js will resolve this as ./other.js +export * from ".//other.js"; \ No newline at end of file diff --git a/tests/registry/npm/@denotest/specifier-two-slashes/1.0.0/other.js b/tests/registry/npm/@denotest/specifier-two-slashes/1.0.0/other.js new file mode 100644 index 0000000000..7d658310b0 --- /dev/null +++ b/tests/registry/npm/@denotest/specifier-two-slashes/1.0.0/other.js @@ -0,0 +1,3 @@ +export function add(a, b) { + return a + b; +} diff --git a/tests/registry/npm/@denotest/specifier-two-slashes/1.0.0/package.json b/tests/registry/npm/@denotest/specifier-two-slashes/1.0.0/package.json new file mode 100644 index 0000000000..55e46b2fd1 --- /dev/null +++ b/tests/registry/npm/@denotest/specifier-two-slashes/1.0.0/package.json @@ -0,0 +1,6 @@ +{ + "name": "@denotest/specifier-two-slashes", + "version": "1.0.0", + "type": "module", + "main": "index.js" +} \ No newline at end of file diff --git a/tests/specs/npm/specifier_two_slashes/__test__.jsonc b/tests/specs/npm/specifier_two_slashes/__test__.jsonc new file mode 100644 index 0000000000..bddbdbc1c8 --- /dev/null +++ b/tests/specs/npm/specifier_two_slashes/__test__.jsonc @@ -0,0 +1,4 @@ +{ + "args": "run --quiet main.ts", + "output": "3\n" +} diff --git a/tests/specs/npm/specifier_two_slashes/main.ts b/tests/specs/npm/specifier_two_slashes/main.ts new file mode 100644 index 0000000000..ef1adceb5c --- /dev/null +++ b/tests/specs/npm/specifier_two_slashes/main.ts @@ -0,0 +1,3 @@ +import { add } from "npm:@denotest/specifier-two-slashes"; + +console.log(add(1, 2));