Skip to content

fix: read react-native shared config from array form of shared - #1454

Open
giaBaoJS wants to merge 1 commit into
callstack:mainfrom
giaBaoJS:fix/mf-shared-array-deep-imports
Open

fix: read react-native shared config from array form of shared#1454
giaBaoJS wants to merge 1 commit into
callstack:mainfrom
giaBaoJS:fix/mf-shared-array-deep-imports

Conversation

@giaBaoJS

@giaBaoJS giaBaoJS commented Sep 6, 2026

Copy link
Copy Markdown

Summary

ModuleFederationPlugin adds react-native/ and @react-native/ to shared so deep imports resolve through the shared scope, and it copies eager, import (and version in V1) from the user's react-native entry. That copy only works when shared is an object. With the array form, the deep imports always end up as eager: true and without import: false.

Reproduction

new Repack.plugins.ModuleFederationPlugin({
  name: 'miniapp',
  shared: [{ 'react-native': { singleton: true, eager: false, import: false } }],
});

Config handed to the underlying ModuleFederationPlugin:

[
  { 'react-native':  { singleton: true, eager: false, import: false } },
  { 'react-native/':  { singleton: true, eager: true, requiredVersion: '*' } }, // wrong
  { '@react-native/': { singleton: true, eager: true, requiredVersion: '*' } }, // wrong
]

The equivalent object form is handled correctly, which is the sibling path that shows the intended behaviour:

shared: { 'react-native': { singleton: true, eager: false, import: false } }
// -> 'react-native/':  { singleton: true, eager: false, requiredVersion: '*', import: false }
// -> '@react-native/': { singleton: true, eager: false, requiredVersion: '*', import: false }

For a remote container this means the React Native deep imports get eagerly bundled into the container instead of being consumed from the host, which is the opposite of what eager: false, import: false asks for.

Root cause

In the array branch, findSharedDependency returned the array item, which is an object keyed by the dependency name ({ 'react-native': {...} }), rather than the config stored under that key. Reading .eager / .import / .requiredVersion off the wrapper therefore always produced undefined, and sharedDependencyConfig fell back to its defaults. The object branch on the next line returns the config itself, so it never had the problem.

What the tests assert

Four new cases, mirroring the existing object-form tests, two per plugin:

  • shared: [{ react: ... }, { 'react-native': { eager: false, ... } }] produces react-native/ and @react-native/ with eager: false (and, for V1, requiredVersion: '0.76.0' rather than '*').
  • shared: [{ 'react-native': { import: false } }] produces both deep imports with import: false.

Without the source change all four fail on the value itself (eager is true instead of false, import is undefined instead of false).

packages/repack jest suite: 312 passing before, 316 after, plus tsc --noEmit and biome check clean.

ModuleFederationPlugin adds `react-native/` and `@react-native/` deep
imports and copies `eager`, `import` and `version` from the user's
`react-native` shared config. When `shared` is given as an array,
findSharedDependency returned the array item itself, which is an object
keyed by the dependency name, so reading `.eager` / `.import` /
`.requiredVersion` off it always yielded undefined and the deep imports
silently fell back to `eager: true` with no `import: false`. The object
form of `shared` returns the config itself and behaves correctly.

Applies to both ModuleFederationPluginV1 and ModuleFederationPluginV2.
@changeset-bot

changeset-bot Bot commented Sep 6, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 2faf061

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

@vercel

vercel Bot commented Sep 6, 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.

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