diff --git a/.changeset/wicked-laws-bake.md b/.changeset/wicked-laws-bake.md
new file mode 100644
index 000000000..fe1b973b3
--- /dev/null
+++ b/.changeset/wicked-laws-bake.md
@@ -0,0 +1,5 @@
+---
+"@solidjs/start": patch
+---
+
+Fixed virtual module CSS not being collected in vite dev.
diff --git a/apps/fixtures/css/src/components/test.tsx b/apps/fixtures/css/src/components/test.tsx
index 43b7de1b9..a052ba7c7 100644
--- a/apps/fixtures/css/src/components/test.tsx
+++ b/apps/fixtures/css/src/components/test.tsx
@@ -60,6 +60,12 @@ export const CommonTests = (props: { routeModuleClass?: string }) => (
class={props.routeModuleClass}
integration="module"
/>
+
+ ({
+ name: "css-fixture-virtual-css",
+ resolveId(source) {
+ if (source === id) return resolvedId;
+ },
+ load(id) {
+ if (id.startsWith(resolvedId))
+ return `.virtualCss { background-color: var(--color-success); }`;
+ },
+ }) satisfies Plugin;
+
+export default virtualCSS;
diff --git a/apps/fixtures/css/vite.config.ts b/apps/fixtures/css/vite.config.ts
index 636b0a385..45a044c7a 100644
--- a/apps/fixtures/css/vite.config.ts
+++ b/apps/fixtures/css/vite.config.ts
@@ -2,7 +2,8 @@ import tailwindcss from "@tailwindcss/vite";
import { defineConfig } from "vite";
import { nitroV2Plugin } from "../../../packages/start-nitro-v2-vite-plugin/src";
import { solidStart } from "../../../packages/start/src/config";
+import virtualCSS from "./src/virtualCssPlugin";
export default defineConfig({
- plugins: [solidStart(), nitroV2Plugin(), tailwindcss()],
+ plugins: [virtualCSS(), solidStart(), nitroV2Plugin(), tailwindcss()],
});
diff --git a/packages/start/src/config/manifest.ts b/packages/start/src/config/manifest.ts
index e1276d600..093cc7209 100644
--- a/packages/start/src/config/manifest.ts
+++ b/packages/start/src/config/manifest.ts
@@ -3,6 +3,7 @@ import { type PluginOption, type ViteDevServer } from "vite";
import { findStylesInModuleGraph } from "../server/collect-styles.ts";
import { VIRTUAL_MODULES } from "./constants.ts";
import { type SolidStartOptions } from "./index.ts";
+import { wrapId } from "./vite-utils.ts";
export function manifest(start: SolidStartOptions): PluginOption {
let devServer: ViteDevServer = undefined!;
@@ -69,10 +70,10 @@ export function manifest(start: SolidStartOptions): PluginOption {
tag: "style",
attrs: {
type: "text/css",
- "data-vite-dev-id": "${key}",
+ "data-vite-dev-id": "${wrapId(key)}",
"data-vite-ref": "0",
},
- children: () => import("${value}?inline").then(mod => mod.default),
+ children: () => import("${wrapId(value)}?inline").then(mod => mod.default),
}`,
);
diff --git a/packages/start/src/config/vite-utils.ts b/packages/start/src/config/vite-utils.ts
index f5a7d7627..c718af9f8 100644
--- a/packages/start/src/config/vite-utils.ts
+++ b/packages/start/src/config/vite-utils.ts
@@ -12,6 +12,7 @@ export const FS_PREFIX = `/@fs/`;
export const VALID_ID_PREFIX = `/@id/`;
export const NULL_BYTE_PLACEHOLDER = `__x00__`;
+const NULL_BYTE_REGEX = /^\0/;
export function normalizeResolvedIdToUrl(
environment: DevEnvironment,
@@ -52,10 +53,13 @@ export function normalizeResolvedIdToUrl(
return url;
}
+/**
+ * Inspired by:
+ * https://github.com/withastro/astro/blob/fddde5fad81007795eb263c7fd0cea096b8e2cba/packages/astro/src/core/util.ts#L115
+ * https://github.com/vitejs/vite/blob/130e7181a55c524383c63bbfb1749d0ff7185cad/packages/vite/src/shared/utils.ts#L11
+ */
export function wrapId(id: string): string {
- return id.startsWith(VALID_ID_PREFIX)
- ? id
- : VALID_ID_PREFIX + id.replace("\0", NULL_BYTE_PLACEHOLDER);
+ return id.replace(NULL_BYTE_REGEX, `${VALID_ID_PREFIX}${NULL_BYTE_PLACEHOLDER}`);
}
export function unwrapId(id: string): string {
diff --git a/packages/start/src/server/StartServer.tsx b/packages/start/src/server/StartServer.tsx
index 97419175c..3ca15d1e1 100644
--- a/packages/start/src/server/StartServer.tsx
+++ b/packages/start/src/server/StartServer.tsx
@@ -5,6 +5,7 @@ import App from "solid-start:app";
import { ErrorBoundary, TopErrorBoundary } from "../shared/ErrorBoundary.tsx";
import { useAssets } from "./assets/index.ts";
+import PatchVirtualDevStyles from "./assets/PatchVirtualDevStyles.tsx";
import { getSsrManifest } from "./manifest/ssr-manifest.ts";
import type { DocumentComponentProps, PageEvent } from "./types.ts";
@@ -29,6 +30,7 @@ export function StartServer(props: { document: Component
assets={}
scripts={
<>
+