Skip to content

Commit bab7fb0

Browse files
committed
feat(create-vite): support react compiler
1 parent 8099582 commit bab7fb0

File tree

4 files changed

+112
-9
lines changed

4 files changed

+112
-9
lines changed

packages/create-vite/__tests__/cli.spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,27 @@ test('successfully scaffolds a project with subfolder based on react starter tem
124124
expect(templateFilesReact).toEqual(generatedFiles)
125125
})
126126

127+
test('successfully scaffolds a project based on react-compiler-ts starter template', () => {
128+
const { stdout } = run([projectName, '--template', 'react-compiler-ts'], {
129+
cwd: __dirname,
130+
})
131+
const configFile = fs.readFileSync(
132+
path.join(genPath, 'vite.config.ts'),
133+
'utf-8',
134+
)
135+
const packageJsonFile = fs.readFileSync(
136+
path.join(genPath, 'package.json'),
137+
'utf-8',
138+
)
139+
const readmeFile = fs.readFileSync(path.join(genPath, 'README.md'), 'utf-8')
140+
141+
// Assertions
142+
expect(stdout).toContain(`Scaffolding project in ${genPath}`)
143+
expect(configFile).toContain('babel-plugin-react-compiler')
144+
expect(packageJsonFile).toContain('babel-plugin-react-compiler')
145+
expect(readmeFile).toContain('The React Compiler is enabled on this template')
146+
})
147+
127148
test('works with the -t alias', () => {
128149
const { stdout } = run([projectName, '-t', 'vue'], {
129150
cwd: __dirname,

packages/create-vite/src/index.ts

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,16 @@ Options:
4141
-t, --template NAME use a specific template
4242
4343
Available templates:
44-
${yellow ('vanilla-ts vanilla' )}
45-
${green ('vue-ts vue' )}
46-
${cyan ('react-ts react' )}
47-
${cyan ('react-swc-ts react-swc')}
48-
${magenta ('preact-ts preact' )}
49-
${redBright ('lit-ts lit' )}
50-
${red ('svelte-ts svelte' )}
51-
${blue ('solid-ts solid' )}
52-
${blueBright('qwik-ts qwik' )}`
44+
${yellow ('vanilla-ts vanilla' )}
45+
${green ('vue-ts vue' )}
46+
${cyan ('react-ts react' )}
47+
${cyan ('react-compiler-ts react-compiler')}
48+
${cyan ('react-swc-ts react-swc' )}
49+
${magenta ('preact-ts preact' )}
50+
${redBright ('lit-ts lit' )}
51+
${red ('svelte-ts svelte' )}
52+
${blue ('solid-ts solid' )}
53+
${blueBright('qwik-ts qwik' )}`
5354

5455
type ColorFunc = (str: string | number) => string
5556
type Framework = {
@@ -122,6 +123,11 @@ const FRAMEWORKS: Framework[] = [
122123
display: 'TypeScript',
123124
color: blue,
124125
},
126+
{
127+
name: 'react-compiler-ts',
128+
display: 'TypeScript + React Compiler',
129+
color: blue,
130+
},
125131
{
126132
name: 'react-swc-ts',
127133
display: 'TypeScript + SWC',
@@ -132,6 +138,11 @@ const FRAMEWORKS: Framework[] = [
132138
display: 'JavaScript',
133139
color: yellow,
134140
},
141+
{
142+
name: 'react-compiler',
143+
display: 'JavaScript + React Compiler',
144+
color: yellow,
145+
},
135146
{
136147
name: 'react-swc',
137148
display: 'JavaScript + SWC',
@@ -479,6 +490,11 @@ async function init() {
479490
isReactSwc = true
480491
template = template.replace('-swc', '')
481492
}
493+
let isReactCompiler = false
494+
if (template.includes('react-compiler')) {
495+
isReactCompiler = true
496+
template = template.replace('-compiler', '')
497+
}
482498

483499
const pkgManager = pkgInfo ? pkgInfo.name : 'npm'
484500

@@ -531,6 +547,8 @@ async function init() {
531547

532548
if (isReactSwc) {
533549
setupReactSwc(root, template.endsWith('-ts'))
550+
} else if (isReactCompiler) {
551+
setupReactCompiler(root, template.endsWith('-ts'))
534552
}
535553

536554
let doneMessage = ''
@@ -639,6 +657,62 @@ function setupReactSwc(root: string, isTs: boolean) {
639657
return content.replace('@vitejs/plugin-react', '@vitejs/plugin-react-swc')
640658
},
641659
)
660+
updateReactCompilerReadme(
661+
root,
662+
'The React Compiler is currently not compatible with SWC. See [this issue](https://github.com/vitejs/vite-plugin-react/issues/428) for tracking the progress.',
663+
)
664+
}
665+
666+
function setupReactCompiler(root: string, isTs: boolean) {
667+
// renovate: datasource=npm depName=babel-plugin-react-compiler
668+
const reactCompilerPluginVersion = '19.1.0-rc.3'
669+
670+
editFile(path.resolve(root, 'package.json'), (content) => {
671+
const asObject = JSON.parse(content)
672+
const devDepsEntries = Object.entries(asObject.devDependencies)
673+
devDepsEntries.push([
674+
'babel-plugin-react-compiler',
675+
`^${reactCompilerPluginVersion}`,
676+
])
677+
devDepsEntries.sort()
678+
asObject.devDependencies = Object.fromEntries(devDepsEntries)
679+
return JSON.stringify(asObject, null, 2) + '\n'
680+
})
681+
editFile(
682+
path.resolve(root, `vite.config.${isTs ? 'ts' : 'js'}`),
683+
(content) => {
684+
return content.replace(
685+
' plugins: [react()],',
686+
` plugins: [
687+
react({
688+
babel: {
689+
plugins: [['babel-plugin-react-compiler']],
690+
},
691+
}),
692+
],`,
693+
)
694+
},
695+
)
696+
updateReactCompilerReadme(
697+
root,
698+
'The React Compiler is enabled on this template. See [this documentation](https://react.dev/learn/react-compiler) for more information.',
699+
)
700+
}
701+
702+
function updateReactCompilerReadme(root: string, newBody: string) {
703+
editFile(path.resolve(root, `README.md`), (content) => {
704+
const h2Start = content.indexOf('## React Compiler')
705+
const bodyStart = content.indexOf('\n\n', h2Start)
706+
const comilerSectionEnd = content.indexOf('\n## ', bodyStart)
707+
if (h2Start === -1 || bodyStart === -1 || comilerSectionEnd === -1) {
708+
console.warn('Could not update compiler section in README.md')
709+
return content
710+
}
711+
return content.replace(
712+
content.slice(bodyStart + 2, comilerSectionEnd - 1),
713+
newBody,
714+
)
715+
})
642716
}
643717

644718
function editFile(file: string, callback: (content: string) => string) {

packages/create-vite/template-react-ts/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ Currently, two official plugins are available:
77
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
88
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
99

10+
## React Compiler
11+
12+
The React Compiler is not enabled on this template. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
13+
1014
## Expanding the ESLint configuration
1115

1216
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:

packages/create-vite/template-react/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ Currently, two official plugins are available:
77
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
88
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
99

10+
## React Compiler
11+
12+
The React Compiler is not enabled on this template. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
13+
1014
## Expanding the ESLint configuration
1115

1216
If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.

0 commit comments

Comments
 (0)