Skip to content

Commit e2f90ad

Browse files
committed
refactor(rsc): use inline style for server css during dev
1 parent 54e9a9d commit e2f90ad

File tree

1 file changed

+117
-8
lines changed

1 file changed

+117
-8
lines changed

packages/plugin-rsc/src/plugin.ts

Lines changed: 117 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
cleanUrl,
3737
directRequestRE,
3838
evalValue,
39+
injectQuery,
3940
normalizeViteImportAnalysisUrl,
4041
prepareError,
4142
} from './plugins/vite-utils'
@@ -1923,6 +1924,55 @@ function vitePluginRscCss(
19231924
return { ids: [...cssIds], hrefs, visitedFiles: [...visitedFiles] }
19241925
}
19251926

1927+
async function collectCss2(
1928+
environment: DevEnvironment,
1929+
clientEnvironment: DevEnvironment,
1930+
entryId: string,
1931+
) {
1932+
const visited = new Set<string>()
1933+
const cssIds = new Set<string>()
1934+
const visitedFiles = new Set<string>()
1935+
1936+
function recurse(id: string) {
1937+
if (visited.has(id)) {
1938+
return
1939+
}
1940+
visited.add(id)
1941+
const mod = environment.moduleGraph.getModuleById(id)
1942+
if (mod?.file) {
1943+
visitedFiles.add(mod.file)
1944+
}
1945+
for (const next of mod?.importedModules ?? []) {
1946+
if (next.id) {
1947+
if (isCSSRequest(next.id)) {
1948+
if (hasSpecialCssQuery(next.id)) {
1949+
continue
1950+
}
1951+
cssIds.add(next.id)
1952+
} else {
1953+
recurse(next.id)
1954+
}
1955+
}
1956+
}
1957+
}
1958+
1959+
recurse(entryId)
1960+
1961+
const styles: Record<string, string> = {}
1962+
for (const id of cssIds) {
1963+
try {
1964+
const result = await clientEnvironment.transformRequest(
1965+
injectQuery(id, 'direct'),
1966+
)
1967+
styles[id] = result?.code ?? ''
1968+
} catch (e) {
1969+
console.error(`[collectCss failed '${id}']`, e)
1970+
}
1971+
}
1972+
1973+
return { ids: [...cssIds], styles, visitedFiles: [...visitedFiles] }
1974+
}
1975+
19261976
function getRscCssTransformFilter({
19271977
id,
19281978
code,
@@ -2122,23 +2172,33 @@ function vitePluginRscCss(
21222172
}
21232173
}
21242174
},
2125-
load(id) {
2175+
async load(id) {
21262176
const { server } = manager
21272177
const parsed = parseCssVirtual(id)
21282178
if (parsed?.type === 'rsc') {
21292179
assert(this.environment.name === 'rsc')
21302180
const importer = parsed.id
21312181
if (this.environment.mode === 'dev') {
2132-
const result = collectCss(server.environments.rsc!, importer)
2182+
const result = await collectCss2(
2183+
server.environments.rsc!,
2184+
server.environments.client,
2185+
importer,
2186+
)
21332187
for (const file of [importer, ...result.visitedFiles]) {
21342188
this.addWatchFile(file)
21352189
}
2136-
const cssHrefs = result.hrefs.map((href) => href.slice(1))
2137-
const deps = assetsURLOfDeps({ css: cssHrefs, js: [] }, manager)
2138-
return generateResourcesCode(
2139-
serializeValueWithRuntime(deps),
2140-
manager,
2141-
)
2190+
return generateResourcesCode2(result.styles, manager)
2191+
2192+
// const result = collectCss(server.environments.rsc!, importer)
2193+
// for (const file of [importer, ...result.visitedFiles]) {
2194+
// this.addWatchFile(file)
2195+
// }
2196+
// const cssHrefs = result.hrefs.map((href) => href.slice(1))
2197+
// const deps = assetsURLOfDeps({ css: cssHrefs, js: [] }, manager)
2198+
// return generateResourcesCode(
2199+
// serializeValueWithRuntime(deps),
2200+
// manager,
2201+
// )
21422202
} else {
21432203
const key = manager.toRelativeId(importer)
21442204
manager.serverResourcesMetaMap[importer] = { key }
@@ -2188,6 +2248,55 @@ export default function RemoveDuplicateServerCss() {
21882248
]
21892249
}
21902250

2251+
function generateResourcesCode2(
2252+
styles: Record<string, string>,
2253+
manager: RscPluginManager,
2254+
) {
2255+
const ResourcesFn = (
2256+
React: typeof import('react'),
2257+
styles: Record<string, string>,
2258+
RemoveDuplicateServerCss?: React.FC,
2259+
) => {
2260+
return function Resources() {
2261+
return React.createElement(React.Fragment, null, [
2262+
...Object.entries(styles).map(([id, content]) =>
2263+
React.createElement(
2264+
'style',
2265+
{
2266+
key: 'css:' + id,
2267+
rel: 'stylesheet',
2268+
precedence: 'vite-rsc/importer-resources',
2269+
// href: href,
2270+
// 'data-rsc-css-href': href,
2271+
},
2272+
content,
2273+
),
2274+
),
2275+
RemoveDuplicateServerCss &&
2276+
React.createElement(RemoveDuplicateServerCss, {
2277+
key: 'remove-duplicate-css',
2278+
}),
2279+
])
2280+
}
2281+
}
2282+
2283+
return `
2284+
import __vite_rsc_react__ from "react";
2285+
2286+
${
2287+
manager.config.command === 'serve'
2288+
? `import RemoveDuplicateServerCss from "virtual:vite-rsc/remove-duplicate-server-css";`
2289+
: `const RemoveDuplicateServerCss = undefined;`
2290+
}
2291+
2292+
export const Resources = (${ResourcesFn.toString()})(
2293+
__vite_rsc_react__,
2294+
${JSON.stringify(styles)},
2295+
RemoveDuplicateServerCss,
2296+
);
2297+
`
2298+
}
2299+
21912300
function generateResourcesCode(depsCode: string, manager: RscPluginManager) {
21922301
const ResourcesFn = (
21932302
React: typeof import('react'),

0 commit comments

Comments
 (0)