Skip to content

fix(turbopack): merged alias lost module factory for missing type import#121

Merged
fireairforce merged 1 commit intoutoofrom
fix-merged-alias
Mar 15, 2026
Merged

fix(turbopack): merged alias lost module factory for missing type import#121
fireairforce merged 1 commit intoutoofrom
fix-merged-alias

Conversation

@fireairforce
Copy link
Copy Markdown
Member

fix scope hoisting with missing export type binding cause module factory lost:

image

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, 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 addresses a critical issue in Turbopack where merged aliases were losing their module factories, particularly affecting import namespaces due to incorrect scope hoisting and missing export type bindings. The changes introduce a more robust module merging process that correctly identifies and exposes module factories for these cases, ensuring that bundled modules behave as expected and preventing runtime errors related to missing module definitions.

Highlights

  • Module Merging Logic: Enhanced the merge_modules function to correctly handle and return fallback_import_idents, which are crucial for preserving module factories for aliased imports.
  • Module Factory Exposure: Updated the mechanism for determining additional_ids to ensure that module factories are properly exposed for modules identified by fallback_import_idents or those explicitly marked as external.
  • Configuration Cleanup: Removed a redundant ..Default::default() spread from the decorators configuration, simplifying the code.
Changelog
  • turbopack/crates/turbopack-ecmascript/src/lib.rs
    • Modified the merge_modules function signature and return type to include fallback_import_idents.
    • Refactored the logic for collecting additional_ids to incorporate fallback_import_idents when determining which module factories to expose.
  • turbopack/crates/turbopack-ecmascript/src/transform/mod.rs
    • Removed redundant ..Default::default() from the decorators configuration.
Activity
  • No human activity has been recorded on this pull request yet.
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.

@fireairforce fireairforce changed the title fix(turbopack): merged alias lost module factory for import namespace… fix(turbopack): merged alias lost module factory for missing type import Mar 15, 2026
@fireairforce fireairforce merged commit 2772655 into utoo Mar 15, 2026
9 of 24 checks passed
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 appears to fix an issue in Turbopack's scope hoisting where a module factory was being lost. This is achieved by passing around fallback_import_idents from the module merging step and using this information to correctly identify all modules that require a module factory. The logic seems sound. I've included one suggestion to optimize a loop by avoiding unnecessary object creation, which should provide a minor performance benefit. The other change in transform/mod.rs appears to be a necessary code cleanup, possibly due to a dependency update, and looks correct.

Comment on lines +1188 to +1200
if module == first_entry {
return None;
}
let fallback_ident: Atom =
crate::magic_identifier::mangle(&format!("imported module {module_id}"))
.into();
if exposure == MergeableModuleExposure::External
|| fallback_import_idents.contains(&fallback_ident)
{
Some(module_id)
} else {
None
}
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

For a minor performance improvement, you can avoid the cost of creating fallback_ident (which involves string formatting, mangling, and atom interning) when exposure == MergeableModuleExposure::External is true. By checking for this condition first and returning early, you can skip the unnecessary work inside this filter_map closure.

                    if module == first_entry {
                        return None;
                    }
                    if exposure == MergeableModuleExposure::External {
                        return Some(module_id);
                    }
                    let fallback_ident: Atom =
                        crate::magic_identifier::mangle(&format!("imported module {module_id}"))
                            .into();
                    if fallback_import_idents.contains(&fallback_ident) {
                        Some(module_id)
                    } else {
                        None
                    }

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.

1 participant