Skip to content

fix: stop DevelopmentPlugin crashing on official MF plugins - #1471

Open
giaBaoJS wants to merge 1 commit into
callstack:mainfrom
giaBaoJS:fix/dev-entries-official-mf-plugin
Open

giaBaoJS wants to merge 1 commit into
callstack:mainfrom
giaBaoJS:fix/dev-entries-official-mf-plugin

Conversation

@giaBaoJS

Copy link
Copy Markdown
Contributor

DevelopmentPlugin has a branch for official Module Federation plugins, but it reads exposes from the wrong property:

// official MF plugins expose _options property
if ('_options' in plugin && plugin.config.exposes) {
  return plugin._options.name;
}

Official plugins (@module-federation/enhanced, and the built-in container.ModuleFederationPlugin in Rspack and webpack) only have _options, so plugin.config is undefined and the entryOption hook throws. Any config that puts one of them next to RepackPlugin fails as soon as the compiler is created in dev with hot enabled:

TypeError: Cannot read properties of undefined (reading 'exposes')
    at .../dist/plugins/DevelopmentPlugin.js:53:49
    at Array.map (<anonymous>)

I reproduced this on main by creating an Rspack compiler with devServer: { hot: true }, new DevelopmentPlugin({ platform: 'ios' }) and each of @module-federation/enhanced/rspack's ModuleFederationPlugin, rspack.container.ModuleFederationPlugin and webpack.container.ModuleFederationPlugin (the last one with a webpack compiler). All three threw, with or without exposes. With this change all three compilers are created.

The _options branch was added in #960 as deliberate support for official plugins. #1085 then added the exposes check to both branches and copied plugin.config into the second one. The fix reads plugin._options.exposes, so official plugins now get the same treatment as Re.Pack's: dev entries are added to the container entry when the plugin exposes modules, and skipped when it does not, which is the #1085 behavior.

There were no tests for DevelopmentPlugin, so I added a small suite with a mock compiler. It captures the entryOption callback and records which entry names receive the development entries:

  • an official plugin with exposes gives ['main', 'remote'] (on main this throws the TypeError above)
  • an official plugin without exposes gives ['main'] (also throws on main)
  • Re.Pack's ModuleFederationPluginV2 with exposes gives ['main', 'remote'] (passes before and after, and guards the unchanged branch)

Each test fails against a different wrong version of the check: dropping the exposes condition, returning plugin.name instead of plugin._options.name, or turning the old read into plugin.config?.exposes so that it no longer throws.

pnpm test: @callstack/repack goes from 38 suites / 342 tests to 39 / 345. The other workspaces are unchanged. pnpm typecheck and pnpm lint:ci are clean. I did not change the constructor.name detection or the webpack-only entry reordering in the same plugin. Both already handle official plugins.

@vercel

vercel Bot commented Sep 27, 2026

Copy link
Copy Markdown

@giaBaoJS is attempting to deploy a commit to the Callstack Team on Vercel.

A member of the Team first needs to authorize it.

@changeset-bot

changeset-bot Bot commented Sep 27, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 071c154

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@callstack/repack Patch
@callstack/repack-plugin-expo-modules Patch
@callstack/repack-plugin-nativewind Patch
@callstack/repack-plugin-reanimated Patch
@callstack/repack-dev-server Patch
@callstack/repack-init Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

This branch has not been deployed

No deployments
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