Ghost fallback chunks / import: false behaviour with large transitive dep trees — Re.Pack MF
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 55/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Quiet
- Tech stack
- javascript, react, react-native, typescript
- Domain
- build-system, mobile
Research direction
Start with host/webpack.config.mjs, app1/webpack.config.mjs, and app1/src/App.tsx, then reproduce the issue with the listed bundle commands. Inspect the generated app1/build/ios/*.chunk.bundle files and compare the grep counts and sizes with the expected results: moment should not appear in the exposed chunk, which should remain about 50 KB.
Written by the indexing model from the issue text.
Description
Environment
Re.Pack: @callstack/repack 4.4.1
webpack: 5.107.2
Platform: Android
Description
I've been working through the optimal shared config for a production React Native app with Module Federation and have a few questions based on testing against your example at repack-examples/module-federation/app1/webpack.config.mjs.
Observation 1 : Official example only shares react + react-native, The example only declares react and react-native as shared. In a real app with large SDKs (tracking, UI component libraries, animation, totalling ~80 MB
bundled), should these also be declared as shared singletons? If not, are two instances of a tracking SDK acceptable in a host+remote setup?
Observation 2 : eager: STANDALONE produces ~78 MB ghost fallback chunks for large packages
When I apply eager: STANDALONE (i.e. eager: false in APK builds) to a package with a large transitive dep tree (e.g. @shared/trackingsdk, whose tree totals ~78 MB), webpack generates ghost fallback chunks of ~78 MB.
This happens even after declaring all of the package's direct deps as shared — the
bloat comes from deeper transitive deps not in the shared scope. I found that eager: true eliminates the ghost chunks (code goes into the container instead), but multiplies APK size when adding more remotes (each container duplicates the ~80 MB).
Observation 3 : import: false doesn't suppress transitive bundling, I tried { singleton: true, eager: false, import: false } to avoid both the ghost chunk and the container copy — expecting webpack to generate only a
consume-shared stub. The container correctly shrank to ~50 KB, but the exposed module chunk (App_SRP_js.chunk.bundle) absorbed the full ~79 MB dep tree instead. The bytes moved files, not disappeared.
Questions:
- Is import: false supported in Re.Pack's ModuleFederationPlugin? The behaviour differs from webpack 5's documented spec.
- For packages with large transitive dep trees, what is the recommended approach to avoid both ghost chunks AND container bloat when the host always provides these deps?
- The comment in your example says "to be figured out" on the eager: STANDALONE line : is there an updated recommendation for production setups?
Reproducible Demo
Base repo: callstack/repack-examples (module-federation example)
Branch to fork: main
Step 1 — Add moment as a test package moment is used as the probe, 392 KB bundled, easy to detect with grep, no native deps.
cd module-federation
yarn add moment
Step 2 — Modify host webpack config, In host/webpack.config.mjs, add moment to the shared config so the host provides it:
shared: {
react: { singleton: true, eager: true },
'react-native': { singleton: true, eager: true },
moment: { singleton: true, eager: true }, // ← add this
},
Step 3 — Modify app1 (remote) webpack config, In app1/webpack.config.mjs, add moment with import: false:
shared: {
react: { singleton: true, eager: STANDALONE },
'react-native': { singleton: true, eager: STANDALONE },
moment: { singleton: true, eager: false, import: false }, // ← add this
},
Step 4 — Import moment in the exposed component, In app1/src/App.tsx, add a direct import:
import moment from 'moment';
// use it anywhere so webpack doesn't tree-shake it
console.log(moment().format('YYYY'));
Step 5 — Build and inspect
Build host (provides moment to shared scope)
cd host && yarn bundle:ios # or android
Build remote
cd app1 && yarn bundle:ios
Step 6 — Check remote output
Should print 0 — moment must NOT be in the exposed chunk
grep -c "isMoment|_isUTC|proto.format" app1/build/ios/*.chunk.bundle
Check bundle sizes
ls -lh app1/build/ios/*.bundle
Expected result
grep output
0 ← moment is consumed from shared scope, not bundled
Exposed module chunk
app1_src_App_tsx.chunk.bundle ~50 KB (just App.tsx, no moment)
Actual result
grep output
14 ← moment IS in the exposed module chunk
Exposed module chunk
app1_src_App_tsx.chunk.bundle ~450 KB (App.tsx + full moment library)
With import: false, webpack 5 MF spec says no local fallback should be generated — the module is consumed exclusively from the shared scope. However, Re.Pack's ModuleFederationPlugin compiles the package into the exposed module chunk instead. The bytes change location but are never absent.
- Dominant language
- Java
- Stars
- 69
- Forks
- 23
- PR merge metrics
- No merged PRs in 30d
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from callstack/repack-examples
-
Difficulty 3/5 1-2 days Newbie friendliness 25/100
callstack/repack-examples#12 · 2 comments ·
-
Difficulty 3/5 1-2 days Newbie friendliness 25/100
callstack/repack-examples#11 · 1 comment · 1 reaction ·
-
question
Difficulty 3/5 1-2 days Newbie friendliness 25/100
callstack/repack-examples#10 · 4 comments ·
-
Difficulty 5/5 Over a week Newbie friendliness 20/100
-
Difficulty 4/5 3-5 days Newbie friendliness 30/100
callstack/repack-examples#7 · 4 comments ·
All issues in callstack/repack-examples
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
infinispan/infinispan#18150 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
opensearch-project/k-NN#3597 ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100