[Bug] ESM SSR development mode - chunk cache not invalidated properly
Description
In ESM SSR development mode, when source files are modified, the server-rendered content doesn't reflect the changes, causing hydration mismatch errors. This is because rspack's internal chunk loading mechanism doesn't properly invalidate the cache.
Steps to Reproduce
- Create an SSR project with Modern.js using ESM mode (
type: "module" in package.json)
- Start the dev server
- Modify a page component (e.g., change text in page.tsx)
- Refresh the browser
Expected Behavior
The server should render the updated content.
Actual Behavior
The server renders stale content while the client has the new content, causing a hydration mismatch error:
Hydration failed because the server rendered text didn't match the client
+ ESM-CACHE-REPRODUCE
- Welcome to111
Root Cause Analysis(maybe, but i not sure)
When rspack bundles the code, it uses code splitting - the main bundle (index.js) loads page chunks dynamically via __webpack_require__.e("page").
The problem is:
- The main bundle (
index.js) can be reloaded using timestamp or Module._compile
- But the chunk loading (
__webpack_require__.e) has its own internal caching mechanism
- This chunk cache is not properly invalidated in development mode
Bundle Structure
dist/bundles/
├── index.js # Main bundle (can be reloaded)
├── index-server-loaders.js # Server loaders
└── page.js # Page chunk (NOT reloaded - uses cached version)
How it works
In the bundled index.js, there's code like:
// This is rspack-generated code
__webpack_require__.e("page").then(() => {
return __webpack_require__("./src/routes/page.tsx");
})
The __webpack_require__.e function is rspack's internal chunk loading mechanism, which has its own cache that's not controlled by external timestamp/cache-busting mechanisms.
Environment
- rspack: latest
- Node.js: 20+
- Modern.js: V3
Comparison with CJS mode
In CJS mode (MODERN_LIB_FORMAT !== 'esm'), this issue doesn't occur because:
- Uses
require() which has a writable cache (require.cache)
- Can directly delete cache entries:
delete require.cache[filepath]
In ESM mode:
- Uses
import() which has a read-only cache (import.meta.cache)
- Cannot directly invalidate the cache
Suggested Fix
The chunk loading mechanism (__webpack_require__.e) should properly handle cache invalidation in development mode, similar to how it handles HMR for client-side code.
Related
[Bug] ESM SSR development mode - chunk cache not invalidated properly
Description
In ESM SSR development mode, when source files are modified, the server-rendered content doesn't reflect the changes, causing hydration mismatch errors. This is because rspack's internal chunk loading mechanism doesn't properly invalidate the cache.
Steps to Reproduce
type: "module"in package.json)Expected Behavior
The server should render the updated content.
Actual Behavior
The server renders stale content while the client has the new content, causing a hydration mismatch error:
Root Cause Analysis(maybe, but i not sure)
When rspack bundles the code, it uses code splitting - the main bundle (
index.js) loads page chunks dynamically via__webpack_require__.e("page").The problem is:
index.js) can be reloaded using timestamp or Module._compile__webpack_require__.e) has its own internal caching mechanismBundle Structure
How it works
In the bundled
index.js, there's code like:The
__webpack_require__.efunction is rspack's internal chunk loading mechanism, which has its own cache that's not controlled by external timestamp/cache-busting mechanisms.Environment
Comparison with CJS mode
In CJS mode (
MODERN_LIB_FORMAT !== 'esm'), this issue doesn't occur because:require()which has a writable cache (require.cache)delete require.cache[filepath]In ESM mode:
import()which has a read-only cache (import.meta.cache)Suggested Fix
The chunk loading mechanism (
__webpack_require__.e) should properly handle cache invalidation in development mode, similar to how it handles HMR for client-side code.Related