@@ -10,14 +10,16 @@ import {
1010 js ,
1111} from "./helpers/create-fixture.js" ;
1212
13- const ANY_CSS_LINK_SELECTOR = "link[rel='stylesheet'][href*='css-component']" ;
14- // Links with a trailing hash are only ever managed by React Router, not
15- // Vite's dynamic CSS injection logic
16- const ROUTE_CSS_LINK_SELECTOR = `${ ANY_CSS_LINK_SELECTOR } [href$='#']` ;
13+ const CSS_LINK_SELECTOR = "link[rel='stylesheet']" ;
14+ const CSS_COMPONENT_LINK_SELECTOR = `${ CSS_LINK_SELECTOR } [href*='css-component']` ;
15+ // Link hrefs with a trailing hash are only ever managed by React Router, to
16+ // ensure they're forcibly unique from the Vite-injected links
17+ const ANY_FORCIBLY_UNIQUE_CSS_LINK_SELECTOR = `${ CSS_LINK_SELECTOR } [href$='#']` ;
18+ const CSS_COMPONENT_FORCIBLY_UNIQUE_LINK_SELECTOR = `${ CSS_COMPONENT_LINK_SELECTOR } [href$='#']` ;
1719
18- function getCssComponentColor ( page : Page ) {
20+ function getColor ( page : Page , selector : string ) {
1921 return page
20- . locator ( "[data-css-component]" )
22+ . locator ( selector )
2123 . first ( )
2224 . evaluate ( ( el ) => window . getComputedStyle ( el ) . color ) ;
2325}
@@ -29,18 +31,33 @@ test.describe("Vite CSS lazy loading", () => {
2931 test . beforeAll ( async ( ) => {
3032 fixture = await createFixture ( {
3133 files : {
32- "app/components/css-component.module. css" : css `
33- .test {
34+ "app/components/css-component.css" : css `
35+ .css-component {
3436 color: rgb(0, 128, 0);
3537 font-family: sans-serif;
3638 font-weight: bold;
3739 }
3840 ` ,
3941
4042 "app/components/css-component.tsx" : js `
41- import styles from "./css-component.module .css";
43+ import "./css-component.css";
4244 export default function CssComponent() {
43- return <p data-css-component className={styles.test}>This text should be green.</p>;
45+ return <p data-css-component className="css-component">This text should be green.</p>;
46+ }
47+ ` ,
48+
49+ "app/components/static-only-css-component.css" : css `
50+ .static-only-css-component {
51+ color: rgb(128, 128, 0);
52+ font-family: sans-serif;
53+ font-weight: bold;
54+ }
55+ ` ,
56+
57+ "app/components/static-only-css-component.tsx" : js `
58+ import "./static-only-css-component.css";
59+ export default function StaticOnlyCssComponent() {
60+ return <p data-static-only-css-component className="static-only-css-component">This text should be olive.</p>;
4461 }
4562 ` ,
4663
@@ -81,6 +98,9 @@ test.describe("Vite CSS lazy loading", () => {
8198 <li>
8299 <Link to="/siblings/with-lazy-css-component">Siblings / Route with Lazy CSS Component</Link>
83100 </li>
101+ <li>
102+ <Link to="/with-static-only-css-component">Route with Static Only CSS Component</Link>
103+ </li>
84104 </ul>
85105 </nav>
86106 <Outlet />
@@ -162,6 +182,18 @@ test.describe("Vite CSS lazy loading", () => {
162182 );
163183 }
164184 ` ,
185+
186+ "app/routes/_layout.with-static-only-css-component.tsx" : js `
187+ import StaticOnlyCssComponent from "../components/static-only-css-component";
188+ export default function WithStaticOnlyCssComponent() {
189+ return (
190+ <>
191+ <h2 data-route-with-static-only-css-component>Route with Static Only CSS Component</h2>
192+ <StaticOnlyCssComponent />
193+ </>
194+ );
195+ }
196+ ` ,
165197 } ,
166198 } ) ;
167199
@@ -180,22 +212,28 @@ test.describe("Vite CSS lazy loading", () => {
180212 await app . goto ( "/parent-child/with-css-component" ) ;
181213 await page . waitForSelector ( "[data-child-route-with-css-component]" ) ;
182214 expect ( await page . locator ( "[data-css-component]" ) . count ( ) ) . toBe ( 1 ) ;
183- expect ( await page . locator ( ANY_CSS_LINK_SELECTOR ) . count ( ) ) . toBe ( 1 ) ;
184- expect ( await page . locator ( ROUTE_CSS_LINK_SELECTOR ) . count ( ) ) . toBe ( 1 ) ;
185- expect ( await getCssComponentColor ( page ) ) . toBe ( "rgb(0, 128, 0)" ) ;
215+ expect ( await page . locator ( CSS_COMPONENT_LINK_SELECTOR ) . count ( ) ) . toBe ( 1 ) ;
216+ expect (
217+ await page . locator ( CSS_COMPONENT_FORCIBLY_UNIQUE_LINK_SELECTOR ) . count ( ) ,
218+ ) . toBe ( 1 ) ;
219+ expect ( await getColor ( page , "[data-css-component]" ) ) . toBe ( "rgb(0, 128, 0)" ) ;
186220
187221 await page . locator ( "[data-load-lazy-css-component]" ) . click ( ) ;
188222 await page . waitForSelector ( "[data-css-component]" ) ;
189- expect ( await page . locator ( ANY_CSS_LINK_SELECTOR ) . count ( ) ) . toBe ( 2 ) ;
190- expect ( await page . locator ( ROUTE_CSS_LINK_SELECTOR ) . count ( ) ) . toBe ( 1 ) ;
191- expect ( await getCssComponentColor ( page ) ) . toBe ( "rgb(0, 128, 0)" ) ;
223+ expect ( await page . locator ( CSS_COMPONENT_LINK_SELECTOR ) . count ( ) ) . toBe ( 2 ) ;
224+ expect (
225+ await page . locator ( CSS_COMPONENT_FORCIBLY_UNIQUE_LINK_SELECTOR ) . count ( ) ,
226+ ) . toBe ( 1 ) ;
227+ expect ( await getColor ( page , "[data-css-component]" ) ) . toBe ( "rgb(0, 128, 0)" ) ;
192228
193229 await app . clickLink ( "/parent-child/without-css-component" ) ;
194230 await page . waitForSelector ( "[data-child-route-without-css-component]" ) ;
195231 expect ( await page . locator ( "[data-css-component]" ) . count ( ) ) . toBe ( 1 ) ;
196- expect ( await page . locator ( ANY_CSS_LINK_SELECTOR ) . count ( ) ) . toBe ( 1 ) ;
197- expect ( await page . locator ( ROUTE_CSS_LINK_SELECTOR ) . count ( ) ) . toBe ( 0 ) ;
198- expect ( await getCssComponentColor ( page ) ) . toBe ( "rgb(0, 128, 0)" ) ;
232+ expect ( await page . locator ( CSS_COMPONENT_LINK_SELECTOR ) . count ( ) ) . toBe ( 1 ) ;
233+ expect (
234+ await page . locator ( CSS_COMPONENT_FORCIBLY_UNIQUE_LINK_SELECTOR ) . count ( ) ,
235+ ) . toBe ( 0 ) ;
236+ expect ( await getColor ( page , "[data-css-component]" ) ) . toBe ( "rgb(0, 128, 0)" ) ;
199237 } ) ;
200238
201239 test ( "supports CSS lazy loading when navigating to a sibling route if the current route has a static dependency on the same CSS" , async ( {
@@ -206,15 +244,35 @@ test.describe("Vite CSS lazy loading", () => {
206244 await app . goto ( "/siblings/with-css-component" ) ;
207245 await page . waitForSelector ( "[data-sibling-route-with-css-component]" ) ;
208246 expect ( await page . locator ( "[data-css-component]" ) . count ( ) ) . toBe ( 1 ) ;
209- expect ( await page . locator ( ANY_CSS_LINK_SELECTOR ) . count ( ) ) . toBe ( 1 ) ;
210- expect ( await page . locator ( ROUTE_CSS_LINK_SELECTOR ) . count ( ) ) . toBe ( 1 ) ;
211- expect ( await getCssComponentColor ( page ) ) . toBe ( "rgb(0, 128, 0)" ) ;
247+ expect ( await page . locator ( CSS_COMPONENT_LINK_SELECTOR ) . count ( ) ) . toBe ( 1 ) ;
248+ expect (
249+ await page . locator ( CSS_COMPONENT_FORCIBLY_UNIQUE_LINK_SELECTOR ) . count ( ) ,
250+ ) . toBe ( 1 ) ;
251+ expect ( await getColor ( page , "[data-css-component]" ) ) . toBe ( "rgb(0, 128, 0)" ) ;
212252
213253 await app . clickLink ( "/siblings/with-lazy-css-component" ) ;
214254 await page . waitForSelector ( "[data-sibling-route-with-lazy-css-component]" ) ;
215255 expect ( await page . locator ( "[data-css-component]" ) . count ( ) ) . toBe ( 1 ) ;
216- expect ( await page . locator ( ANY_CSS_LINK_SELECTOR ) . count ( ) ) . toBe ( 1 ) ;
217- expect ( await page . locator ( ROUTE_CSS_LINK_SELECTOR ) . count ( ) ) . toBe ( 0 ) ;
218- expect ( await getCssComponentColor ( page ) ) . toBe ( "rgb(0, 128, 0)" ) ;
256+ expect ( await page . locator ( CSS_COMPONENT_LINK_SELECTOR ) . count ( ) ) . toBe ( 1 ) ;
257+ expect (
258+ await page . locator ( CSS_COMPONENT_FORCIBLY_UNIQUE_LINK_SELECTOR ) . count ( ) ,
259+ ) . toBe ( 0 ) ;
260+ expect ( await getColor ( page , "[data-css-component]" ) ) . toBe ( "rgb(0, 128, 0)" ) ;
261+ } ) ;
262+
263+ test ( "does not add a hash to the CSS link if the CSS is only ever statically imported" , async ( {
264+ page,
265+ } ) => {
266+ let app = new PlaywrightFixture ( appFixture , page ) ;
267+
268+ await app . goto ( "/with-static-only-css-component" ) ;
269+ await page . waitForSelector ( "[data-route-with-static-only-css-component]" ) ;
270+ expect ( await page . locator ( CSS_LINK_SELECTOR ) . count ( ) ) . toBe ( 1 ) ;
271+ expect (
272+ await page . locator ( ANY_FORCIBLY_UNIQUE_CSS_LINK_SELECTOR ) . count ( ) ,
273+ ) . toBe ( 0 ) ;
274+ expect ( await getColor ( page , "[data-static-only-css-component]" ) ) . toBe (
275+ "rgb(128, 128, 0)" ,
276+ ) ;
219277 } ) ;
220278} ) ;
0 commit comments