Skip to content

Conversation

@xusd320
Copy link

@xusd320 xusd320 commented Jan 7, 2026

This PR refactors the Resolution Plugin traits to use Option for their conditions. This allow plugins to return None, skipping the expensive matches task calls entirely. Testing on a medium project showed a reduction of resolve_call tasks.

@gemini-code-assist
Copy link

Summary of Changes

Hello @xusd320, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant optimization to Turbopack's resolution plugin system. By refactoring plugin conditions to use Rust's Option type, plugins can now signal when their conditions are not applicable, preventing the system from performing unnecessary and computationally intensive matching operations. This change streamlines the resolution process, leading to improved performance by reducing redundant task executions.

Highlights

  • Performance Optimization: Refactored resolution plugin traits to utilize Option for their conditions, allowing plugins to explicitly return None when they don't apply, thereby skipping expensive matches task calls. This change has shown a reduction in resolve_call tasks on a medium project.
  • API Change: Introduced OptionBeforeResolvePluginCondition and OptionAfterResolvePluginCondition types, modifying the before_resolve_condition and after_resolve_condition trait methods to return these new Option-wrapped conditions.
  • Plugin Integration: Updated several existing plugins across next-core (e.g., NextFontLocalResolvePlugin, ExternalCjsModulesResolvePlugin, InvalidImportResolvePlugin, NextExternalResolvePlugin, NextNodeSharedRuntimeResolvePlugin, ModuleFeatureReportResolvePlugin, NextSharedRuntimeResolvePlugin) to conform to the new Option based condition API.
  • Core Resolution Logic Update: Modified the core handle_before_resolve_plugins and handle_after_resolve_plugins functions in turbopack-core to correctly process the new Option conditions, only evaluating and matching conditions when they are Some.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@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 refactors the resolution plugin traits to use Option for their conditions, which is a good optimization to avoid expensive matches calls. The changes across the various plugins are consistent with this new approach.

However, I've found a potential correctness issue in how the matches task is being called in turbopack/crates/turbopack-core/src/resolve/mod.rs. The Vc is being resolved to its value before the task is called, which is not the standard pattern for turbo_tasks. I've provided suggestions to fix this.

Additionally, the logic for handling these optional conditions can be simplified to improve readability and reduce code duplication. My suggestions also include refactoring for better maintainability. Please review the detailed comments.

Comment on lines +1688 to 1694
let condition_option = plugin.before_resolve_condition().await?;
if let Some(condition) = *condition_option {
let condition = condition.resolve().await?;
if !*condition.matches(request).await? {
continue;
}
}

Choose a reason for hiding this comment

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

high

This block has a potential correctness issue and can be refactored for better readability.

  1. condition.resolve().await? resolves the Vc to an Arc<...>, but turbo_tasks::functions like matches should be called on the Vc itself.
  2. The logic can be flattened to avoid nested if statements by first determining if the condition matches, and then acting on it.

Here is a suggested refactoring that addresses both points.

Suggested change
let condition_option = plugin.before_resolve_condition().await?;
if let Some(condition) = *condition_option {
let condition = condition.resolve().await?;
if !*condition.matches(request).await? {
continue;
}
}
let condition_option = plugin.before_resolve_condition().await?;
let matches = if let Some(condition) = *condition_option {
*condition.resolve().matches(request).await?
} else {
true
};
if !matches {
continue;
}

Comment on lines +1722 to 1748
let after_resolve_condition_option = plugin.after_resolve_condition().await?;
if let Some(after_resolve_condition) = *after_resolve_condition_option {
let after_resolve_condition = after_resolve_condition.resolve().await?;
if *after_resolve_condition.matches(path.clone()).await?
&& let Some(result) = *plugin
.after_resolve(
path.clone(),
lookup_path.clone(),
reference_type.clone(),
request,
)
.await?
{
return Ok(Some(*result));
}
} else if let Some(result) = *plugin
.after_resolve(
path.clone(),
lookup_path.clone(),
reference_type.clone(),
request,
)
.await?
{
// If there is no condition, the plugin applies to all paths.
return Ok(Some(*result));
}

Choose a reason for hiding this comment

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

high

This block has a potential correctness issue and can be significantly simplified to improve readability and reduce code duplication.

  1. Similar to the before_resolve handler, after_resolve_condition.resolve().await? is used, which is likely incorrect for calling a turbo_tasks::function. matches should be called on the Vc.
  2. The plugin.after_resolve(...) call is duplicated in both the if and else if branches.
  3. The overall logic can be flattened.

Here's a suggested refactoring that addresses these points.

            let after_resolve_condition_option = plugin.after_resolve_condition().await?;
            let matches = if let Some(after_resolve_condition) = *after_resolve_condition_option {
                *after_resolve_condition.resolve().matches(path.clone()).await?
            } else {
                // If there is no condition, the plugin applies to all paths.
                true
            };

            if matches {
                if let Some(result) = *plugin
                    .after_resolve(
                        path.clone(),
                        lookup_path.clone(),
                        reference_type.clone(),
                        request,
                    )
                    .await?
                {
                    return Ok(Some(*result));
                }
            }

@xusd320 xusd320 merged commit 28c7b26 into utoo Jan 7, 2026
12 of 25 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.

3 participants