Skip to content

[Bug]: split route modules drop exported clientLoader dependencies #15335

Description

@comp615

Reproduction

Failing Framework Mode integration test based on the repository's integration/bug-report-test.ts template:

https://github.com/comp615/react-router/blob/d53520674e7b2b9281045c9aa597a01702ac9bf6/integration/bug-report-test.ts

Run from the repository root:

pnpm install
pnpm build
pnpm test:integration:run bug-report --project chromium

The fixture enables route-module splitting, performs a successful production build, starts the production server, and navigates to a route whose clientLoader calls a sibling exported helper:

export function exportedHelper() {
  return "Loaded through exported helper";
}

export function clientLoader() {
  return exportedHelper();
}

The fixture build exits successfully. Client navigation then renders the Application Error boundary with:

ReferenceError: exportedHelper is not defined
    at dependency-client-loader-*.js

This was originally reproduced with @react-router/dev 7.18.1. The linked test reproduces it on current main at d2f1f1baa, whose workspace packages are versioned 8.2.0.

System Info

System:
  OS: macOS 26.5.2
  CPU: (16) arm64 Apple M3 Max
  Memory: 11.42 GB / 64.00 GB
  Shell: 5.9 - /bin/zsh
Binaries:
  Node: 24.16.0
  npm: 11.13.0
  pnpm: 11.7.0
Browsers:
  Chrome: 150.0.7871.125
  Firefox: 152.0.5
  Safari: 26.5.2
npmPackages:
  @react-router/dev: workspace:* => 8.2.0
  react-router: workspace:* => 8.2.0
  vite: ^7.0.0 => 7.3.1

Used Package Manager

pnpm

Expected Behavior

A split clientLoader chunk should retain all module-local declarations selected as dependencies of clientLoader, including sibling exported function or class declarations. The production route should load and render Loaded through exported helper.

Actual Behavior

The production build succeeds, but the generated clientLoader chunk calls exportedHelper without including its declaration. Client navigation fails at runtime with ReferenceError: exportedHelper is not defined.

Dependency analysis selects the helper, but a later filter removes exported function/class declarations unless their declaration name equals the selected route export name (clientLoader here). The filter is still present in:

A non-exported helper does not go through this filter and is retained, so removing only the export modifier avoids the runtime failure.

🤖 Report and reproduction prepared with AI assistance.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions