fix(enhanced): key cache serializers by install directory - #5144
ScriptedAlchemy wants to merge 2 commits into
Conversation
Two installed copies of enhanced in one process both registered their classes under the same 'enhanced/lib/...' key, and webpack's global serializer registry throws on the second registration.
🦋 Changeset detectedLatest commit: 8b63693 The changes in this PR will be included in the next version bump. This PR includes changesets to release 48 packages
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 |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
@module-federation/devtools
@module-federation/cli
create-module-federation
@module-federation/dts-plugin
@module-federation/enhanced
@module-federation/error-codes
@module-federation/esbuild
@module-federation/managers
@module-federation/manifest
@module-federation/metro
@module-federation/metro-plugin-rnc-cli
@module-federation/metro-plugin-rnef
@module-federation/metro-plugin-rock
@module-federation/modern-js
@module-federation/modern-js-v3
@module-federation/native-federation-tests
@module-federation/native-federation-typescript
@module-federation/nextjs-mf
@module-federation/node
@module-federation/observability-plugin
@module-federation/playground
@module-federation/retry-plugin
@module-federation/rsbuild-plugin
@module-federation/rspack
@module-federation/rspress-plugin
@module-federation/rstest
@module-federation/runtime
@module-federation/runtime-core
@module-federation/runtime-tools
@module-federation/sdk
@module-federation/storybook-addon
@module-federation/third-party-dts-extractor
@module-federation/treeshake-frontend
@module-federation/treeshake-server
@module-federation/typescript
@module-federation/utilities
@module-federation/webpack-bundler-runtime
@module-federation/bridge-react
@module-federation/bridge-react-webpack-plugin
@module-federation/bridge-shared
@module-federation/bridge-vue3
@module-federation/inject-external-runtime-core-plugin
commit: |
Bundle Size Report6 package(s) changed, 37 unchanged. Package dist + ESM entry
Bundle targets
Consumer scenarios
Total dist (raw): 23.41 MB (+981 B (+0.0%)) Bundle sizes are generated with rslib (Rspack). Package-root metrics preserve the historical report. Tracked subpath exports such as |
Found while building the RFC #5128 stack; the same fix is carried in #5140.
Symptom
When two installed copies of
@module-federation/enhancedload in one webpack process (for example the app's copy and the one@module-federation/nodedepends on), the second copy throws as soon as its plugin applies:It fails at module load, with or without
cache: { type: 'filesystem' }.Root cause
Every serializable class called webpack's
makeSerializable(Class, 'enhanced/lib/...')with a fixed key. Webpack's serializer registry is process-wide and throws when a key is registered twice, so the second copy cannot load.Fix
All 16 call sites now go through
src/lib/makeSerializable.ts, which passes the copy's install directory as webpack'snameargument. Each copy gets its own key, and the key stays the same across runs for a given install.Skipping the duplicate registration was rejected. The second copy's classes would have no serializer, so webpack could not persist its modules. It would also make cache restore depend on which copy loaded first, even when the two copies are different versions. With per-copy keys, each copy's cache entries are restored by that copy's own classes. Existing caches are not affected in practice. Upgrading enhanced changes its build dependencies, which invalidates the pack before any entry is read.
Test plan
test/compiler-unit/container/duplicateEnhancedCopies.test.tsruns a child Node process that loads the builtdistfrom two directories with one shared webpack. It builds withModuleFederationPluginfrom each copy using the filesystem cache, then rebuilds. The test asserts no errors or cache warnings, and that the remote, consume, and provide modules are restored from the cache on the second build (0 rebuilt). The test fails onmainwith the error above and passes with the fix.pnpm --filter @module-federation/enhanced testpasses (463 + 6 tests).Related open PRs
makeSerializablecall inAsyncEntrypointRuntimeDependency.ts. Whichever PR lands second should route that call through the new helper.FederationCompositionPlugintest swallows the "already registered" error to load a second copy. This fix makes that workaround unnecessary.