Skip to content

TURBOPACK: Fix subpath imports resolving to dependencies#150

Merged
fireairforce merged 1 commit into
utoofrom
fix/turbopack-subpath-imports-dependencies
May 19, 2026
Merged

TURBOPACK: Fix subpath imports resolving to dependencies#150
fireairforce merged 1 commit into
utoofrom
fix/turbopack-subpath-imports-dependencies

Conversation

@yuzheng14
Copy link
Copy Markdown

Summary

  • Allow package.json subpath imports targets to resolve as bare package specifiers instead of always forcing relative paths.
  • Add a snapshot fixture verifying an imports entry can point to a dependency in node_modules.

Upstream PR vercel#93308 is addressing the same issue, but there is no clear timeline on when it will be merged.

Test plan

  • cargo test -p turbopack-tests snapshot covers subpath-imports resolving to a node_modules dependency

Allow package.json subpath imports targets to resolve as bare package specifiers instead of always forcing relative paths. Add a snapshot fixture that verifies an imports entry can point to a dependency in node_modules.
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates Turbopack's resolution logic to support subpath imports by allowing both relative and bare specifier resolutions. It also exposes the ExportImport enum internally and adds a test case for subpath imports within node_modules. Feedback was provided regarding the use of Pattern::alternatives in handle_exports_imports_field, which may introduce ambiguity or deviate from the Node.js specification. The reviewer suggested a refactor to improve readability and ensure spec compliance.

Comment on lines +3268 to +3274
let request =
Pattern::Concatenation(vec![Pattern::Constant(rcstr!("./")), result_path.clone()]);
let request = match kind {
ExportImport::Export => request,
ExportImport::Import => Pattern::alternatives(vec![request, result_path.clone()]),
};
let request = *Request::parse(request).to_resolved().await?;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using Pattern::alternatives to try both a relative path (prefixed with ./) and the original path for subpath imports can lead to ambiguous resolution. According to the Node.js specification, subpath import targets are either relative (starting with ./ or ../) or bare package specifiers. Trying both might cause a bare specifier like "#dep": "my-pkg" to accidentally resolve to a local file ./my-pkg if it exists, which deviates from standard Node.js behavior.

If the intention is to strictly follow the spec, result_path.clone() should be sufficient for ExportImport::Import, as Request::parse will correctly handle the relativeness based on the prefix. If backward compatibility for missing ./ prefixes is required, the current approach is a safe fallback, but the code can be simplified to avoid redundant shadowing and improve readability.

            let request = match kind {
                ExportImport::Export => {
                    Pattern::Concatenation(vec![Pattern::Constant(rcstr!("./")), result_path.clone()])
                }
                ExportImport::Import => Pattern::alternatives(vec![
                    Pattern::Concatenation(vec![
                        Pattern::Constant(rcstr!("./")),
                        result_path.clone(),
                    ]),
                    result_path.clone(),
                ]),
            };
            let request = *Request::parse(request).to_resolved().await?;

@yuzheng14 yuzheng14 requested review from fireairforce and xusd320 May 19, 2026 08:55
@fireairforce fireairforce merged commit e3b7a69 into utoo May 19, 2026
17 of 31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants