diff --git a/packages/plugin-rsc/examples/basic/src/routes/style-server/not-detected/server.css b/packages/plugin-rsc/examples/basic/src/routes/style-server/not-detected/server.css new file mode 100644 index 00000000..17d82f3f --- /dev/null +++ b/packages/plugin-rsc/examples/basic/src/routes/style-server/not-detected/server.css @@ -0,0 +1,3 @@ +.test-style-server-not-detected { + color: rgb(255, 165, 0); +} diff --git a/packages/plugin-rsc/examples/basic/src/routes/style-server/not-detected/server.tsx b/packages/plugin-rsc/examples/basic/src/routes/style-server/not-detected/server.tsx new file mode 100644 index 00000000..dc5a2b67 --- /dev/null +++ b/packages/plugin-rsc/examples/basic/src/routes/style-server/not-detected/server.tsx @@ -0,0 +1,9 @@ +import './server.css' + +export function TestStyleServerNotDetected() { + return ( +
+ test-style-server-not-detected +
+ ) +} diff --git a/packages/plugin-rsc/examples/basic/src/routes/style-server/server.tsx b/packages/plugin-rsc/examples/basic/src/routes/style-server/server.tsx index 66166992..b8f3db2a 100644 --- a/packages/plugin-rsc/examples/basic/src/routes/style-server/server.tsx +++ b/packages/plugin-rsc/examples/basic/src/routes/style-server/server.tsx @@ -1,7 +1,9 @@ import './server.css' import styles from './server.module.css' +// import { TestStyleServerNotDetected } from "./not-detected/server"; -export function TestStyleServer() { +export async function TestStyleServer() { + const { TestStyleServerNotDetected } = await import('./not-detected/server') return ( <>
test-style-server
@@ -14,6 +16,7 @@ export function TestStyleServer() { precedence="test-style-server-manual" />
test-style-server-manual
+ ) } diff --git a/packages/plugin-rsc/src/plugin.ts b/packages/plugin-rsc/src/plugin.ts index 91b7e811..d4116644 100644 --- a/packages/plugin-rsc/src/plugin.ts +++ b/packages/plugin-rsc/src/plugin.ts @@ -696,6 +696,7 @@ export default function vitePluginRsc( typeof rscBuildOptions.manifest === 'string' ? rscBuildOptions.manifest : rscBuildOptions.manifest && '.vite/manifest.json' + const rscCssFiles: string[] = [] for (const asset of Object.values(rscBundle)) { if (asset.fileName === rscViteManifest) continue if (asset.type === 'asset' && filterAssets(asset.fileName)) { @@ -704,16 +705,39 @@ export default function vitePluginRsc( fileName: asset.fileName, source: asset.source, }) + if (asset.fileName.endsWith('.css')) { + rscCssFiles.push(asset.fileName) + } } } const serverResources: Record = {} const rscAssetDeps = collectAssetDeps(rscBundle) + const usedRscCssFiles: string[] = [] for (const [id, meta] of Object.entries(serverResourcesMetaMap)) { + const css = rscAssetDeps[id]?.deps.css ?? [] serverResources[meta.key] = assetsURLOfDeps({ js: [], - css: rscAssetDeps[id]?.deps.css ?? [], + css, }) + usedRscCssFiles.push(...css) + } + + // warn if css files are not associated with server components + // TODO: but this is technically fine when using explicit `?raw/inline/url` query import + // to render css manually. + const unusedRscCssFiles = rscCssFiles.filter( + (f) => !usedRscCssFiles.includes(f), + ) + if (unusedRscCssFiles.length > 0) { + const files = [...new Set(unusedRscCssFiles)].join(', ') + this.warn( + `\ +The following CSS files in 'rsc' environment are not rendered by any server components: +- ${files} +See https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-rsc#css-support +`, + ) } const assetDeps = collectAssetDeps(bundle) @@ -1521,7 +1545,7 @@ function mergeAssetDeps(a: AssetDeps, b: AssetDeps): AssetDeps { } function collectAssetDeps(bundle: Rollup.OutputBundle) { - const chunkToDeps = new Map() + const chunkToDeps = new Map() for (const chunk of Object.values(bundle)) { if (chunk.type === 'chunk') { chunkToDeps.set(chunk, collectAssetDepsInner(chunk.fileName, bundle)) @@ -1529,7 +1553,7 @@ function collectAssetDeps(bundle: Rollup.OutputBundle) { } const idToDeps: Record< string, - { chunk: Rollup.OutputChunk; deps: AssetDeps } + { chunk: Rollup.OutputChunk; deps: ResolvedAssetDeps } > = {} for (const [chunk, deps] of chunkToDeps.entries()) { for (const id of chunk.moduleIds) { @@ -1542,7 +1566,7 @@ function collectAssetDeps(bundle: Rollup.OutputBundle) { function collectAssetDepsInner( fileName: string, bundle: Rollup.OutputBundle, -): AssetDeps { +): ResolvedAssetDeps { const visited = new Set() const css: string[] = []