Skip to content

Commit c99d42e

Browse files
feat: add support for react compiler (#6211)
Co-authored-by: Hector Garcia <[email protected]>
1 parent 34b7917 commit c99d42e

File tree

11 files changed

+222
-5
lines changed

11 files changed

+222
-5
lines changed

.changeset/clean-ends-end.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@primer/react': minor
3+
---
4+
5+
Add partial support for React Compiler to components

.github/workflows/migration-status.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,21 @@ on:
55
workflow_dispatch:
66

77
jobs:
8+
react-compiler:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
12+
- name: Set up Node.js
13+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
14+
with:
15+
node-version: 22
16+
cache: 'npm'
17+
- name: Install dependencies
18+
run: npm ci
19+
- name: Run migration script
20+
run: |
21+
node --experimental-strip-types script/react-compiler-migration-status.mts >> $GITHUB_STEP_SUMMARY
22+
823
styled-components:
924
runs-on: ubuntu-latest
1025
steps:

package-lock.json

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/react/.storybook/main.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import path from 'node:path'
33
import react from '@vitejs/plugin-react'
44
import postcssPresetPrimer from 'postcss-preset-primer'
55
import type {StorybookConfig} from '@storybook/react-vite'
6+
import {isSupported} from '../script/react-compiler.mjs'
67

78
const require = createRequire(import.meta.url)
89

@@ -55,7 +56,22 @@ const config: StorybookConfig = {
5556
config.css.postcss.plugins = [postcssPresetPrimer()]
5657
}
5758

58-
config.plugins = [...(config.plugins ?? []), react()]
59+
config.plugins = [
60+
...(config.plugins ?? []),
61+
react({
62+
babel: {
63+
plugins: [
64+
[
65+
'babel-plugin-react-compiler',
66+
{
67+
sources: (filepath: string) => isSupported(filepath),
68+
target: '18',
69+
},
70+
],
71+
],
72+
},
73+
}),
74+
]
5975

6076
if (DEPLOY_ENV === 'development') {
6177
config.server = {

packages/react/babel.config.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
const defines = require('./babel-defines')
2+
const {isSupported} = require('./script/react-compiler.mjs')
23

34
function replacementPlugin(env) {
45
return ['babel-plugin-transform-replace-expressions', {replace: defines[env]}]
56
}
67

78
const sharedPlugins = [
9+
[
10+
'babel-plugin-react-compiler',
11+
{
12+
target: '18',
13+
sources: isSupported,
14+
},
15+
],
816
'macros',
917
'dev-expression',
1018
'add-react-displayname',

packages/react/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
"hsluv": "1.0.1",
105105
"lodash.isempty": "^4.4.0",
106106
"lodash.isobject": "^3.0.2",
107+
"react-compiler-runtime": "^19.1.0-rc.2",
107108
"react-intersection-observer": "^9.16.0",
108109
"react-is": "^18.2.0",
109110
"styled-system": "^5.1.5",
@@ -164,6 +165,7 @@
164165
"babel-plugin-dev-expression": "0.2.3",
165166
"babel-plugin-macros": "3.1.0",
166167
"babel-plugin-open-source": "1.3.4",
168+
"babel-plugin-react-compiler": "^19.1.0-rc.2",
167169
"babel-plugin-styled-components": "2.1.4",
168170
"babel-plugin-transform-replace-expressions": "0.2.0",
169171
"babel-polyfill": "6.26.0",

packages/react/rollup.config.mjs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {importCSS} from 'rollup-plugin-import-css'
99
import postcss from 'rollup-plugin-postcss'
1010
import postcssPresetPrimer from 'postcss-preset-primer'
1111
import MagicString from 'magic-string'
12+
import {isSupported} from './script/react-compiler.mjs'
1213
import packageJson from './package.json' with {type: 'json'}
1314

1415
const input = new Set([
@@ -83,6 +84,13 @@ const baseConfig = {
8384
],
8485
],
8586
plugins: [
87+
[
88+
'babel-plugin-react-compiler',
89+
{
90+
target: '18',
91+
sources: filepath => isSupported(filepath),
92+
},
93+
],
8694
'macros',
8795
'add-react-displayname',
8896
'dev-expression',
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import path from 'node:path'
2+
import glob from 'fast-glob'
3+
import {fileURLToPath} from 'node:url'
4+
5+
const PACKAGE_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
6+
const files = glob
7+
.sync('src/**/*.{ts,tsx}', {
8+
cwd: PACKAGE_DIR,
9+
ignore: ['**/*.d.ts'],
10+
})
11+
.map(match => {
12+
return path.join(PACKAGE_DIR, match)
13+
})
14+
const unsupported = new Set(
15+
[
16+
'src/ActionList/**/*.tsx',
17+
'src/ActionMenu/**/*.tsx',
18+
'src/AvatarStack/**/*.tsx',
19+
'src/Button/**/*.tsx',
20+
'src/ConfirmationDialog/**/*.tsx',
21+
'src/Pagehead/**/*.tsx',
22+
'src/Pagination/**/*.tsx',
23+
'src/PointerBox/**/*.tsx',
24+
'src/SelectPanel/**/*.tsx',
25+
'src/SideNav.tsx',
26+
'src/internal/components/CheckboxOrRadioGroup/**/*.tsx',
27+
].flatMap(pattern => {
28+
if (glob.isDynamicPattern(pattern)) {
29+
const matches = glob.sync(pattern, {cwd: PACKAGE_DIR})
30+
if (matches) {
31+
return matches.map(match => {
32+
return path.join(PACKAGE_DIR, match)
33+
})
34+
}
35+
}
36+
return path.join(PACKAGE_DIR, pattern)
37+
}),
38+
)
39+
40+
function isSupported(filepath) {
41+
return !unsupported.has(filepath)
42+
}
43+
44+
const notMigrated = Array.from(unsupported)
45+
46+
export {files, notMigrated, isSupported}

packages/react/src/SegmentedControl/SegmentedControl.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ describe('SegmentedControl', () => {
397397
</SegmentedControl>,
398398
)
399399

400-
expect(spy).toHaveBeenCalledTimes(2)
400+
expect(spy).toHaveBeenCalledTimes(1)
401401
spy.mockRestore()
402402
})
403403

packages/react/vitest.config.mts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
1-
import {defineConfig} from 'vitest/config'
21
import react from '@vitejs/plugin-react'
2+
import {defineConfig} from 'vitest/config'
3+
import {isSupported} from './script/react-compiler.mjs'
34

45
export default defineConfig({
5-
plugins: [react()],
6+
plugins: [
7+
react({
8+
babel: {
9+
plugins: [
10+
[
11+
'babel-plugin-react-compiler',
12+
{
13+
sources: (filepath: string) => isSupported(filepath),
14+
target: '18',
15+
},
16+
],
17+
],
18+
},
19+
}),
20+
],
621
define: {
722
__DEV__: true,
823
},
@@ -12,4 +27,3 @@ export default defineConfig({
1227
environment: 'node',
1328
},
1429
})
15-

0 commit comments

Comments
 (0)