-
Notifications
You must be signed in to change notification settings - Fork 418
Expand file tree
/
Copy pathmanifest.ts
More file actions
115 lines (105 loc) · 4.81 KB
/
manifest.ts
File metadata and controls
115 lines (105 loc) · 4.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import fs from "node:fs";
import path from "node:path";
import { type PluginOption, type ViteDevServer, version as viteVersion } 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!;
return {
name: "solid-start:manifest-plugin",
enforce: "pre",
configureServer(server) {
devServer = server;
},
async resolveId(id) {
if (id === VIRTUAL_MODULES.clientViteManifest)
return `\0${VIRTUAL_MODULES.clientViteManifest}`;
if (id === VIRTUAL_MODULES.getClientManifest)
return this.resolve(
new URL("../server/manifest/client-manifest", import.meta.url).pathname,
);
if (id === VIRTUAL_MODULES.getManifest) {
return this.environment.config.consumer === "client"
? this.resolve(new URL("../server/manifest/client-manifest", import.meta.url).pathname)
: this.resolve(new URL("../server/manifest/ssr-manifest", import.meta.url).pathname);
}
if (id === VIRTUAL_MODULES.middleware) {
if (start.middleware) return await this.resolve(start.middleware);
return `\0${VIRTUAL_MODULES.middleware}`;
}
},
async load(id) {
if (id === `\0${VIRTUAL_MODULES.clientViteManifest}`) {
let clientViteManifest: Record<string, Record<string, any>>;
if (this.environment.config.command === "serve") {
clientViteManifest = {};
} else {
const entry = Object.values(globalThis.START_CLIENT_BUNDLE).find(
v => "isEntry" in v && v.isEntry,
);
if (!entry) throw new Error("No client entry found");
let rawManifest: string | undefined;
const viteMajor = parseInt(viteVersion.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 {
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 {};";
else if (id.startsWith("/@manifest")) {
if (this.environment.mode !== "dev")
throw new Error("@manifest queries are only allowed in dev");
const [urlPath, query] = id.split("?");
const target = id.split("/")[2]!;
const params = new URLSearchParams(query);
if (!urlPath || !query) return;
if (urlPath.endsWith("assets")) {
const id = params.get("id");
if (!id) {
throw new Error("Missing id to get assets.");
}
// Client env does not have css dependencies in mod.transformResult
// Aalways use ssr env instead, to prevent hydration mismatches
const env = devServer.environments["ssr"];
const styles = await findStylesInModuleGraph(env, id);
const cssAssets = Object.entries(styles).map(
([key, value]) => `{
tag: "style",
attrs: {
type: "text/css",
"data-vite-dev-id": "${wrapId(key)}",
"data-vite-ref": "0",
},
children: () => import("${wrapId(value)}?inline").then(mod => mod.default),
}`,
);
return `export default [${cssAssets.join(",")}]`;
}
}
},
};
}