fully-react
Version:
React Server for Vite
293 lines (288 loc) • 8.64 kB
JavaScript
import {
createModuleMapProxy,
setupWebpackEnv
} from "./chunk-5OA5SROH.js";
import {
createServerRouter
} from "./chunk-OS6VLPVU.js";
// src/server/entry.tsx
import path2, { basename, join, relative } from "node:path";
// src/server/dev/find-styles.tsx
import path from "node:path";
async function find_deps(vite, node, deps) {
const branches = [];
async function add(node2) {
if (!deps.has(node2)) {
deps.add(node2);
await find_deps(vite, node2, deps);
}
}
async function add_by_url(url) {
const node2 = await vite.moduleGraph.getModuleByUrl(url);
if (node2) {
await add(node2);
}
}
if (node.ssrTransformResult) {
if (node.ssrTransformResult.deps) {
node.ssrTransformResult.deps.forEach(
(url) => branches.push(add_by_url(url))
);
}
} else {
node.importedModules.forEach((node2) => branches.push(add(node2)));
}
await Promise.all(branches);
}
var style_pattern = /\.(css|less|sass|scss|styl|stylus|pcss|postcss)$/;
async function collectStyles(devServer, match) {
const styles = {};
const deps = /* @__PURE__ */ new Set();
try {
for (const file of match) {
const resolvedId = await devServer.pluginContainer.resolveId(file);
if (!resolvedId) {
console.log("not found");
continue;
}
const id = resolvedId.id;
const normalizedPath = path.resolve(id).replace(/\\/g, "/");
let node = devServer.moduleGraph.getModuleById(normalizedPath);
if (!node) {
const absolutePath = path.resolve(file);
await devServer.ssrLoadModule(absolutePath);
node = await devServer.moduleGraph.getModuleByUrl(absolutePath);
if (!node) {
console.log("not found");
return;
}
}
await find_deps(devServer, node, deps);
}
} catch (e) {
}
for (const dep of deps) {
const parsed = new URL(dep.url, "http://localhost/");
const query = parsed.searchParams;
if (style_pattern.test(dep.file ?? "")) {
try {
const mod = await devServer.ssrLoadModule(dep.url);
styles[dep.url] = mod.default;
} catch {
}
}
}
return styles;
}
// src/server/entry.tsx
import fs from "node:fs";
import { lazy } from "react";
var findAssetsInManifest = (manifest, id, assetMap = /* @__PURE__ */ new Map()) => {
function traverse(id2) {
const cached = assetMap.get(id2);
if (cached) {
return cached;
}
const chunk = manifest[id2];
if (!chunk) {
return [];
}
const assets = [
...chunk.assets || [],
...chunk.css || [],
...chunk.imports?.flatMap(traverse) || []
];
const imports = chunk.imports?.flatMap(traverse) || [];
const all = [...assets, ...imports].filter(
Boolean
);
all.push(chunk.file);
assetMap.set(id2, all);
return Array.from(new Set(all));
}
return traverse(id);
};
var findAssetsInModuleNode = (moduleNode) => {
const seen = /* @__PURE__ */ new Set();
function traverse(node) {
if (seen.has(node.url)) {
return [];
}
seen.add(node.url);
const imports = [...node.importedModules].flatMap(traverse) || [];
imports.push(node.url);
return Array.from(new Set(imports));
}
return traverse(moduleNode);
};
var linkPropsMap = /* @__PURE__ */ new Map([
["js", { rel: "modulepreload", crossorigin: "true" }],
["jsx", { rel: "modulepreload", crossorigin: "true" }],
["ts", { rel: "modulepreload", crossorigin: "true" }],
["tsx", { rel: "modulepreload", crossorigin: "true" }],
["css", { rel: "stylesheet" }],
[
"woff",
{ rel: "preload", as: "font", type: "font/woff", crossorigin: "true" }
],
[
"woff2",
{ rel: "preload", as: "font", type: "font/woff2", crossorigin: "true" }
],
["gif", { rel: "preload", as: "image", type: "image/gif" }],
["jpg", { rel: "preload", as: "image", type: "image/jpeg" }],
["jpeg", { rel: "preload", as: "image", type: "image/jpeg" }],
["png", { rel: "preload", as: "image", type: "image/png" }],
["webp", { rel: "preload", as: "image", type: "image/webp" }],
["svg", { rel: "preload", as: "image", type: "image/svg+xml" }],
["ico", { rel: "preload", as: "image", type: "image/x-icon" }],
["avif", { rel: "preload", as: "image", type: "image/avif" }],
["mp4", { rel: "preload", as: "video", type: "video/mp4" }],
["webm", { rel: "preload", as: "video", type: "video/webm" }]
]);
function renderLinkTag(file) {
const ext = basename(file).split(".").pop();
if (!ext) {
return "";
}
const props = linkPropsMap.get(ext);
if (!props) {
return "";
}
const attrs = Object.entries(props).map(([key, value]) => `${key}="${value}"`).join(" ");
return `<link href="${file}" ${attrs} />`;
}
function readJSON(path3) {
return JSON.parse(fs.readFileSync(path3, "utf-8"));
}
function getManifests() {
const buildAppRoot = path2.join(
process.cwd(),
process.env.OUT_ROOT_DIR ?? "."
);
const srcAppRoot = import.meta.env.ROOT_DIR;
const clientManifest = readJSON(
path2.join(buildAppRoot, "dist", "server", "static-manifest.json")
);
const serverManifest = readJSON(
path2.join(buildAppRoot, "dist", "server", "manifest.json")
);
const reactServerManifest = readJSON(
path2.join(buildAppRoot, "dist", "server", "react-server", "manifest.json")
);
const routesConfig = readJSON(
path2.join(buildAppRoot, "dist", "server", "react-server", "routes.json")
);
return {
buildAppRoot,
srcAppRoot,
clientManifest,
serverManifest,
reactServerManifest,
routesConfig,
findInServerManifest(chunk) {
const file = serverManifest[relative(srcAppRoot, chunk)];
if (file) {
return join(
buildAppRoot,
"dist",
"server",
serverManifest[relative(srcAppRoot, chunk)].file
);
} else {
return join(
buildAppRoot,
"dist",
"server",
"react-server",
reactServerManifest[relative(srcAppRoot, chunk)].file
);
}
}
};
}
var createProdEnv = () => {
const manifests = getManifests();
const loadModule = async (chunk) => {
const url = manifests.findInServerManifest(chunk);
const mod = await import(
/* @vite-ignore */
url
);
return mod;
};
setupWebpackEnv(loadModule);
return {
clientModuleMap: createModuleMapProxy(),
components: {},
manifests,
bootstrapScriptContent: `window.manifest = ${JSON.stringify({
root: process.cwd(),
client: Object.fromEntries(
Object.entries(manifests.clientManifest).filter(([key, asset]) => asset.file).map(([key, asset]) => [key, asset.file])
)
})};`,
bootstrapModules: [
`/${manifests.clientManifest[relative(import.meta.env.ROOT_DIR, import.meta.env.CLIENT_ENTRY)].file}`
],
loadModule,
routesConfig: manifests.routesConfig,
lazyComponent: (id) => {
return lazy(() => loadModule(id));
},
findAssets: async () => {
const findAssets = (chunk) => {
return [
...findAssetsInManifest(manifests.serverManifest, chunk).filter((asset) => !asset.endsWith(".js")).map((asset) => `/${asset}`),
...findAssetsInManifest(manifests.reactServerManifest, chunk).filter((asset) => !asset.endsWith(".js")).map((asset) => `/${asset}`)
];
};
return [...findAssets("app/root.tsx")];
}
};
};
var createDevEnv = () => {
const loader = setupWebpackEnv(async (chunk) => {
return await import(
/* @vite-ignore */
chunk
);
});
const routesConfig = __vite_dev_server__.routesConfig;
return {
clientModuleMap: createModuleMapProxy(),
components: {},
bootstrapScriptContent: void 0,
bootstrapModules: [import.meta.env.CLIENT_ENTRY],
routesConfig,
lazyComponent: (id) => {
return lazy(() => loader.load(id));
},
findAssets: async () => {
const { default: devServer } = await import("./dev-server-7Z7UZWCJ.js");
const styles = await collectStyles(devServer, ["~/root?rsc"]);
return [
...Object.entries(styles ?? {}).map(([key, value]) => ({
type: "style",
style: value,
src: key
}))
];
},
loadModule(id) {
return loader.load(id);
}
};
};
var createEnv = import.meta.env.PROD ? createProdEnv : createDevEnv;
function createHandler() {
const env = createEnv();
globalThis.env = env;
return createServerRouter(env).buildHandler();
}
export {
findAssetsInManifest,
findAssetsInModuleNode,
renderLinkTag,
createHandler
};