Current Behavior
NxModuleFederationDevServerPlugin serves static remotes through a raw http-server fork with no cache flag:
|
const httpServerProcess = fork( |
|
pathToHttpServer, |
|
[ |
|
commonOutputDirectory!, |
|
`-p=${staticRemotesPort}`, |
|
`-a=localhost`, |
|
`--cors`, |
|
], |
http-server's default Cache-Control is max-age=3600 (1 hour). With the exact binary and args the plugin forks (http-server@14.1.1, -a=localhost --cors, no -c):
$ curl -sI http://localhost:<staticRemotesPort>/index.html | grep -i -E '^HTTP|cache-control'
HTTP/1.1 200 OK
cache-control: max-age=3600
So every static remote asset — including remoteEntry.js — is cached by the browser for an hour. When a static remote is rebuilt (each nx serve of the host rebuilds them), a normal reload keeps using the cached remoteEntry.js, which points at chunk hashes that no longer exist on the file server → ChunkLoadError for that remote until the cache expires or is cleared manually.
Expected Behavior
Dev-time static remotes are served uncached. This is exactly what #27005 fixed for the executor-based dev-server, and the executor path still has it (cacheSeconds: -1):
The flag was never ported when the plugin path reimplemented the file server as a direct http-server fork.
Steps to Reproduce
- React Module Federation workspace (host + remotes) using
NxModuleFederationDevServerPlugin; nx serve <host> so the remotes are served statically.
curl -sI http://localhost:<staticRemotesPort>/<remote>/remoteEntry.js | grep -i cache-control → max-age=3600.
- Change a static remote, re-run the serve, reload the app (devtools closed) → the browser reuses the cached
remoteEntry.js → ChunkLoadError on chunks whose hashes changed.
We hit this in a 17-remote production monorepo. We have been running the one-line fix — -c-1 on the forked http-server, matching #27005 — via a pnpm patch since Nx 23. PR follows.
Context: the plugin path is the v24 migration target
The executor-based module-federation-dev-server — the path that still has the cacheSeconds: -1 fix — is deprecated with removal in Nx v24, and now warns at runtime directing users to the @nx/react:consumer / NxModuleFederationDevServerPlugin model:
|
"x-deprecated": "The `@nx/rspack:module-federation-dev-server` executor is deprecated. Dynamic federation in `@nx/react:consumer` removes the need for host-orchestrated remote serving. Removed in Nx v24.", |
We migrated our workspace to the plugin model following that guidance, which is how we hit this. Once the executors are removed in v24 the plugin path is the only dev-serving path, so this is a parity gap on the migration target rather than an edge case — everyone following the deprecation warning inherits it.
Nx Report
Node : 24.17.0
pnpm : 11.8.0
nx (and all @nx/* plugins) : 23.0.0
@nx/module-federation : 23.0.0
typescript : 5.9.3
Current Behavior
NxModuleFederationDevServerPluginserves static remotes through a rawhttp-serverfork with no cache flag:nx/packages/module-federation/src/plugins/utils/start-static-remotes-file-server.ts
Lines 44 to 51 in 0824cce
http-server's defaultCache-Controlismax-age=3600(1 hour). With the exact binary and args the plugin forks (http-server@14.1.1,-a=localhost --cors, no-c):So every static remote asset — including
remoteEntry.js— is cached by the browser for an hour. When a static remote is rebuilt (eachnx serveof the host rebuilds them), a normal reload keeps using the cachedremoteEntry.js, which points at chunk hashes that no longer exist on the file server →ChunkLoadErrorfor that remote until the cache expires or is cleared manually.Expected Behavior
Dev-time static remotes are served uncached. This is exactly what #27005 fixed for the executor-based dev-server, and the executor path still has it (
cacheSeconds: -1):nx/packages/module-federation/src/executors/utils/start-static-remotes-file-server.ts
Line 62 in 0824cce
The flag was never ported when the plugin path reimplemented the file server as a direct
http-serverfork.Steps to Reproduce
NxModuleFederationDevServerPlugin;nx serve <host>so the remotes are served statically.curl -sI http://localhost:<staticRemotesPort>/<remote>/remoteEntry.js | grep -i cache-control→max-age=3600.remoteEntry.js→ChunkLoadErroron chunks whose hashes changed.We hit this in a 17-remote production monorepo. We have been running the one-line fix —
-c-1on the forkedhttp-server, matching #27005 — via a pnpm patch since Nx 23. PR follows.Context: the plugin path is the v24 migration target
The executor-based
module-federation-dev-server— the path that still has thecacheSeconds: -1fix — is deprecated with removal in Nx v24, and now warns at runtime directing users to the@nx/react:consumer/NxModuleFederationDevServerPluginmodel:nx/packages/rspack/src/executors/module-federation-dev-server/schema.json
Line 6 in 9f2d9bc
We migrated our workspace to the plugin model following that guidance, which is how we hit this. Once the executors are removed in v24 the plugin path is the only dev-serving path, so this is a parity gap on the migration target rather than an edge case — everyone following the deprecation warning inherits it.
Nx Report