1- import fs from 'node:fs'
2- import path from 'node:path'
31import { expect , test } from '@playwright/test'
42import { setupInlineFixture , useFixture } from './fixture'
53import { waitForHydration } from './helper'
64import { defineStarterTest } from './starter'
75
8- // When `build.cssCodeSplit: false`, Vite emits a single consolidated CSS
9- // bundle asset and no `importedCss` metadata on chunks. The rsc plugin must
10- // still copy the rsc environment's CSS asset into the client output and
11- // reference it from server-component resources, otherwise RSC-only CSS
12- // (e.g. from a server component module) goes missing from the client build.
13-
146test . describe ( 'cssCodeSplit-false' , ( ) => {
157 const root = 'examples/e2e/temp/cssCodeSplit-false'
168
@@ -19,28 +11,20 @@ test.describe('cssCodeSplit-false', () => {
1911 src : 'examples/starter' ,
2012 dest : root ,
2113 files : {
14+ 'vite.config.base.ts' : { cp : 'vite.config.ts' } ,
2215 'vite.config.ts' : /* js */ `
23- import rsc from '@vitejs/plugin-rsc'
24- import react from '@vitejs/plugin-react'
25- import { defineConfig } from 'vite'
16+ import { defineConfig, mergeConfig } from 'vite'
17+ import baseConfig from './vite.config.base.ts'
2618
27- export default defineConfig({
28- build: { cssCodeSplit: false },
29- plugins: [
30- react(),
31- rsc({
32- entries: {
33- client: './src/framework/entry.browser.tsx',
34- ssr: './src/framework/entry.ssr.tsx',
35- rsc: './src/framework/entry.rsc.tsx',
36- }
37- }),
38- ],
19+ const overrideConfig = defineConfig({
20+ build: {
21+ cssCodeSplit: false,
22+ },
3923 })
24+
25+ export default mergeConfig(baseConfig, overrideConfig)
4026 ` ,
41- // CSS module imported exclusively by a server component module, so its
42- // styles only reach the client via plugin-rsc's server-resources <link>
43- // path.
27+ // test server css module
4428 'src/server-only.module.css' : /* css */ `
4529 .serverOnly {
4630 color: rgb(123, 45, 67);
@@ -49,15 +33,20 @@ test.describe('cssCodeSplit-false', () => {
4933 'src/server-only.tsx' : /* js */ `
5034 import styles from './server-only.module.css'
5135 export function ServerOnly() {
52- return <div data-testid="server-only" className={styles.serverOnly}>rsc-css-only</div>
36+ return (
37+ <button data-testid="server-only" className={styles.serverOnly}>
38+ server-only
39+ </button>
40+ )
5341 }
5442 ` ,
5543 'src/root.tsx' : {
5644 edit : ( s ) =>
5745 s
5846 . replace (
5947 `import { ClientCounter } from './client.tsx'` ,
60- `import { ClientCounter } from './client.tsx'\nimport { ServerOnly } from './server-only.tsx'` ,
48+ `import { ClientCounter } from './client.tsx';
49+ import { ServerOnly } from './server-only.tsx'` ,
6150 )
6251 . replace ( `<ClientCounter />` , `<ClientCounter /><ServerOnly />` ) ,
6352 } ,
@@ -69,19 +58,8 @@ test.describe('cssCodeSplit-false', () => {
6958 const f = useFixture ( { root, mode : 'build' } )
7059 defineStarterTest ( f )
7160
72- test ( 'rsc-only css is present in the client output' , ( ) => {
73- const dir = path . join ( f . root , 'dist/client/assets' )
74- const cssFiles = fs . readdirSync ( dir ) . filter ( ( n ) => n . endsWith ( '.css' ) )
75- const combined = cssFiles
76- . map ( ( n ) => fs . readFileSync ( path . join ( dir , n ) , 'utf-8' ) )
77- . join ( '\n' )
78- // minifier may hex-encode; accept either form
79- expect ( combined ) . toMatch ( / r g b \( 1 2 3 , \s * 4 5 , \s * 6 7 \) | # 7 b 2 d 4 3 / i)
80- } )
81-
82- test ( 'rsc-only css is applied at runtime' , async ( { page } ) => {
61+ test ( 'server css module' , async ( { page } ) => {
8362 await page . goto ( f . url ( ) )
84- await waitForHydration ( page )
8563 await expect ( page . getByTestId ( 'server-only' ) ) . toHaveCSS (
8664 'color' ,
8765 'rgb(123, 45, 67)' ,
0 commit comments