diff --git a/packages/astro/src/core/build/index.ts b/packages/astro/src/core/build/index.ts index 11e2b1fa9..40cf9decd 100644 --- a/packages/astro/src/core/build/index.ts +++ b/packages/astro/src/core/build/index.ts @@ -1,9 +1,9 @@ -import type { AstroConfig, AstroSettings, ManifestData, RuntimeMode } from '../../@types/astro'; import fs from 'fs'; import * as colors from 'kleur/colors'; import { performance } from 'perf_hooks'; import type * as vite from 'vite'; import type yargs from 'yargs-parser'; +import type { AstroConfig, AstroSettings, ManifestData, RuntimeMode } from '../../@types/astro'; import { runHookBuildDone, runHookBuildStart, @@ -11,7 +11,7 @@ import { runHookConfigSetup, } from '../../integrations/index.js'; import { createVite } from '../create-vite.js'; -import { debug, info, warn, levels, timerMessage, type LogOptions } from '../logger/core.js'; +import { debug, info, levels, timerMessage, warn, type LogOptions } from '../logger/core.js'; import { printHelp } from '../messages.js'; import { apply as applyPolyfill } from '../polyfill.js'; import { RouteCache } from '../render/route-cache.js'; diff --git a/packages/astro/src/core/build/plugins/plugin-middleware.ts b/packages/astro/src/core/build/plugins/plugin-middleware.ts index 6db39733e..8afca2fbc 100644 --- a/packages/astro/src/core/build/plugins/plugin-middleware.ts +++ b/packages/astro/src/core/build/plugins/plugin-middleware.ts @@ -1,9 +1,9 @@ import type { Plugin as VitePlugin } from 'vite'; import { MIDDLEWARE_PATH_SEGMENT_NAME } from '../../constants.js'; import { addRollupInput } from '../add-rollup-input.js'; +import type { BuildInternals } from '../internal'; import type { AstroBuildPlugin } from '../plugin'; import type { StaticBuildOptions } from '../types'; -import type { BuildInternals } from '../internal'; export const MIDDLEWARE_MODULE_ID = '@astro-middleware'; diff --git a/packages/astro/src/core/middleware/index.ts b/packages/astro/src/core/middleware/index.ts index 47127c674..66c34985f 100644 --- a/packages/astro/src/core/middleware/index.ts +++ b/packages/astro/src/core/middleware/index.ts @@ -1,6 +1,6 @@ import type { MiddlewareResponseHandler, Params } from '../../@types/astro'; -import { sequence } from './sequence.js'; import { createAPIContext } from '../endpoint/index.js'; +import { sequence } from './sequence.js'; function defineMiddleware(fn: MiddlewareResponseHandler) { return fn; diff --git a/packages/integrations/vercel/README.md b/packages/integrations/vercel/README.md index 19d841a2f..fd03abba9 100644 --- a/packages/integrations/vercel/README.md +++ b/packages/integrations/vercel/README.md @@ -235,7 +235,7 @@ export default defineConfig({ ### Vercel Edge Middleware -You can use Vercel Edge middleware to intercept a request and redirect before sending a response. Vercel middleware can run for Edge, SSR, and Static deployments. You may not need to install this package for your middleware. `@vercel/edge` is only required to use some middleware features such as geolocation. For more information see [Vercel’s middleware documentation](https://vercel.com/docs/concepts/functions/edge-middleware). +You can use Vercel Edge middleware to intercept a request and redirect before sending a response. Vercel middleware can run for Edge, SSR, and Static deployments. You may not need to install this package for your middleware. `@vercel/edge` is only required to use some middleware features such as geolocation. For more information see [Vercel’s middleware documentation](https://vercel.com/docs/concepts/functions/edge-middleware). 1. Add a `middleware.js` file to the root of your project: @@ -270,15 +270,15 @@ This is an opt-in feature, and the `build.excludeMiddleware` option needs to be ```js // astro.config.mjs -import {defineConfig} from "astro/config"; -import vercel from "@astrojs/vercel"; +import { defineConfig } from 'astro/config'; +import vercel from '@astrojs/vercel'; export default defineConfig({ - output: "server", - adapter: vercel(), - build: { - excludeMiddleware: true - } -}) + output: 'server', + adapter: vercel(), + build: { + excludeMiddleware: true, + }, +}); ``` Optionally, you can create a file recognized by the adapter named `vercel-edge-middleware.(js|ts)` in the [`srcDir`](https://docs.astro.build/en/reference/configuration-reference/#srcdir) folder to create [`Astro.locals`](https://docs.astro.build/en/reference/api-reference/#astrolocals). @@ -288,16 +288,16 @@ Typings requires the [`@vercel/edge`](https://www.npmjs.com/package/@vercel/edge ```js // src/vercel-edge-middleware.js /** - * + * * @param options.request {Request} * @param options.context {import("@vercel/edge").RequestContext} * @returns {object} */ -export default function({ request, context }) { - // do something with request and context - return { - title: "Spider-man's blog" - } +export default function ({ request, context }) { + // do something with request and context + return { + title: "Spider-man's blog", + }; } ``` @@ -305,33 +305,34 @@ If you use TypeScript, you can type the function as follows: ```ts // src/vercel-edge-middleware.ts -import type {RequestContext} from "@vercel/edge"; +import type { RequestContext } from '@vercel/edge'; -export default function ({request, context}: { request: Request, context: RequestContext }) { - // do something with request and context - return { - title: "Spider-man's blog" - } +export default function ({ request, context }: { request: Request; context: RequestContext }) { + // do something with request and context + return { + title: "Spider-man's blog", + }; } ``` The data returned by this function will be passed to Astro middleware. The function: + - must export a **default** function; - must **return** an `object`; - accepts an object with a `request` and `context` as properties; - `request` is typed as [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request); - `context` is typed as [`RequestContext`](https://vercel.com/docs/concepts/functions/edge-functions/vercel-edge-package#requestcontext); -#### Limitations and constraints +#### Limitations and constraints When you opt in to this feature, there are few constraints to note: + - The Vercel Edge middleware will always be the **first** function to receive the `Request` and the last function to receive `Response`. This an architectural constraint that follows the [boundaries set by Vercel](https://vercel.com/docs/concepts/functions/edge-middleware). - Only `request` and `context` may be used to produce an `Astro.locals` object. Operations like redirects, etc. should be delegated to Astro middleware. - `Astro.locals` **must be serializable**. Failing to do so will result in a **runtime error**. This means that you **cannot** store complex types like `Map`, `function`, `Set`, etc. - ## Troubleshooting **A few known complex packages (example: [puppeteer](https://github.com/puppeteer/puppeteer)) do not support bundling and therefore will not work properly with this adapter.** By default, Vercel doesn't include npm installed files & packages from your project's `./node_modules` folder. To address this, the `@astrojs/vercel` adapter automatically bundles your final build output using `esbuild`. diff --git a/packages/integrations/vercel/src/serverless/adapter.ts b/packages/integrations/vercel/src/serverless/adapter.ts index 9d799a7bf..79e0a91ae 100644 --- a/packages/integrations/vercel/src/serverless/adapter.ts +++ b/packages/integrations/vercel/src/serverless/adapter.ts @@ -2,6 +2,7 @@ import type { AstroAdapter, AstroConfig, AstroIntegration, RouteData } from 'ast import glob from 'fast-glob'; import { basename } from 'node:path'; +import { fileURLToPath } from 'node:url'; import { pathToFileURL } from 'url'; import { defaultImageConfig, @@ -14,7 +15,6 @@ import { getVercelOutput, removeDir, writeJson } from '../lib/fs.js'; import { copyDependenciesToFunction } from '../lib/nft.js'; import { getRedirects } from '../lib/redirects.js'; import { generateEdgeMiddleware } from './middleware.js'; -import { fileURLToPath } from 'node:url'; const PACKAGE_NAME = '@astrojs/vercel/serverless'; export const ASTRO_LOCALS_HEADER = 'x-astro-locals'; diff --git a/packages/integrations/vercel/src/serverless/entrypoint.ts b/packages/integrations/vercel/src/serverless/entrypoint.ts index 3c0e22a28..48c9b71d9 100644 --- a/packages/integrations/vercel/src/serverless/entrypoint.ts +++ b/packages/integrations/vercel/src/serverless/entrypoint.ts @@ -3,8 +3,8 @@ import type { SSRManifest } from 'astro'; import { App } from 'astro/app'; import type { IncomingMessage, ServerResponse } from 'node:http'; -import { getRequest, setResponse } from './request-transform'; import { ASTRO_LOCALS_HEADER } from './adapter'; +import { getRequest, setResponse } from './request-transform'; polyfill(globalThis, { exclude: 'window document', diff --git a/packages/integrations/vercel/src/serverless/middleware.ts b/packages/integrations/vercel/src/serverless/middleware.ts index 2f05756c6..c28425f4c 100644 --- a/packages/integrations/vercel/src/serverless/middleware.ts +++ b/packages/integrations/vercel/src/serverless/middleware.ts @@ -1,7 +1,7 @@ -import { fileURLToPath, pathToFileURL } from 'node:url'; -import { join } from 'node:path'; -import { ASTRO_LOCALS_HEADER } from './adapter.js'; import { existsSync } from 'fs'; +import { join } from 'node:path'; +import { fileURLToPath, pathToFileURL } from 'node:url'; +import { ASTRO_LOCALS_HEADER } from './adapter.js'; /** * It generates the Vercel Edge Middleware file.