Skip to content
5 changes: 5 additions & 0 deletions .changeset/vite-ecosystem-ci-bump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@solidjs/start": patch
---

Add support for Vite 8 asset manifest loading
4 changes: 2 additions & 2 deletions packages/start/src/config/fs-routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ export function fsRoutes({ routers }: FsRoutesArgs): Array<PluginOption> {
const buildId = `${v.src}?${v.pick.map((p: any) => `pick=${p}`).join("&")}`;
return {
src: relative(root, buildId),
build: isBuild ? `_$() => import(/* @vite-ignore */ '${buildId}')$_` : undefined,
import: `_$() => import(/* @vite-ignore */ '${buildId}')$_`,
build: isBuild ? `_$() => import('${buildId}')$_` : undefined,
import: `_$() => import('${buildId}')$_`,
};
}
return v;
Expand Down
13 changes: 12 additions & 1 deletion packages/start/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,16 @@ export function solidStart(options?: SolidStartOptions): Array<PluginOption> {
return {
appType: "custom",
build: { assetsDir: "_build/assets" },
optimizeDeps: {
// Suppress TS errors from Vite 7 types when configuring Vite 8's Rolldown
...({
rolldownOptions: {
transform: {
jsx: "react",
},
},
} as any),
},
environments: {
[VITE_ENVIRONMENTS.client]: {
consumer: "client",
Expand Down Expand Up @@ -221,8 +231,9 @@ export function solidStart(options?: SolidStartOptions): Array<PluginOption> {
{
name: "solid-start:capture-client-bundle",
enforce: "post",
generateBundle(_options, bundle) {
generateBundle(options, bundle) {
globalThis.START_CLIENT_BUNDLE = bundle;
(globalThis as any).START_CLIENT_OUT_DIR = options.dir;
},
},
devServer(),
Expand Down
45 changes: 42 additions & 3 deletions packages/start/src/config/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,48 @@ export function manifest(start: SolidStartOptions): PluginOption {
v => "isEntry" in v && v.isEntry,
);
if (!entry) throw new Error("No client entry found");
clientViteManifest = JSON.parse(
(globalThis.START_CLIENT_BUNDLE[".vite/manifest.json"] as any).source,
);
let viteStrVersion = (devServer?.config?.logger as any)?.config?.version;
if (!viteStrVersion) {
try {
viteStrVersion = await import("vite").then(m => m.version);
} catch (e) {
// ignore
}
}

let rawManifest: string | undefined;

const viteMajor = parseInt(viteStrVersion!.split('.')[0], 10);

const manifestKey = Object.keys(globalThis.START_CLIENT_BUNDLE).find(k => k.endsWith("manifest.json"));
if (manifestKey && viteMajor < 8) {
const manifestAsset = globalThis.START_CLIENT_BUNDLE[manifestKey] as any;
rawManifest = manifestAsset.source as string;
} else {
const fs = await import("node:fs");
const path = await import("node:path");
try {
const appRoot = (start as any).appRoot || "./src";
let outDir = ".solid-start/client";
if (devServer?.environments?.client?.config?.build?.outDir) {
outDir = devServer.environments.client.config.build.outDir;
} else if (this.environment?.config?.build?.outDir && this.environment?.config?.consumer === "client") {
outDir = this.environment.config.build.outDir;
} else if ((globalThis as any).START_CLIENT_OUT_DIR) {
outDir = (globalThis as any).START_CLIENT_OUT_DIR;
}
const manifestPath = path.resolve(appRoot, "..", outDir, ".vite/manifest.json");
rawManifest = fs.readFileSync(manifestPath, "utf-8");
} catch (e) {
throw new Error(`Manifest asset not found in bundle and could not be read from disk. Keys: ${Object.keys(globalThis.START_CLIENT_BUNDLE).join(", ")}. Error: ${e}`);
}
}

if (!rawManifest) {
throw new Error("Failed to extract or read raw manifest.");
}

clientViteManifest = JSON.parse(rawManifest);
}
return `export const clientViteManifest = ${JSON.stringify(clientViteManifest)};`;
} else if (id === `\0${VIRTUAL_MODULES.middleware}`) return "export default {};";
Expand Down
Loading