diff --git a/packages/plugin-rsc/e2e/basic.test.ts b/packages/plugin-rsc/e2e/basic.test.ts index cc6cadd06..763cd379a 100644 --- a/packages/plugin-rsc/e2e/basic.test.ts +++ b/packages/plugin-rsc/e2e/basic.test.ts @@ -46,65 +46,6 @@ test.describe('build-default', () => { defineTest(f) }) -test.describe('dev-base', () => { - const f = useFixture({ - root: 'examples/basic', - mode: 'dev', - cliOptions: { - env: { - TEST_BASE: 'true', - }, - }, - }) - defineTest(f) -}) - -test.describe('build-base', () => { - const f = useFixture({ - root: 'examples/basic', - mode: 'build', - cliOptions: { - env: { - TEST_BASE: 'true', - }, - }, - }) - defineTest(f) -}) - -test.describe('dev-react-compiler', () => { - const f = useFixture({ - root: 'examples/basic', - mode: 'dev', - cliOptions: { - env: { - TEST_REACT_COMPILER: 'true', - }, - }, - }) - defineTest(f) - - test('verify react compiler', async ({ page }) => { - await page.goto(f.url()) - await waitForHydration(page) - const res = await page.request.get(f.url('src/routes/client.tsx')) - expect(await res.text()).toContain('react.memo_cache_sentinel') - }) -}) - -test.describe('build-react-compiler', () => { - const f = useFixture({ - root: 'examples/basic', - mode: 'build', - cliOptions: { - env: { - TEST_REACT_COMPILER: 'true', - }, - }, - }) - defineTest(f) -}) - test.describe(() => { // disabled by default if (process.env.TEST_ISOLATED !== 'true') return diff --git a/packages/plugin-rsc/e2e/fixture.ts b/packages/plugin-rsc/e2e/fixture.ts index b9cf2f070..0f3e2c169 100644 --- a/packages/plugin-rsc/e2e/fixture.ts +++ b/packages/plugin-rsc/e2e/fixture.ts @@ -192,3 +192,37 @@ function editFileJson(filepath: string, edit: (s: string) => string) { ), ) } + +// inspired by +// https://github.com/remix-run/react-router/blob/433872f6ab098eaf946cc6c9cf80abf137420ad2/integration/helpers/vite.ts#L239 +// for syntax highlighting of /* js */, use this extension +// https://github.com/mjbvz/vscode-comment-tagged-templates +export async function setupInlineFixture(options: { + src: string + dest: string + files?: Record +}) { + fs.rmSync(options.dest, { recursive: true, force: true }) + fs.mkdirSync(options.dest, { recursive: true }) + + // copy src + fs.cpSync(options.src, options.dest, { + recursive: true, + filter: (src) => !src.includes('node_modules') && !src.includes('dist'), + }) + + // write additional files + if (options.files) { + for (const [filename, contents] of Object.entries(options.files)) { + let filepath = path.join(options.dest, filename) + fs.mkdirSync(path.dirname(filepath), { recursive: true }) + // strip indent + const indent = contents.match(/^\s*/)?.[0] ?? '' + const strippedContents = contents + .split('\n') + .map((line) => line.replace(new RegExp(`^${indent}`), '')) + .join('\n') + fs.writeFileSync(filepath, strippedContents) + } + } +} diff --git a/packages/plugin-rsc/e2e/starter.test.ts b/packages/plugin-rsc/e2e/starter.test.ts index 1bee50b70..cccdd7b1a 100644 --- a/packages/plugin-rsc/e2e/starter.test.ts +++ b/packages/plugin-rsc/e2e/starter.test.ts @@ -1,5 +1,5 @@ import { expect, test } from '@playwright/test' -import { type Fixture, useFixture } from './fixture' +import { setupInlineFixture, type Fixture, useFixture } from './fixture' import { expectNoReload, testNoJs, @@ -42,6 +42,107 @@ test.describe('build-no-ssr', () => { }) }) +test.describe(() => { + const root = 'examples/e2e/temp/react-compiler' + + test.beforeAll(async () => { + await setupInlineFixture({ + src: 'examples/starter', + dest: root, + files: { + 'vite.config.ts': /* js */ ` + import rsc from '@vitejs/plugin-rsc' + import react from '@vitejs/plugin-react' + import { defineConfig } from 'vite' + + export default defineConfig({ + plugins: [ + react({ + babel: { plugins: ['babel-plugin-react-compiler'] }, + }).map((p) => ({ + ...p, + applyToEnvironment: (e) => e.name === 'client', + })), + rsc({ + entries: { + client: './src/framework/entry.browser.tsx', + ssr: './src/framework/entry.ssr.tsx', + rsc: './src/framework/entry.rsc.tsx', + } + }), + ], + }) + `, + }, + }) + }) + + test.describe('dev-react-compiler', () => { + const f = useFixture({ root, mode: 'dev' }) + defineTest(f) + + test('verify react compiler', async ({ page }) => { + await page.goto(f.url()) + await waitForHydration_(page) + const res = await page.request.get(f.url('src/client.tsx')) + expect(await res.text()).toContain('react.memo_cache_sentinel') + }) + }) + + test.describe('build-react-compiler', () => { + const f = useFixture({ root, mode: 'build' }) + defineTest(f) + }) +}) + +test.describe(() => { + const root = 'examples/e2e/temp/base' + + test.beforeAll(async () => { + await setupInlineFixture({ + src: 'examples/starter', + dest: root, + files: { + 'vite.config.ts': /* js */ ` + import rsc from '@vitejs/plugin-rsc' + import react from '@vitejs/plugin-react' + import { defineConfig } from 'vite' + + export default defineConfig({ + base: '/custom-base/', + plugins: [ + react(), + rsc({ + entries: { + client: './src/framework/entry.browser.tsx', + ssr: './src/framework/entry.ssr.tsx', + rsc: './src/framework/entry.rsc.tsx', + } + }), + ], + }) + `, + }, + }) + }) + + test.describe('dev-base', () => { + const f = useFixture({ root, mode: 'dev' }) + defineTest({ + ...f, + url: (url) => new URL(url ?? './', f.url('./custom-base/')).href, + }) + }) + + test.describe('build-base', () => { + const f = useFixture({ root, mode: 'build' }) + defineTest({ + ...f, + url: (url) => new URL(url ?? './', f.url('./custom-base/')).href, + }) + }) +}) + function defineTest(f: Fixture, variant?: 'no-ssr') { const waitForHydration: typeof waitForHydration_ = (page) => waitForHydration_(page, variant === 'no-ssr' ? '#root' : 'body') diff --git a/packages/plugin-rsc/examples/basic/package.json b/packages/plugin-rsc/examples/basic/package.json index fc11d417a..bed815b99 100644 --- a/packages/plugin-rsc/examples/basic/package.json +++ b/packages/plugin-rsc/examples/basic/package.json @@ -25,7 +25,6 @@ "@vitejs/test-dep-client-in-server2": "file:./test-dep/client-in-server2", "@vitejs/test-dep-server-in-client": "file:./test-dep/server-in-client", "@vitejs/test-dep-server-in-server": "file:./test-dep/server-in-server", - "babel-plugin-react-compiler": "19.1.0-rc.2", "tailwindcss": "^4.1.11", "vite": "^7.0.4", "vite-plugin-inspect": "^11.3.0", diff --git a/packages/plugin-rsc/examples/basic/vite.config.ts b/packages/plugin-rsc/examples/basic/vite.config.ts index 38061c0f1..97d0f30b8 100644 --- a/packages/plugin-rsc/examples/basic/vite.config.ts +++ b/packages/plugin-rsc/examples/basic/vite.config.ts @@ -7,18 +7,10 @@ import inspect from 'vite-plugin-inspect' import path from 'node:path' export default defineConfig({ - base: process.env.TEST_BASE ? '/custom-base/' : undefined, clearScreen: false, plugins: [ tailwindcss(), - process.env.TEST_REACT_COMPILER - ? react({ - babel: { plugins: ['babel-plugin-react-compiler'] }, - }).map((p) => ({ - ...p, - applyToEnvironment: (e) => e.name === 'client', - })) - : react(), + react(), vitePluginUseCache(), rsc({ entries: { diff --git a/packages/plugin-rsc/examples/e2e/package.json b/packages/plugin-rsc/examples/e2e/package.json new file mode 100644 index 000000000..314068f26 --- /dev/null +++ b/packages/plugin-rsc/examples/e2e/package.json @@ -0,0 +1,10 @@ +{ + "name": "@vitejs/plugin-rsc-examples-e2e", + "private": true, + "type": "module", + "devDependencies": { + "@vitejs/plugin-rsc": "latest", + "@vitejs/plugin-react": "latest", + "babel-plugin-react-compiler": "19.1.0-rc.2" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 42641f74b..74e6d51d0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -542,9 +542,6 @@ importers: '@vitejs/test-dep-server-in-server': specifier: file:./test-dep/server-in-server version: file:packages/plugin-rsc/examples/basic/test-dep/server-in-server(react@19.1.0) - babel-plugin-react-compiler: - specifier: 19.1.0-rc.2 - version: 19.1.0-rc.2 tailwindcss: specifier: ^4.1.11 version: 4.1.11 @@ -558,6 +555,18 @@ importers: specifier: ^4.24.3 version: 4.24.3 + packages/plugin-rsc/examples/e2e: + devDependencies: + '@vitejs/plugin-react': + specifier: latest + version: link:../../../plugin-react + '@vitejs/plugin-rsc': + specifier: latest + version: link:../.. + babel-plugin-react-compiler: + specifier: 19.1.0-rc.2 + version: 19.1.0-rc.2 + packages/plugin-rsc/examples/no-ssr: dependencies: '@vitejs/plugin-rsc': @@ -7741,7 +7750,7 @@ snapshots: babel-plugin-react-compiler@19.1.0-rc.2: dependencies: - '@babel/types': 7.27.7 + '@babel/types': 7.28.0 bail@2.0.2: {}