44# name, source, and directories as upstream's `react_compiler_*`, and adds the
55# metadata + `publish` flags to release `nextjs_react_compiler` and its deps to crates.io.
66#
7+ # The core compiler crates live in react/react:compiler/crates/. The SWC integration
8+ # crate (react_compiler_swc) was moved to swc-project/swc:crates/swc_ecma_react_compiler;
9+ # `sync` pulls from both repos and overlays the swc crate on top of the react/react snapshot.
10+ #
711# The oxc-project org ruleset forbids merge commits, so the vendor is a linear
812# snapshot (not `git subtree`): each `sync` re-extracts upstream's `compiler/`,
913# re-runs the transform tool (./codemod), re-applies ./patches, and commits once.
1014# Both are re-applied every sync because the snapshot is taken fresh.
1115#
1216# just import # one-time: create ./react-compiler (transformed)
13- # just sync # update ./react-compiler to the latest main state (re-transformed)
17+ # just sync # update ./react-compiler from both upstreams, re-transform, commit
18+ # just sync-react # extract react/react compiler crates only (no commit)
19+ # just sync-swc # extract swc-project/swc integration crate only (no commit)
1420# just codemod # (re)run codemod on ./react-compiler in place
1521# just patch # apply ./patches/*.patch (Rust source changes the codemod can't express)
1622# just check # cargo check the vendored workspace
@@ -23,38 +29,94 @@ upstream_ref := "main"
2329src_dir := " compiler" # path of the compiler inside the react monorepo
2430prefix := " react-compiler" # where it lives in THIS repo
2531
32+ swc_repo := " https://github.com/swc-project/swc.git"
33+ swc_ref := " main"
34+ swc_src := " crates/swc_ecma_react_compiler" # path within swc-project/swc
35+ swc_dest := " react_compiler_swc" # crate directory name in this repo
36+
2637# Show available recipes
2738default :
2839 @ just --list
2940
3041# One-time import (same operation as sync; kept for discoverability)
3142import : sync
3243
33- # Snapshot react's `compiler/` into ./{{prefix}}, set published names to nextjs_react_compiler_*, commit once
44+ # Full sync: extract from both upstreams, transform, patch, and commit.
3445sync :
3546 #!/usr/bin/env bash
3647 set -euo pipefail
37- git fetch --depth=1 --no-tags {{react_repo}} {{upstream_ref}}
38- upstream=" $( git rev-parse FETCH_HEAD) "
39- tree=" $( git rev-parse " FETCH_HEAD:{{src_dir}}" ) "
4048 # Preserve the currently-published version across the wipe so cargo-release-oxc
4149 # stays the single source of truth — the codemod re-stamps whatever is committed
4250 # rather than inventing a number.
4351 version=" $( sed -n ' s/^version = "\(.*\)"/\1/p' {{prefix}}/Cargo.toml | head -1) "
4452 version=" ${version:- 0.1.0} "
45- git rm -r --cached --quiet --ignore-unmatch {{prefix}}
46- rm -rf {{prefix}}
47- git read-tree --prefix={{prefix}}/ -u " $tree "
53+ just sync-react
54+ just sync-swc
4855 just codemod " $version "
4956 just patch
5057 git add -A {{prefix}}
5158 if git diff --cached --quiet -- {{prefix}}; then
52- echo " {{prefix}} already at react {{upstream_ref}} @ ${upstream} — nothing to commit."
59+ echo " {{prefix}} already up to date — nothing to commit."
5360 else
54- git commit -q -m " vendor: react-compiler from {{upstream_ref}} @ ${upstream} (nextjs_react_compiler) "
55- echo " Committed {{prefix}} @ ${upstream} ."
61+ git commit -q -m " vendor: sync react-compiler from react/react and swc-project/swc "
62+ echo " Committed {{prefix}}."
5663 fi
5764
65+ # Extract the React compiler crates from react/react into ./{{prefix}}.
66+ # Wipes and re-extracts the full tree; run sync-swc afterward to overlay the SWC crate.
67+ sync-react :
68+ #!/usr/bin/env bash
69+ set -euo pipefail
70+ git fetch --depth=1 --no-tags {{react_repo}} {{upstream_ref}}
71+ upstream=" $( git rev-parse FETCH_HEAD) "
72+ tree=" $( git rev-parse " FETCH_HEAD:{{src_dir}}" ) "
73+ git rm -r --cached -f --quiet --ignore-unmatch {{prefix}}
74+ rm -rf {{prefix}}
75+ git read-tree --prefix={{prefix}}/ -u " $tree "
76+ echo " sync-react: {{prefix}} from {{react_repo}} @ ${upstream} "
77+
78+ # Extract the SWC integration crate from swc-project/swc into ./{{prefix}}/crates/{{swc_dest}}.
79+ # The SWC crate was moved out of react/react; this overlays it on top of a sync-react extraction.
80+ sync-swc :
81+ #!/usr/bin/env bash
82+ set -euo pipefail
83+ git fetch --depth=1 --no-tags {{swc_repo}} {{swc_ref}}
84+ swc_upstream=" $( git rev-parse FETCH_HEAD) "
85+ swc_tree=" $( git rev-parse " FETCH_HEAD:{{swc_src}}" ) "
86+ dest=" {{prefix}}/crates/{{swc_dest}}"
87+ git rm -r --cached -f --quiet --ignore-unmatch " $dest "
88+ rm -rf " $dest "
89+ git read-tree --prefix=" $dest /" -u " $swc_tree "
90+ just _fixup-swc-cargo " $dest /Cargo.toml"
91+ echo " sync-swc: {{swc_dest}} from {{swc_repo}} @ ${swc_upstream} "
92+
93+ # Post-process the upstream swc crate's Cargo.toml to fit our workspace:
94+ # - rename from the swc upstream name to our crate name (codemod adds the nextjs_ prefix)
95+ # - strip monorepo path deps, leaving only the crates.io version
96+ # - resolve swc-workspace-inherited deps to explicit crates.io versions
97+ # - drop [dev-dependencies] (swc-internal test harness not available on crates.io)
98+ _ fixup-swc-cargo cargo :
99+ #!/usr/bin/env bash
100+ set -euo pipefail
101+ cargo=" {{cargo}}"
102+ # All sed substitutions in one pass → temp file → replace (avoids BSD/GNU -i differences)
103+ sed -E \
104+ -e ' s/^(name[[:space:]]*=[[:space:]]*)"swc_ecma_react_compiler"/\1"react_compiler_swc"/' \
105+ -e ' s/,[[:space:]]*path[[:space:]]*=[[:space:]]*"[^"]*"//g' \
106+ -e ' s/^(rustc-hash[[:space:]]*=[[:space:]]*)\{[^}]*workspace[^}]*\}/\1"2"/' \
107+ -e ' s/^(serde[[:space:]]*=[[:space:]]*)\{[^}]*workspace[^}]*\}/\1{ version = "1", features = ["derive"] }/' \
108+ -e ' s/^(serde_json[[:space:]]*=[[:space:]]*)\{[^}]*workspace[^}]*\}/\1"1"/' \
109+ -e ' s/^(indexmap[[:space:]]*=[[:space:]]*)\{[^}]*workspace[^}]*\}/\1{ version = "2", features = ["serde"] }/' \
110+ -e ' s/^(swc_atoms[[:space:]]*=[[:space:]]*)\{[^}]*\}/\1"9"/' \
111+ -e ' s/^(swc_common[[:space:]]*=[[:space:]]*)\{[^}]*\}/\1"21"/' \
112+ -e ' s/^(swc_ecma_ast[[:space:]]*=[[:space:]]*)\{[^}]*\}/\1"23"/' \
113+ -e ' s/^(swc_ecma_codegen[[:space:]]*=[[:space:]]*)\{[^}]*\}/\1"26"/' \
114+ -e ' s/^(swc_ecma_parser[[:space:]]*=[[:space:]]*)\{[^}]*\}/\1"39"/' \
115+ -e ' s/^(swc_ecma_visit[[:space:]]*=[[:space:]]*)\{[^}]*\}/\1"23"/' \
116+ " $cargo " > " ${cargo} .tmp" && mv " ${cargo} .tmp" " $cargo "
117+ # Drop [dev-dependencies] section — the `testing` crate is swc-internal and not on crates.io
118+ awk ' /^\[dev-dependencies\]/{skip=1; next} skip && /^\[/{skip=0} !skip{print}' " $cargo " > " ${cargo} .tmp" && mv " ${cargo} .tmp" " $cargo "
119+
58120# (Re)run codemod on ./{{prefix}}: published names, workspace deps, publish flags, LICENSE, oxc_release.toml.
59121# `version` defaults to the version already in the tree (cargo-release-oxc owns the bumps).
60122codemod version = ` sed -n ' s/^version = "\(.*\)"/\1/p' react-compiler/Cargo.toml 2> /dev/null | head -1 ` :
0 commit comments