Turbopack: Generate a warning if both react-compiler and styled-jsx are enabled, suggest manually configuring them with babelrc#84006
Conversation
…re enabled, suggest manually configuring them with babelrc
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
| const text = session | ||
| .elementByCss('#react-compiler-enabled-message') | ||
| .text() |
There was a problem hiding this comment.
The test code is missing await keywords, which will cause the text comparison to fail.
View Details
📝 Patch Details
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index fceb9cd1a1..0741166ac5 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -290,7 +290,7 @@ importers:
version: 5.2.1(eslint@9.12.0(jiti@2.5.1))
eslint-plugin-import:
specifier: 2.31.0
- version: 2.31.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.12.0(jiti@2.5.1))
+ version: 2.31.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.12.0(jiti@2.5.1)))(eslint@9.12.0(jiti@2.5.1)))(eslint@9.12.0(jiti@2.5.1))
eslint-plugin-jest:
specifier: 27.6.3
version: 27.6.3(@typescript-eslint/eslint-plugin@8.36.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.12.0(jiti@2.5.1))(jest@29.7.0(@types/node@20.17.6(patch_hash=rvl3vkomen3tospgr67bzubfyu))(babel-plugin-macros@3.1.0))(typescript@5.9.2)
@@ -660,7 +660,7 @@ importers:
version: 9.12.0(jiti@2.5.1)
eslint-config-next:
specifier: canary
- version: link:../../packages/eslint-config-next
+ version: 15.6.0-canary.19(eslint-plugin-import-x@4.3.1(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2)
tailwindcss:
specifier: 4.1.13
version: 4.1.13
@@ -4401,6 +4401,9 @@ packages:
'@next/env@15.5.3':
resolution: {integrity: sha512-RSEDTRqyihYXygx/OJXwvVupfr9m04+0vH8vyy0HfZ7keRto6VX9BbEk0J2PUk0VGy6YhklJUSrgForov5F9pw==}
+ '@next/eslint-plugin-next@15.6.0-canary.19':
+ resolution: {integrity: sha512-oQ8YlBf8fad7UmfVRaIC6pio9LAIz2c/0UqHWFmA1bGb2zNHtiys3pitJKH38PKXeaXy//MwGKiiY+tVg5dD8Q==}
+
'@next/swc-darwin-arm64@15.5.3':
resolution: {integrity: sha512-nzbHQo69+au9wJkGKTU9lP7PXv0d1J5ljFpvb+LnEomLtSbJkbZyEs6sbF3plQmiOB2l9OBtN2tNSvCH1nQ9Jg==}
engines: {node: '>= 10'}
@@ -9210,6 +9213,15 @@ packages:
engines: {node: '>=6.0'}
hasBin: true
+ eslint-config-next@15.6.0-canary.19:
+ resolution: {integrity: sha512-JMoW38eXd9C5hCXZm9LGYEbWJ0cdYtAq8oPsSJ/Y8vuWEN455e17OrFngdWw4BrhXEqzaR5sKO+emD+AoE3cVA==}
+ peerDependencies:
+ eslint: ^7.23.0 || ^8.0.0 || ^9.0.0
+ typescript: '>=3.3.1'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
eslint-formatter-codeframe@7.32.1:
resolution: {integrity: sha512-DK/3Q3+zVKq/7PdSYiCxPrsDF8H/TRMK5n8Hziwr4IMkMy+XiKSwbpj25AdajS63I/B61Snetq4uVvX9fOLyAg==}
engines: {node: ^10.12.0 || >=12.0.0}
@@ -14736,6 +14748,7 @@ packages:
engines: {node: '>=0.6.0', teleport: '>=0.2.0'}
deprecated: |-
You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.
+
(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)
qs@6.11.0:
@@ -21048,6 +21061,10 @@ snapshots:
'@next/env@15.5.3': {}
+ '@next/eslint-plugin-next@15.6.0-canary.19':
+ dependencies:
+ fast-glob: 3.3.1
+
'@next/swc-darwin-arm64@15.5.3':
optional: true
@@ -26701,6 +26718,26 @@ snapshots:
optionalDependencies:
source-map: 0.6.1
+ eslint-config-next@15.6.0-canary.19(eslint-plugin-import-x@4.3.1(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2):
+ dependencies:
+ '@next/eslint-plugin-next': 15.6.0-canary.19
+ '@rushstack/eslint-patch': 1.10.4
+ '@typescript-eslint/eslint-plugin': 8.36.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2)
+ '@typescript-eslint/parser': 8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2)
+ eslint: 9.12.0(jiti@2.5.1)
+ eslint-import-resolver-node: 0.3.9
+ eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.12.0(jiti@2.5.1)))(eslint@9.12.0(jiti@2.5.1))
+ eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.12.0(jiti@2.5.1)))(eslint@9.12.0(jiti@2.5.1)))(eslint@9.12.0(jiti@2.5.1))
+ eslint-plugin-jsx-a11y: 6.10.0(eslint@9.12.0(jiti@2.5.1))
+ eslint-plugin-react: 7.37.1(eslint@9.12.0(jiti@2.5.1))
+ eslint-plugin-react-hooks: 5.0.0(eslint@9.12.0(jiti@2.5.1))
+ optionalDependencies:
+ typescript: 5.9.2
+ transitivePeerDependencies:
+ - eslint-import-resolver-webpack
+ - eslint-plugin-import-x
+ - supports-color
+
eslint-formatter-codeframe@7.32.1:
dependencies:
'@babel/code-frame': 7.12.11
@@ -26734,6 +26771,26 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
+ eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.12.0(jiti@2.5.1)))(eslint@9.12.0(jiti@2.5.1)):
+ dependencies:
+ '@nolyfill/is-core-module': 1.0.39
+ debug: 4.3.7
+ enhanced-resolve: 5.17.1
+ eslint: 9.12.0(jiti@2.5.1)
+ eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.12.0(jiti@2.5.1)))(eslint@9.12.0(jiti@2.5.1)))(eslint@9.12.0(jiti@2.5.1))
+ fast-glob: 3.3.2
+ get-tsconfig: 4.8.1
+ is-bun-module: 1.2.1
+ is-glob: 4.0.3
+ optionalDependencies:
+ eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.12.0(jiti@2.5.1)))(eslint@9.12.0(jiti@2.5.1)))(eslint@9.12.0(jiti@2.5.1))
+ eslint-plugin-import-x: 4.3.1(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2)
+ transitivePeerDependencies:
+ - '@typescript-eslint/parser'
+ - eslint-import-resolver-node
+ - eslint-import-resolver-webpack
+ - supports-color
+
eslint-mdx@3.1.5(eslint@9.12.0(jiti@2.5.1)):
dependencies:
acorn: 8.14.0
@@ -26766,13 +26823,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-module-utils@2.12.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.12.0(jiti@2.5.1)):
+ eslint-module-utils@2.12.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.12.0(jiti@2.5.1)))(eslint@9.12.0(jiti@2.5.1)))(eslint@9.12.0(jiti@2.5.1)):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2)
eslint: 9.12.0(jiti@2.5.1)
eslint-import-resolver-node: 0.3.9
+ eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.12.0(jiti@2.5.1)))(eslint@9.12.0(jiti@2.5.1))
transitivePeerDependencies:
- supports-color
@@ -26800,6 +26858,24 @@ snapshots:
- typescript
optional: true
+ eslint-plugin-import-x@4.3.1(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2):
+ dependencies:
+ '@typescript-eslint/utils': 8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2)
+ debug: 4.4.0
+ doctrine: 3.0.0
+ eslint: 9.12.0(jiti@2.5.1)
+ eslint-import-resolver-node: 0.3.9
+ get-tsconfig: 4.10.0
+ is-glob: 4.0.3
+ minimatch: 9.0.5
+ semver: 7.6.3
+ stable-hash: 0.0.4
+ tslib: 2.8.1
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+ optional: true
+
eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.16.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@9.12.0(jiti@2.5.1)):
dependencies:
'@rtsao/scc': 1.1.0
@@ -26829,7 +26905,7 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
- eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.12.0(jiti@2.5.1)):
+ eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.12.0(jiti@2.5.1)))(eslint@9.12.0(jiti@2.5.1)))(eslint@9.12.0(jiti@2.5.1)):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.8
@@ -26840,7 +26916,7 @@ snapshots:
doctrine: 2.1.0
eslint: 9.12.0(jiti@2.5.1)
eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.12.0(jiti@2.5.1))
+ eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.36.0(eslint@9.12.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.12.0(jiti@2.5.1)))(eslint@9.12.0(jiti@2.5.1)))(eslint@9.12.0(jiti@2.5.1))
hasown: 2.0.2
is-core-module: 2.15.1
is-glob: 4.0.3
diff --git a/test/e2e/react-compiler-with-styled-jsx/index.test.ts b/test/e2e/react-compiler-with-styled-jsx/index.test.ts
index 106b394974..26ed04ca91 100644
--- a/test/e2e/react-compiler-with-styled-jsx/index.test.ts
+++ b/test/e2e/react-compiler-with-styled-jsx/index.test.ts
@@ -137,7 +137,7 @@ describe('react-compiler-with-styled-jsx', () => {
it('applies the react compiler transform', async () => {
const session = await next.browser('/')
await retry(async () => {
- const text = session
+ const text = await session
.elementByCss('#react-compiler-enabled-message')
.text()
expect(text).toMatch(/React compiler is enabled/)
Analysis
Missing await keyword causes test failure in elementByCss chain
What fails: session.elementByCss().text() chain on line 140-142 returns a Promise object instead of text string, causing expect(text).toMatch() to fail
How to reproduce:
# The test would fail because text is a Promise, not a string:
const text = session.elementByCss('#react-compiler-enabled-message').text()
expect(text).toMatch(/React compiler is enabled/) // Matches against Promise objectResult: Test assertion fails because regex match operates on Promise object instead of actual text content
Expected: Should await the full chain like other tests in the codebase: await session.elementByCss(...).text() to get the actual text string
Evidence: All other elementByCss usage in codebase consistently uses await before the entire chain - see test/development/acceptance-app/error-recovery.test.ts:431 and similar patterns
| let $_: any | ||
| if (typeof window !== 'undefined') { | ||
| // eslint-disable-next-line no-eval | ||
| $_ = eval('typeof $ !== undefined ? $ : undefined') |
There was a problem hiding this comment.
| $_ = eval('typeof $ !== undefined ? $ : undefined') | |
| $_ = eval('typeof $ !== "undefined" ? $ : undefined') |
The eval statement has a syntax error that will cause the React Compiler detection to fail.
View Details
Analysis
React Compiler detection fails due to incorrect typeof comparison
What fails: The eval statement in page.tsx line 11 compares typeof $ (string "undefined") to undefined (value), causing ReferenceError when $ is not defined
How to reproduce:
cd test/e2e/react-compiler-with-styled-jsx
node -e "eval('typeof $ !== undefined ? $ : undefined')"Result: Throws ReferenceError: $ is not defined instead of returning undefined
Expected: Should return undefined when React Compiler hasn't injected the $ variable, allowing the detection logic to work properly
The issue occurs because typeof $ returns the string "undefined" when $ is not defined, but the code compares this to the value undefined. Since "undefined" !== undefined is true, the ternary tries to access $, which throws a ReferenceError.

I've decided this approach is a dead-end, but I'm putting the PR up here for reference.
Suggesting manual configuration of both babel plugins could serve as a stopgap solution for using react-compiler with styled-jsx.
But now I've realized that it's not really practical to ask the user to manually configure react-compiler with babel. We run babel transforms on both client+server, and there's no sane way to specify that a transform (
react-compiler) is client-only in the babel configuration file format (thenext/babelpreset uses some webpack loader magic to pass down this information).So instead, I need to go straight for the harder-but-"better" solution, which is to generate a warning, and to expose an option in
compiler.styledJsxto use the babel implementation. Fortunately, #83502 already lays most of the groundwork needed for that.