feat(es/react-compiler): Add React Compiler#11917
Conversation
🦋 Changeset detectedLatest commit: b3b2571 The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Merging this PR will not alter performance
Comparing Footnotes
|
7b77755 to
d3a25d2
Compare
There was a problem hiding this comment.
Can you use oxc-project/forked-react-compiler for testing?
d3a25d2 to
871eddb
Compare
**Related issue:** - #11917 - #react/react#36173
548bc1a to
78acfef
Compare
|
Still working on this. |
78acfef to
6e42318
Compare
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
4dc33fb to
a3d28ed
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a3d28ed826
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@magic-akari Can you reflect the unresolved review items? You can mark them as resolved if those are not correct |
|
In the long run, we should consider merging the swc |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2568cfdbc1
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
The binary size increases by ~5MB: This is expected but can probably be further optimized. See oxc-project/oxc#22942 (comment). |
Done. All issues have been marked as resolved, including two fixes. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c510a6ada8
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
292e7e6 to
7f88b5d
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7f88b5dcbe
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
7f88b5d to
a76a723
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a76a723924
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b3b2571b20
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ScopeFlags::Class | ScopeFlags::StrictMode, | ||
| class_decl.class.span, | ||
| ); | ||
| class_decl.class.visit_children_with(self); |
There was a problem hiding this comment.
Keep static-block vars scoped to the block
When a class contains a static {} block, this default class traversal reaches the static block as an ordinary block under the class scope; var declarations inside it then use enclosing_function_scope() and get registered in the outer program/function scope. For inputs like const x = 1; class C { static { var x = 2; } } function App() { return x; }, ScopeInfo can resolve App's x to the static-block-local var even though static-block vars do not escape, so React Compiler dependency/rename analysis can target the wrong binding; handle StaticBlock with its own var scope before visiting its body.
Useful? React with 👍 / 👎.
| }), | ||
| Expression::Import(import) => swc::Callee::Import(swc::Import { | ||
| span: self.span_from_base(&import.base), | ||
| phase: swc::ImportPhase::Evaluation, |
There was a problem hiding this comment.
Preserve dynamic import phases
For source/defer dynamic imports that pass through this bridge, this hard-coded Evaluation phase turns import.source("foo") or import.defer("foo") into a plain import("foo") after React Compiler is enabled. SWC stores the phase on Callee::Import and codegen uses it to print .source/.defer, so preserve the original phase in the call shell instead of resetting it here.
Useful? React with 👍 / 👎.
| if self.declaration_starts.contains(&start) { | ||
| return; | ||
| } | ||
| self.reference_identifier(ident); |
There was a problem hiding this comment.
Skip intrinsic JSX tags in scope references
When a component/file also has a binding named like an intrinsic tag, for example const div = value; function App() { return <div />; }, SWC's JSXElementName::Ident traversal reaches this catch-all identifier visitor and records the lowercase tag as a reference to that binding. If React Compiler later renames that binding, the span-based rename plan can rewrite preserved JSX to <div_0 />, and even without a rename it adds a spurious dependency; add a JSX element-name visitor that only references component-like names/member objects and skips intrinsic tags.
Useful? React with 👍 / 👎.
| for (sym_id, &bind_id) in &symbol_to_binding { | ||
| if self.scoping.symbol_name(*sym_id) == name { |
There was a problem hiding this comment.
Bind default-export refs by declaration span
When another symbol with the same name exists anywhere in the file, this unordered HashMap scan can attach the Babel-style ExportDefaultDeclaration reference for export default function Foo() to the wrong Foo binding. React Compiler consumes this ScopeInfo for export/reference analysis, so a nested or sibling same-named symbol can make the default export nondeterministically point at the wrong binding; use the function ident's declaration span or the current scope instead of a name-only scan.
Useful? React with 👍 / 👎.
…ar boundaries (#11943) **Description:** This PR fixes scope analysis edge cases in the React Compiler where `var` declarations and TypeScript constructs were incorrectly hoisted or leaked across scope boundaries. **Design Notes:** `declare` and `global` are TypeScript type-system annotations that don't affect runtime emission, yet they still create declarations that downstream code can reference. The analyzer must walk their bodies normally and create bindings accordingly, rather than skipping traversal. **Changes:** - **Class static blocks as `var` boundaries** `var` declarations inside `static { }` blocks are now scoped to the block itself, matching ECMAScript semantics, instead of leaking into the enclosing function. - **TypeScript namespace / module scopes** `namespace` and `module` bodies now create proper `TsModuleBlock` scopes. Their members are no longer incorrectly hoisted to the Program scope. - **Consistent binding for `declare enum`** `declare enum` is now registered as a local binding so references resolve correctly. - **Refactoring** Renamed `enclosing_function_scope()` → `enclosing_var_scope()` and updated `ScopeFlags` definitions to make scope-kind checks clearer. **Known Limitations:** **TypeScript namespace merging is not yet supported.** The scope collector treats each `namespace`/`module` declaration as an isolated lexical scope. Exported members in one block are not visible to later merged blocks, and they are modeled as plain local bindings. This is a similar issue described in #11607. **BREAKING CHANGE:** <!-- If this PR introduces a breaking change, it must contain a notice for it to be included in the CHANGELOG. Add description or remove entirely if not breaking. You may need to update `MIGRATION.md` for the breaking changes. --> **Related issue (if exists):** - #11917 (comment)
Description:
Add experimental SWC support for the Rust React Compiler from react/react#36173.
This adds the
swc_ecma_react_compilerbridge, SWC <-> React Compiler AST/scope conversion,.swcrcjsc.transform.reactCompilerconfiguration, diagnostics forwarding, JS/WASM option types, and tests ported from the upstream SWC integration.TODO:
BREAKING CHANGE:
Related issue (if exists):