Skip to content

[Bug] ESM SSR development mode - chunk cache not invalidated properly #13304

@GiveMe-A-Name

Description

@GiveMe-A-Name

[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

  1. Create an SSR project with Modern.js using ESM mode (type: "module" in package.json)
  2. Start the dev server
  3. Modify a page component (e.g., change text in page.tsx)
  4. 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:

  1. The main bundle (index.js) can be reloaded using timestamp or Module._compile
  2. But the chunk loading (__webpack_require__.e) has its own internal caching mechanism
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    teamThe issue/pr is created by the member of Rspack.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions