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[] = []