diff options
Diffstat (limited to 'packages/integrations/vercel/src')
-rw-r--r-- | packages/integrations/vercel/src/lib/fs.ts | 2 | ||||
-rw-r--r-- | packages/integrations/vercel/src/serverless/adapter.ts | 78 |
2 files changed, 52 insertions, 28 deletions
diff --git a/packages/integrations/vercel/src/lib/fs.ts b/packages/integrations/vercel/src/lib/fs.ts index 875a0ae9c..18fbe85d2 100644 --- a/packages/integrations/vercel/src/lib/fs.ts +++ b/packages/integrations/vercel/src/lib/fs.ts @@ -4,7 +4,7 @@ import nodePath from 'node:path'; import { fileURLToPath } from 'node:url'; export async function writeJson<T>(path: PathLike, data: T) { - await fs.writeFile(path, JSON.stringify(data), { encoding: 'utf-8' }); + await fs.writeFile(path, JSON.stringify(data, null, '\t'), { encoding: 'utf-8' }); } export async function removeDir(dir: PathLike) { diff --git a/packages/integrations/vercel/src/serverless/adapter.ts b/packages/integrations/vercel/src/serverless/adapter.ts index 8a1870770..52fb9b34b 100644 --- a/packages/integrations/vercel/src/serverless/adapter.ts +++ b/packages/integrations/vercel/src/serverless/adapter.ts @@ -1,4 +1,4 @@ -import type { AstroAdapter, AstroConfig, AstroIntegration } from 'astro'; +import type { AstroAdapter, AstroConfig, AstroIntegration, RouteData } from 'astro'; import glob from 'fast-glob'; import { pathToFileURL } from 'url'; @@ -12,6 +12,7 @@ import { exposeEnv } from '../lib/env.js'; import { getVercelOutput, removeDir, writeJson } from '../lib/fs.js'; import { copyDependenciesToFunction } from '../lib/nft.js'; import { getRedirects } from '../lib/redirects.js'; +import { basename } from 'node:path'; const PACKAGE_NAME = '@astrojs/vercel/serverless'; @@ -40,8 +41,34 @@ export default function vercelServerless({ }: VercelServerlessConfig = {}): AstroIntegration { let _config: AstroConfig; let buildTempFolder: URL; - let functionFolder: URL; let serverEntry: string; + let _entryPoints: Map<RouteData, URL>; + + async function createFunctionFolder(funcName: string, entry: URL, inc: URL[]) { + const functionFolder = new URL(`./functions/${funcName}.func/`, _config.outDir); + + // Copy necessary files (e.g. node_modules/) + const { handler } = await copyDependenciesToFunction({ + entry, + outDir: functionFolder, + includeFiles: inc, + excludeFiles: excludeFiles?.map((file) => new URL(file, _config.root)) || [], + }); + + // 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, + launcherType: 'Nodejs', + }); + } return { name: PACKAGE_NAME, @@ -70,7 +97,6 @@ export default function vercelServerless({ setAdapter(getAdapter()); _config = config; buildTempFolder = config.build.server; - functionFolder = new URL('./functions/render.func/', config.outDir); serverEntry = config.build.serverEntry; if (config.output === 'static') { @@ -80,6 +106,9 @@ export default function vercelServerless({ `); } }, + 'astro:build:ssr': async ({ entryPoints }) => { + _entryPoints = entryPoints; + }, 'astro:build:done': async ({ routes }) => { // Merge any includes from `vite.assetsInclude const inc = includeFiles?.map((file) => new URL(file, _config.root)) || []; @@ -98,30 +127,22 @@ export default function vercelServerless({ mergeGlobbedIncludes(_config.vite.assetsInclude); } - // Copy necessary files (e.g. node_modules/) - const { handler } = await copyDependenciesToFunction({ - entry: new URL(serverEntry, buildTempFolder), - outDir: functionFolder, - includeFiles: inc, - excludeFiles: excludeFiles?.map((file) => new URL(file, _config.root)) || [], - }); - - // Remove temporary folder - await removeDir(buildTempFolder); - - // 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', - }); + const routeDefinitions: { src: string; dest: string }[] = []; - // 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, - launcherType: 'Nodejs', - }); + // Multiple entrypoint support + if(_entryPoints.size) { + for(const [route, entryFile] of _entryPoints) { + const func = basename(entryFile.toString()).replace(/\.mjs$/, ''); + await createFunctionFolder(func, entryFile, inc); + routeDefinitions.push({ + src: route.pattern.source, + dest: func + }); + } + } else { + await createFunctionFolder('render', new URL(serverEntry, buildTempFolder), inc); + routeDefinitions.push({ src: '/.*', dest: 'render' }); + } // Output configuration // https://vercel.com/docs/build-output-api/v3#build-output-configuration @@ -130,12 +151,15 @@ export default function vercelServerless({ routes: [ ...getRedirects(routes, _config), { handle: 'filesystem' }, - { src: '/.*', dest: 'render' }, + ...routeDefinitions ], ...(imageService || imagesConfig ? { images: imagesConfig ? imagesConfig : defaultImageConfig } : {}), }); + + // Remove temporary folder + await removeDir(buildTempFolder); }, }, }; |