summaryrefslogtreecommitdiff
path: root/packages/integrations/vercel/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/integrations/vercel/src')
-rw-r--r--packages/integrations/vercel/src/lib/fs.ts2
-rw-r--r--packages/integrations/vercel/src/serverless/adapter.ts78
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);
},
},
};