Skip to content

Commit d143cd5

Browse files
feat(plugin-rsc): allow to control whether CSS links use React's precedence attribute (#1064)
Co-authored-by: Hiroshi Ogawa <hi.ogawa.zz@gmail.com>
1 parent 58dfb9d commit d143cd5

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

packages/plugin-rsc/src/plugin.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,13 @@ export type RscPluginOptions = {
258258
/** server chunk which includes a corresponding client reference proxy module */
259259
serverChunk: string
260260
}) => string | undefined
261+
262+
/**
263+
* Controls whether CSS links use React's `precedence` attribute.
264+
* @experimental
265+
* @default true
266+
*/
267+
cssLinkPrecedence?: boolean
261268
}
262269

263270
export type PluginApi = {
@@ -1014,6 +1021,7 @@ export function createRpcClient(params) {
10141021
const manifest: AssetsManifest = {
10151022
bootstrapScriptContent: `import(${serializeValueWithRuntime(entryUrl)})`,
10161023
clientReferenceDeps: {},
1024+
cssLinkPrecedence: rscPluginOptions.cssLinkPrecedence,
10171025
}
10181026
return `export default ${JSON.stringify(manifest, null, 2)}`
10191027
}
@@ -1085,6 +1093,7 @@ export function createRpcClient(params) {
10851093
bootstrapScriptContent,
10861094
clientReferenceDeps,
10871095
serverResources,
1096+
cssLinkPrecedence: rscPluginOptions.cssLinkPrecedence,
10881097
}
10891098
}
10901099
},
@@ -1980,6 +1989,7 @@ export type AssetsManifest = {
19801989
bootstrapScriptContent: string | RuntimeAsset
19811990
clientReferenceDeps: Record<string, AssetDeps>
19821991
serverResources?: Record<string, Pick<AssetDeps, 'css'>>
1992+
cssLinkPrecedence?: boolean
19831993
}
19841994

19851995
export type AssetDeps = {
@@ -1991,6 +2001,7 @@ export type ResolvedAssetsManifest = {
19912001
bootstrapScriptContent: string
19922002
clientReferenceDeps: Record<string, ResolvedAssetDeps>
19932003
serverResources?: Record<string, Pick<ResolvedAssetDeps, 'css'>>
2004+
cssLinkPrecedence?: boolean
19942005
}
19952006

19962007
export type ResolvedAssetDeps = {
@@ -2059,7 +2070,10 @@ function collectAssetDepsInner(
20592070
//
20602071

20612072
function vitePluginRscCss(
2062-
rscCssOptions: Pick<RscPluginOptions, 'rscCssTransform'> = {},
2073+
rscCssOptions: Pick<
2074+
RscPluginOptions,
2075+
'rscCssTransform' | 'cssLinkPrecedence'
2076+
> = {},
20632077
manager: RscPluginManager,
20642078
): Plugin[] {
20652079
function hasSpecialCssQuery(id: string): boolean {
@@ -2319,6 +2333,7 @@ function vitePluginRscCss(
23192333
return generateResourcesCode(
23202334
serializeValueWithRuntime(deps),
23212335
manager,
2336+
{ cssLinkPrecedence: rscCssOptions.cssLinkPrecedence },
23222337
)
23232338
} else {
23242339
const key = manager.toRelativeId(importer)
@@ -2330,6 +2345,7 @@ function vitePluginRscCss(
23302345
key,
23312346
)}]`,
23322347
manager,
2348+
{ cssLinkPrecedence: rscCssOptions.cssLinkPrecedence },
23332349
)}
23342350
`
23352351
}
@@ -2369,19 +2385,25 @@ export default function RemoveDuplicateServerCss() {
23692385
]
23702386
}
23712387

2372-
function generateResourcesCode(depsCode: string, manager: RscPluginManager) {
2388+
function generateResourcesCode(
2389+
depsCode: string,
2390+
manager: RscPluginManager,
2391+
options: { cssLinkPrecedence?: boolean } = {},
2392+
) {
2393+
const usePrecedence = options.cssLinkPrecedence !== false
23732394
const ResourcesFn = (
23742395
React: typeof import('react'),
23752396
deps: ResolvedAssetDeps,
23762397
RemoveDuplicateServerCss?: React.FC,
2398+
precedence?: string,
23772399
) => {
23782400
return function Resources() {
23792401
return React.createElement(React.Fragment, null, [
23802402
...deps.css.map((href: string) =>
23812403
React.createElement('link', {
23822404
key: 'css:' + href,
23832405
rel: 'stylesheet',
2384-
precedence: 'vite-rsc/importer-resources',
2406+
...(precedence ? { precedence } : {}),
23852407
href: href,
23862408
'data-rsc-css-href': href,
23872409
}),
@@ -2407,6 +2429,7 @@ export const Resources = (${ResourcesFn.toString()})(
24072429
__vite_rsc_react__,
24082430
${depsCode},
24092431
RemoveDuplicateServerCss,
2432+
${usePrecedence ? `"vite-rsc/importer-resources"` : `undefined`},
24102433
);
24112434
`
24122435
}

packages/plugin-rsc/src/ssr.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,10 @@ function preloadDeps(deps: ResolvedAssetDeps) {
6767
for (const href of deps.css) {
6868
ReactDOM.preinit(href, {
6969
as: 'style',
70-
precedence: 'vite-rsc/client-reference',
70+
precedence:
71+
assetsManifest.cssLinkPrecedence !== false
72+
? 'vite-rsc/client-reference'
73+
: undefined,
7174
})
7275
}
7376
}

0 commit comments

Comments
 (0)