Skip to content

fix(react-router): avoid Webpack inlining React.use static analysis#7193

Open
SAY-5 wants to merge 2 commits intoTanStack:mainfrom
SAY-5:fix/react-use-webpack-regression
Open

fix(react-router): avoid Webpack inlining React.use static analysis#7193
SAY-5 wants to merge 2 commits intoTanStack:mainfrom
SAY-5:fix/react-use-webpack-regression

Conversation

@SAY-5
Copy link
Copy Markdown

@SAY-5 SAY-5 commented Apr 15, 2026

Per #7176, recent bundler updates inline const REACT_USE = 'use'; React[REACT_USE] back into the literal React['use'] in the published package, which re-triggers Webpack's static analysis and breaks builds against React 18 (which doesn't export use).

This was previously fixed by #6355, but the bundled output regressed somewhere between #6355 and #6926.

This PR replaces the manual indirection with Reflect.get(React, 'use'). Reflect.get is a real runtime call — bundlers don't fold it into a direct property access — so the property name never appears as a static literal in the bundled output, and Webpack's static analyzer has nothing to flag.

Closes #7176

Summary by CodeRabbit

  • Refactor
    • Internal runtime lookup logic adjusted to be safer and more defensive; preserves existing behavior while improving robustness and maintainability, with no changes to public APIs or user-facing functionality.

…anStack#7176)

Recent bundler updates inline `const REACT_USE = 'use'; React[REACT_USE]`
back into the literal `React['use']` in the published package, which
re-triggers Webpack's static analysis and breaks builds against React
18 (which doesn't export `use`).

Use `Reflect.get(React, 'use')` instead. Reflect.get is a real runtime
call — bundlers don't fold it into direct property access — so the
property name never appears as a static literal in the bundled output,
and Webpack's static analyzer has nothing to flag.

Closes TanStack#7176
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 15, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a4a352d8-2edd-4599-8fd3-53ea3c3a2095

📥 Commits

Reviewing files that changed from the base of the PR and between 9396596 and 80a7859.

📒 Files selected for processing (1)
  • packages/react-router/src/utils.ts

📝 Walkthrough

Walkthrough

Replaces module-level string constant and bracket-style lookup for React's "use" with a runtime Reflect.get(React, 'use') lookup and assigns reactUse only if the retrieved value is a function; no exported signatures were changed.

Changes

Cohort / File(s) Summary
React.use access change
packages/react-router/src/utils.ts
Removed REACT_USE constant and replaced (React as any)[REACT_USE] with Reflect.get(React, 'use'). reactUse now conditionally assigns only when the retrieved candidate is a function; export type and signature unchanged.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 I peeked at React and gave a small tug,
Swapped a string for Reflect — light as a hug,
Only a function earns my nod and cheer,
Webpack blinks, the build runs clear! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: using Reflect.get to avoid Webpack static analysis of the React.use property access.
Linked Issues check ✅ Passed The PR directly addresses issue #7176 by replacing direct property access with Reflect.get(React, 'use') to prevent Webpack's static analysis from detecting the 'use' property name, resolving the build error with React 18.
Out of Scope Changes check ✅ Passed All changes in utils.ts are scoped to fixing the Webpack regression for React.use property access; no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 15, 2026

Bundle Size Benchmarks

  • Commit: 0166fe8ba0f3
  • Measured at: 2026-04-15T04:49:05.336Z
  • Baseline source: history:f7f00250f39c
  • Dashboard: bundle-size history
Scenario Current (gzip) Delta vs baseline Raw Brotli Trend
react-router.minimal 87.37 KiB +28 B (+0.03%) 274.65 KiB 75.88 KiB ▂▁▁▁▁▁▁▃▃▃▃█
react-router.full 90.66 KiB +28 B (+0.03%) 285.79 KiB 78.79 KiB ▃▁▁▁▁▁▁▂▂▅▅█
solid-router.minimal 35.51 KiB 0 B (0.00%) 106.60 KiB 31.91 KiB █▁▁▁▁▁▁▃▃▃▃
solid-router.full 39.99 KiB 0 B (0.00%) 120.09 KiB 35.93 KiB █▁▁▁▁▁▁▆▆▆▆
vue-router.minimal 53.30 KiB 0 B (0.00%) 152.01 KiB 47.88 KiB █▁▁▁▁▁▁▄▄▄▄
vue-router.full 58.20 KiB 0 B (0.00%) 167.43 KiB 52.06 KiB █▁▁▁▁▁▁▄▄▄▄
react-start.minimal 101.79 KiB +21 B (+0.02%) 322.44 KiB 88.06 KiB ▃▁▁▁▁▁▁▂▂▅▅█
react-start.full 105.23 KiB +24 B (+0.02%) 332.77 KiB 90.88 KiB ▃▁▁▁▁▁▁▂▂▅▅█
solid-start.minimal 49.52 KiB 0 B (0.00%) 152.41 KiB 43.66 KiB █▁▁▁▁▁▁▄▄▄▄
solid-start.full 55.04 KiB 0 B (0.00%) 168.61 KiB 48.44 KiB █▁▁▁▁▁▁▅▅▅▅

Trend sparkline is historical gzip bytes ending with this PR measurement; lower is better.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/react-router/src/utils.ts`:
- Around line 17-19: The exported reactUse is assigned via Reflect.get(React,
'use') which is typed as any at runtime; add a runtime guard that verifies the
retrieved value is actually a function (and optionally has arity 1) before
assigning/exporting it so the runtime value matches the declared signature.
Replace the direct Reflect.get usage with a checked assignment: get the
candidate via Reflect.get(React, 'use'), verify typeof candidate === 'function'
(and candidate.length === 1 if you want stricter validation), and only then cast
and export it as reactUse; otherwise export undefined. This uses the existing
reactUse symbol and Reflect.get(React, 'use') location to find and fix the code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 10224a06-e4b6-4a96-8b78-cc7cad4debf5

📥 Commits

Reviewing files that changed from the base of the PR and between 0166fe8 and 9396596.

📒 Files selected for processing (1)
  • packages/react-router/src/utils.ts

Wrap the Reflect.get result in a typeof check before exporting as reactUse
so the runtime value is guaranteed to be a function matching the declared
signature, rather than relying solely on the TypeScript cast.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regression: React.use build error with React 18 and Webpack

1 participant