fully-react
Version:
React Server for Vite
138 lines (119 loc) • 4.01 kB
text/typescript
import { cpSync, readFileSync } from "fs";
import { join, relative } from "path";
import { removeDir, writeJson } from "./fs";
import { Manifest } from "vite";
import { copyDependenciesToFunction } from "./nft";
import { pathToFileURL } from "url";
async function adapt() {
const buildTempFolder = pathToFileURL(process.cwd() + "/");
const outDir = new URL(".vercel/output/", buildTempFolder);
const serverEntry = new URL("dist/server/handler.js", buildTempFolder);
const functionFolder = new URL(
".vercel/output/functions/render.func/",
buildTempFolder,
);
const staticOutDir = new URL("static", outDir);
const staticInDir = new URL("dist/static", buildTempFolder);
// const inc = includeFiles?.map((file) => new URL(file, _config.root)) || [];
// if (_config.vite.assetsInclude) {
// const mergeGlobbedIncludes = (globPattern: unknown) => {
// if (typeof globPattern === "string") {
// const entries = glob.sync(globPattern).map((p) => pathToFileURL(p));
// inc.push(...entries);
// } else if (Array.isArray(globPattern)) {
// for (const pattern of globPattern) {
// mergeGlobbedIncludes(pattern);
// }
// }
// };
// mergeGlobbedIncludes(_config.vite.assetsInclude);
// }
const serverManifest: Manifest = JSON.parse(
readFileSync("dist/server/manifest.json", "utf-8"),
);
const serverClientManifest: string[] = JSON.parse(
readFileSync("dist/server/react-server/client-manifest.json", "utf-8"),
);
const serverServerManifest: string[] = JSON.parse(
readFileSync("dist/server/react-server/server-manifest.json", "utf-8"),
);
const entries: URL[] = [];
serverServerManifest.forEach((s) => {
entries.push(
new URL(
`./` + serverManifest[relative(process.cwd(), s)].file,
serverEntry,
),
);
});
serverClientManifest.forEach((s) => {
entries.push(
new URL(
`./` + serverManifest[relative(process.cwd(), s)].file,
serverEntry,
),
);
});
// Remove previous output folder
await removeDir(outDir);
cpSync(staticInDir, staticOutDir, { recursive: true });
// Copy necessary files (e.g. node_modules/)
const { handler } = await copyDependenciesToFunction({
entries: [
serverEntry,
new URL("dist/server/react-server/react-server.js", buildTempFolder),
...entries,
],
outDir: functionFolder,
// includeFiles: inc,
includeFiles: [],
excludeFiles: [],
// excludeFiles:
// excludeFiles?.map((file) => new URL(file, _config.root)) || [],
});
const root = handler.replace("dist/server/handler.js", "");
// Enable ESM
// https://aws.amazon.com/blogs/compute/using-node-js-es-modules-and-top-level-await-in-aws-lambda/
await writeJson(new URL(`package.json`, functionFolder), {
type: "module",
});
// Serverless function config
// https://vercel.com/docs/build-output-api/v3#vercel-primitives/serverless-functions/configuration
await writeJson(new URL(`.vc-config.json`, functionFolder), {
runtime: getRuntime(),
handler,
environment: {
OUT_ROOT_DIR: root,
},
launcherType: "Nodejs",
});
await writeJson(
new URL(root + "dist/server/static-manifest.json", functionFolder),
JSON.parse(readFileSync("dist/static/manifest.json", "utf-8")),
);
await writeJson(
new URL(root + "dist/server/manifest.json", functionFolder),
JSON.parse(readFileSync("dist/server/manifest.json", "utf-8")),
);
// Output configuration
// https://vercel.com/docs/build-output-api/v3#build-output-configuration
await writeJson(new URL(`config.json`, outDir), {
version: 3,
routes: [
// ...getRedirects(routes, _config),
{ handle: "filesystem" },
{ src: "/.*", dest: "render" },
],
});
}
function getRuntime() {
const version = process.version.slice(1); // 'v16.5.0' --> '16.5.0'
const major = version.split(".")[0]; // '16.5.0' --> '16'
return `nodejs${major}.x`;
}
async function generate() {
const url = join(process.cwd(), "/dist/server/handler.js");
const { default: handler } = await import(url);
console.log(handler);
}
generate();