@@ -34,6 +34,14 @@ const fixtures = [
3434 templateDisplayName : string ;
3535} > ;
3636
37+ type RouteBasePath = "css" | "rsc-server-first-css" ;
38+ const getRouteBasePaths = ( templateName : TemplateName ) => {
39+ if ( templateName . includes ( "rsc" ) ) {
40+ return [ "css" , "rsc-server-first-css" ] as const satisfies RouteBasePath [ ] ;
41+ }
42+ return [ "css" ] as const satisfies RouteBasePath [ ] ;
43+ } ;
44+
3745const files = ( { templateName } : { templateName : TemplateName } ) => ( {
3846 "postcss.config.js" : js `
3947 export default ({
@@ -75,6 +83,12 @@ const files = ({ templateName }: { templateName: TemplateName }) => ({
7583 );
7684 });
7785 ` ,
86+ "app/entry.client.css" : css `
87+ .entry-client {
88+ background: pink;
89+ padding: ${ PADDING } ;
90+ }
91+ ` ,
7892 }
7993 : { } ) ,
8094 "app/root.tsx" : js `
@@ -95,105 +109,72 @@ const files = ({ templateName }: { templateName: TemplateName }) => ({
95109 );
96110 }
97111 ` ,
98- "app/entry.client.css" : css `
99- .entry-client {
100- background: pink;
101- padding: ${ PADDING } ;
102- }
103- ` ,
104- "app/styles-bundled.css" : css `
105- .index_bundled {
106- background: papayawhip;
107- padding: ${ PADDING } ;
108- }
109- ` ,
110- "app/styles-postcss-linked.css" : css `
111- .index_postcss_linked {
112- background: salmon;
113- padding: PADDING_INJECTED_VIA_POSTCSS;
114- }
115- ` ,
116- "app/styles.module.css" : css `
117- .index {
118- background: peachpuff;
119- padding: ${ PADDING } ;
120- }
121- ` ,
122- "app/styles-vanilla-global.css.ts" : js `
123- import { createVar, globalStyle } from "@vanilla-extract/css";
124-
125- globalStyle(".index_vanilla_global", {
126- background: "lightgreen",
127- padding: "${ PADDING } ",
128- });
129- ` ,
130- "app/styles-vanilla-local.css.ts" : js `
131- import { style } from "@vanilla-extract/css";
132-
133- export const index = style({
134- background: "lightblue",
135- padding: "${ PADDING } ",
136- });
137- ` ,
138- "app/routes/_index.tsx" : js `
139- import "../styles-bundled.css";
140- import postcssLinkedStyles from "../styles-postcss-linked.css?url";
141- import cssModulesStyles from "../styles.module.css";
142- import "../styles-vanilla-global.css";
143- import * as stylesVanillaLocal from "../styles-vanilla-local.css";
144-
145- // Workaround for "Generated an empty chunk" warnings in RSC Framework Mode
146- export function loader() {
147- return null;
148- }
112+ ...Object . assign (
113+ { } ,
114+ ...getRouteBasePaths ( templateName ) . map ( ( routeBasePath ) => {
115+ const isServerFirstRoute = routeBasePath === "rsc-server-first-css" ;
116+ const exportName = isServerFirstRoute ? "ServerComponent" : "default" ;
117+
118+ return {
119+ [ `app/routes/${ routeBasePath } /styles-bundled.css` ] : css `
120+ .${ routeBasePath } -bundled {
121+ background: papayawhip;
122+ padding: ${ PADDING } ;
123+ }
124+ ` ,
125+ [ `app/routes/${ routeBasePath } /styles-postcss-linked.css` ] : css `
126+ .${ routeBasePath } -postcss-linked {
127+ background: salmon;
128+ padding: PADDING_INJECTED_VIA_POSTCSS;
129+ }
130+ ` ,
131+ [ `app/routes/${ routeBasePath } /styles.module.css` ] : css `
132+ .index {
133+ background: peachpuff;
134+ padding: ${ PADDING } ;
135+ }
136+ ` ,
137+ [ `app/routes/${ routeBasePath } /styles-vanilla-global.css.ts` ] : js `
138+ import { createVar, globalStyle } from "@vanilla-extract/css";
149139
150- export function links() {
151- return [{ rel: "stylesheet", href: postcssLinkedStyles }];
152- }
140+ globalStyle(".${ routeBasePath } -vanilla-global", {
141+ background: "lightgreen",
142+ padding: "${ PADDING } ",
143+ });
144+ ` ,
145+ [ `app/routes/${ routeBasePath } /styles-vanilla-local.css.ts` ] : js `
146+ import { style } from "@vanilla-extract/css";
153147
154- export default function IndexRoute() {
155- return (
156- <>
157- <input />
158- <div id="entry-client" className="entry-client">
159- <div id="css-modules" className={cssModulesStyles.index}>
160- <div id="css-postcss-linked" className="index_postcss_linked">
161- <div id="css-bundled" className="index_bundled">
162- <div id="css-vanilla-global" className="index_vanilla_global">
163- <div id="css-vanilla-local" className={stylesVanillaLocal.index}>
164- <h2>CSS test</h2>
165- </div>
166- </div>
167- </div>
168- </div>
169- </div>
170- </div>
171- </>
172- );
173- }
174- ` ,
175- ...( templateName . includes ( "rsc" )
176- ? {
177- "app/routes/server-component-route.tsx" : js `
178- import "../styles-bundled.css";
179- import postcssLinkedStyles from "../styles-postcss-linked.css?url";
180- import cssModulesStyles from "../styles.module.css";
181- import "../styles-vanilla-global.css";
182- import * as stylesVanillaLocal from "../styles-vanilla-local.css";
148+ export const index = style({
149+ background: "lightblue",
150+ padding: "${ PADDING } ",
151+ });
152+ ` ,
153+ [ `app/routes/${ routeBasePath } /route.tsx` ] : js `
154+ import "./styles-bundled.css";
155+ import postcssLinkedStyles from "./styles-postcss-linked.css?url";
156+ import cssModulesStyles from "./styles.module.css";
157+ import "./styles-vanilla-global.css";
158+ import * as stylesVanillaLocal from "./styles-vanilla-local.css";
159+
160+ // Workaround for "Generated an empty chunk" warnings in RSC Framework Mode
161+ export function loader() {
162+ return null;
163+ }
183164
184165 export function links() {
185166 return [{ rel: "stylesheet", href: postcssLinkedStyles }];
186167 }
187168
188- export function ServerComponent () {
169+ function TestRoute () {
189170 return (
190171 <>
191172 <input />
192173 <div id="entry-client" className="entry-client">
193174 <div id="css-modules" className={cssModulesStyles.index}>
194- <div id="css-postcss-linked" className="index_postcss_linked ">
195- <div id="css-bundled" className="index_bundled ">
196- <div id="css-vanilla-global" className="index_vanilla_global ">
175+ <div id="css-postcss-linked" className="${ routeBasePath } -postcss-linked ">
176+ <div id="css-bundled" className="${ routeBasePath } -bundled ">
177+ <div id="css-vanilla-global" className="${ routeBasePath } -vanilla-global ">
197178 <div id="css-vanilla-local" className={stylesVanillaLocal.index}>
198179 <h2>CSS test</h2>
199180 </div>
@@ -205,9 +186,12 @@ const files = ({ templateName }: { templateName: TemplateName }) => ({
205186 </>
206187 );
207188 }
189+
190+ export ${ exportName === "default" ? "default" : `const ${ exportName } =` } TestRoute;
208191 ` ,
209- }
210- : { } ) ,
192+ } ;
193+ } ) ,
194+ ) ,
211195} ) ;
212196
213197test . describe ( "Vite CSS" , ( ) => {
@@ -497,16 +481,11 @@ async function pageLoadWorkflow({
497481 base ?: string ;
498482 templateName : TemplateName ;
499483} ) {
500- let pageErrors : Error [ ] = [ ] ;
501- page . on ( "pageerror" , ( error ) => pageErrors . push ( error ) ) ;
484+ for ( const routeBase of getRouteBasePaths ( templateName ) ) {
485+ let pageErrors : Error [ ] = [ ] ;
486+ page . on ( "pageerror" , ( error ) => pageErrors . push ( error ) ) ;
502487
503- const paths = [ "" ] ;
504- if ( templateName . includes ( "rsc" ) ) {
505- paths . push ( "server-component-route" ) ;
506- }
507-
508- for ( const path of paths ) {
509- await page . goto ( `http://localhost:${ port } ${ base ?? "/" } ${ path } ` , {
488+ await page . goto ( `http://localhost:${ port } ${ base ?? "/" } ${ routeBase } ` , {
510489 waitUntil : "networkidle" ,
511490 } ) ;
512491
@@ -543,54 +522,64 @@ async function hmrWorkflow({
543522 return ;
544523 }
545524
546- let pageErrors : Error [ ] = [ ] ;
547- page . on ( "pageerror" , ( error ) => pageErrors . push ( error ) ) ;
525+ for ( const routeBase of getRouteBasePaths ( templateName ) ) {
526+ let pageErrors : Error [ ] = [ ] ;
527+ page . on ( "pageerror" , ( error ) => pageErrors . push ( error ) ) ;
548528
549- await page . goto ( `http://localhost:${ port } ${ base ?? "/" } ` , {
550- waitUntil : "networkidle" ,
551- } ) ;
529+ await page . goto ( `http://localhost:${ port } ${ base ?? "/" } ${ routeBase } ` , {
530+ waitUntil : "networkidle" ,
531+ } ) ;
532+
533+ let input = page . locator ( "input" ) ;
534+ await expect ( input ) . toBeVisible ( ) ;
535+ await input . type ( "stateful" ) ;
536+ await expect ( input ) . toHaveValue ( "stateful" ) ;
537+
538+ let edit = createEditor ( cwd ) ;
539+ let modifyCss = ( contents : string ) =>
540+ contents
541+ . replace ( PADDING , NEW_PADDING )
542+ . replace (
543+ "PADDING_INJECTED_VIA_POSTCSS" ,
544+ "NEW_PADDING_INJECTED_VIA_POSTCSS" ,
545+ ) ;
552546
553- let input = page . locator ( "input" ) ;
554- await expect ( input ) . toBeVisible ( ) ;
555- await input . type ( "stateful" ) ;
556- await expect ( input ) . toHaveValue ( "stateful" ) ;
557-
558- let edit = createEditor ( cwd ) ;
559- let modifyCss = ( contents : string ) =>
560- contents
561- . replace ( PADDING , NEW_PADDING )
562- . replace (
563- "PADDING_INJECTED_VIA_POSTCSS" ,
564- "NEW_PADDING_INJECTED_VIA_POSTCSS" ,
547+ await Promise . all ( [
548+ edit ( `app/routes/${ routeBase } /styles-bundled.css` , modifyCss ) ,
549+ edit ( `app/routes/${ routeBase } /styles.module.css` , modifyCss ) ,
550+ edit ( `app/routes/${ routeBase } /styles-vanilla-global.css.ts` , modifyCss ) ,
551+ edit ( `app/routes/${ routeBase } /styles-vanilla-local.css.ts` , modifyCss ) ,
552+ edit ( `app/routes/${ routeBase } /styles-postcss-linked.css` , modifyCss ) ,
553+ ] ) ;
554+
555+ await Promise . all (
556+ [
557+ "#css-bundled" ,
558+ "#css-postcss-linked" ,
559+ "#css-modules" ,
560+ "#css-vanilla-global" ,
561+ "#css-vanilla-local" ,
562+ ] . map (
563+ async ( selector ) =>
564+ await expect ( page . locator ( selector ) ) . toHaveCSS (
565+ "padding" ,
566+ NEW_PADDING ,
567+ ) ,
568+ ) ,
569+ ) ;
570+
571+ // Ensure CSS updates were handled by HMR
572+ await expect ( input ) . toHaveValue ( "stateful" ) ;
573+
574+ if ( routeBase === "css" ) {
575+ // The following change triggers a full page reload, so we check it after all the checks for HMR state preservation
576+ await edit ( "app/entry.client.css" , modifyCss ) ;
577+ await expect ( page . locator ( "#entry-client" ) ) . toHaveCSS (
578+ "padding" ,
579+ NEW_PADDING ,
565580 ) ;
581+ }
566582
567- await Promise . all ( [
568- edit ( "app/styles-bundled.css" , modifyCss ) ,
569- edit ( "app/styles.module.css" , modifyCss ) ,
570- edit ( "app/styles-vanilla-global.css.ts" , modifyCss ) ,
571- edit ( "app/styles-vanilla-local.css.ts" , modifyCss ) ,
572- edit ( "app/styles-postcss-linked.css" , modifyCss ) ,
573- ] ) ;
574-
575- await Promise . all (
576- [
577- "#css-bundled" ,
578- "#css-postcss-linked" ,
579- "#css-modules" ,
580- "#css-vanilla-global" ,
581- "#css-vanilla-local" ,
582- ] . map (
583- async ( selector ) =>
584- await expect ( page . locator ( selector ) ) . toHaveCSS ( "padding" , NEW_PADDING ) ,
585- ) ,
586- ) ;
587-
588- // Ensure CSS updates were handled by HMR
589- await expect ( input ) . toHaveValue ( "stateful" ) ;
590-
591- // The following change triggers a full page reload, so we check it after all the checks for HMR state preservation
592- await edit ( "app/entry.client.css" , modifyCss ) ;
593- await expect ( page . locator ( "#entry-client" ) ) . toHaveCSS ( "padding" , NEW_PADDING ) ;
594-
595- expect ( pageErrors ) . toEqual ( [ ] ) ;
583+ expect ( pageErrors ) . toEqual ( [ ] ) ;
584+ }
596585}
0 commit comments