summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Matthew Phillips <matthew@skypack.dev> 2023-08-10 13:12:13 -0400
committerGravatar GitHub <noreply@github.com> 2023-08-10 13:12:13 -0400
commit9cc4e48e6a858d3a12e6373a5e287b32d24a1c5a (patch)
tree8356733ee8a25bc3226360ddbdc03d9c2786e114
parent34cb2002161ba88df6bcb72fecfd12ed867c134b (diff)
downloadastro-9cc4e48e6a858d3a12e6373a5e287b32d24a1c5a.tar.gz
astro-9cc4e48e6a858d3a12e6373a5e287b32d24a1c5a.tar.zst
astro-9cc4e48e6a858d3a12e6373a5e287b32d24a1c5a.zip
Remove the Vercel Edge adapter (#8015)
* Remove the Vercel Edge adapter * Update tests * Update .changeset/plenty-keys-add.md Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> * Show enabling edge middleware --------- Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
-rw-r--r--.changeset/plenty-keys-add.md23
-rw-r--r--packages/integrations/vercel/README.md15
-rw-r--r--packages/integrations/vercel/src/edge/adapter.ts182
-rw-r--r--packages/integrations/vercel/src/edge/entrypoint.ts28
-rw-r--r--packages/integrations/vercel/src/edge/shim.ts1
-rw-r--r--packages/integrations/vercel/test/static-assets.test.js15
6 files changed, 27 insertions, 237 deletions
diff --git a/.changeset/plenty-keys-add.md b/.changeset/plenty-keys-add.md
new file mode 100644
index 000000000..73a78ba3b
--- /dev/null
+++ b/.changeset/plenty-keys-add.md
@@ -0,0 +1,23 @@
+---
+'@astrojs/vercel': major
+---
+
+Remove the Vercel Edge adapter
+
+ `@astrojs/vercel/serverless` now supports Edge middleware, so a separate adapter for Edge itself (deploying your entire app to the edge) is no longer necessary. Please update your Astro config to reflect this change:
+
+ ```diff
+ // astro.config.mjs
+import { defineConfig } from 'astro/config';
+- import vercel from '@astrojs/vercel/edge';
++ import vercel from '@astrojs/vercel/serverless';
+
+export default defineConfig({
+ output: 'server',
+ adapter: vercel({
++ edgeMiddleware: true
+ }),
+});
+```
+
+This adapter had several known limitations and compatibility issues that prevented many people from using it in production. To reduce maintenance costs and because we have a better story with Serveless + Edge Middleware, we are removing the Edge adapter.
diff --git a/packages/integrations/vercel/README.md b/packages/integrations/vercel/README.md
index fd03abba9..3bf5e574a 100644
--- a/packages/integrations/vercel/README.md
+++ b/packages/integrations/vercel/README.md
@@ -58,16 +58,12 @@ If you prefer to install the adapter manually instead, complete the following tw
You can deploy to different targets:
-- `edge`: SSR inside an [Edge function](https://vercel.com/docs/concepts/functions/edge-functions).
- `serverless`: SSR inside a [Node.js function](https://vercel.com/docs/concepts/functions/serverless-functions).
- `static`: generates a static website following Vercel's output formats, redirects, etc.
-> **Note**: deploying to the Edge has [its limitations](https://vercel.com/docs/concepts/functions/edge-functions#known-limitations). An edge function can't be more than 1 MB in size and they don't support native Node.js APIs, among others.
-
You can change where to target by changing the import:
```js
-import vercel from '@astrojs/vercel/edge';
import vercel from '@astrojs/vercel/serverless';
import vercel from '@astrojs/vercel/static';
```
@@ -90,7 +86,7 @@ To configure this adapter, pass an object to the `vercel()` function call in `as
### analytics
**Type:** `boolean`<br>
-**Available for:** Serverless, Edge, Static<br>
+**Available for:** Serverless, Static<br>
**Added in:** `@astrojs/vercel@3.1.0`
You can enable [Vercel Analytics](https://vercel.com/analytics) (including Web Vitals and Audiences) by setting `analytics: true`. This will inject Vercel’s tracking scripts into all your pages.
@@ -111,7 +107,7 @@ export default defineConfig({
### imagesConfig
**Type:** `VercelImageConfig`<br>
-**Available for:** Edge, Serverless, Static
+**Available for:** Serverless, Static
**Added in:** `@astrojs/vercel@3.3.0`
Configuration options for [Vercel's Image Optimization API](https://vercel.com/docs/concepts/image-optimization). See [Vercel's image configuration documentation](https://vercel.com/docs/build-output-api/v3/configuration#images) for a complete list of supported parameters.
@@ -134,7 +130,7 @@ export default defineConfig({
### imageService
**Type:** `boolean`<br>
-**Available for:** Edge, Serverless, Static
+**Available for:** Serverless, Static
**Added in:** `@astrojs/vercel@3.3.0`
When enabled, an [Image Service](https://docs.astro.build/en/reference/image-service-reference/) powered by the Vercel Image Optimization API will be automatically configured and used in production. In development, a built-in Squoosh-based service will be used instead.
@@ -175,7 +171,7 @@ import astroLogo from '../assets/logo.png';
### includeFiles
**Type:** `string[]`<br>
-**Available for:** Edge, Serverless
+**Available for:** Serverless
Use this property to force files to be bundled with your function. This is helpful when you notice missing files.
@@ -192,9 +188,6 @@ export default defineConfig({
});
```
-> **Note**
-> When building for the Edge, all the dependencies get bundled in a single file to save space. **No extra file will be bundled**. So, if you _need_ some file inside the function, you have to specify it in `includeFiles`.
-
### excludeFiles
**Type:** `string[]`<br>
diff --git a/packages/integrations/vercel/src/edge/adapter.ts b/packages/integrations/vercel/src/edge/adapter.ts
deleted file mode 100644
index b613f502c..000000000
--- a/packages/integrations/vercel/src/edge/adapter.ts
+++ /dev/null
@@ -1,182 +0,0 @@
-import type { AstroAdapter, AstroConfig, AstroIntegration } from 'astro';
-
-import esbuild from 'esbuild';
-import { relative as relativePath } from 'node:path';
-import { fileURLToPath } from 'node:url';
-
-import {
- defaultImageConfig,
- getImageConfig,
- throwIfAssetsNotEnabled,
- type VercelImageConfig,
-} from '../image/shared.js';
-import { exposeEnv } from '../lib/env.js';
-import {
- copyFilesToFunction,
- getFilesFromFolder,
- getVercelOutput,
- removeDir,
- writeJson,
-} from '../lib/fs.js';
-import { getRedirects } from '../lib/redirects.js';
-
-const PACKAGE_NAME = '@astrojs/vercel/edge';
-
-function getAdapter(): AstroAdapter {
- return {
- name: PACKAGE_NAME,
- serverEntrypoint: `${PACKAGE_NAME}/entrypoint`,
- exports: ['default'],
- supportedAstroFeatures: {
- hybridOutput: 'stable',
- staticOutput: 'stable',
- serverOutput: 'stable',
- assets: {
- supportKind: 'stable',
- isSharpCompatible: false,
- isSquooshCompatible: false,
- },
- },
- };
-}
-
-export interface VercelEdgeConfig {
- includeFiles?: string[];
- analytics?: boolean;
- imageService?: boolean;
- imagesConfig?: VercelImageConfig;
-}
-
-export default function vercelEdge({
- includeFiles = [],
- analytics,
- imageService,
- imagesConfig,
-}: VercelEdgeConfig = {}): AstroIntegration {
- let _config: AstroConfig;
- let buildTempFolder: URL;
- let functionFolder: URL;
- let serverEntry: string;
-
- return {
- name: PACKAGE_NAME,
- hooks: {
- 'astro:config:setup': ({ command, config, updateConfig, injectScript }) => {
- if (command === 'build' && analytics) {
- injectScript('page', 'import "@astrojs/vercel/analytics"');
- }
- const outDir = getVercelOutput(config.root);
- const viteDefine = exposeEnv(['VERCEL_ANALYTICS_ID']);
- updateConfig({
- outDir,
- build: {
- serverEntry: 'entry.mjs',
- client: new URL('./static/', outDir),
- server: new URL('./dist/', config.root),
- },
- vite: {
- define: viteDefine,
- ssr: {
- external: ['@vercel/nft'],
- },
- },
- ...getImageConfig(imageService, imagesConfig, command),
- });
- },
- 'astro:config:done': ({ setAdapter, config }) => {
- throwIfAssetsNotEnabled(config, imageService);
- setAdapter(getAdapter());
- _config = config;
- buildTempFolder = config.build.server;
- functionFolder = new URL('./functions/render.func/', config.outDir);
- serverEntry = config.build.serverEntry;
-
- if (config.output === 'static') {
- throw new Error(`
- [@astrojs/vercel] \`output: "server"\` or \`output: "hybrid"\` is required to use the edge adapter.
-
- `);
- }
- },
- 'astro:build:setup': ({ vite, target }) => {
- if (target === 'server') {
- vite.resolve ||= {};
- vite.resolve.alias ||= {};
-
- const aliases = [{ find: 'react-dom/server', replacement: 'react-dom/server.browser' }];
-
- if (Array.isArray(vite.resolve.alias)) {
- vite.resolve.alias = [...vite.resolve.alias, ...aliases];
- } else {
- for (const alias of aliases) {
- (vite.resolve.alias as Record<string, string>)[alias.find] = alias.replacement;
- }
- }
-
- vite.ssr ||= {};
- vite.ssr.target = 'webworker';
-
- // Vercel edge runtime is a special webworker-ish environment that supports process.env,
- // but Vite would replace away `process.env` in webworkers, so we set a define here to prevent it
- vite.define = {
- 'process.env': 'process.env',
- ...vite.define,
- };
- }
- },
- 'astro:build:done': async ({ routes }) => {
- const entry = new URL(serverEntry, buildTempFolder);
- const generatedFiles = await getFilesFromFolder(buildTempFolder);
- const entryPath = fileURLToPath(entry);
-
- await esbuild.build({
- target: 'es2020',
- platform: 'browser',
- // https://runtime-keys.proposal.wintercg.org/#edge-light
- conditions: ['edge-light', 'worker', 'browser'],
- entryPoints: [entryPath],
- outfile: entryPath,
- allowOverwrite: true,
- format: 'esm',
- bundle: true,
- minify: true,
- });
-
- // Copy entry and other server files
- const commonAncestor = await copyFilesToFunction(
- [...generatedFiles, ...includeFiles.map((file) => new URL(file, _config.root))],
- functionFolder
- );
-
- // Remove temporary folder
- await removeDir(buildTempFolder);
-
- // Edge function config
- // https://vercel.com/docs/build-output-api/v3#vercel-primitives/edge-functions/configuration
- await writeJson(new URL(`./.vc-config.json`, functionFolder), {
- runtime: 'edge',
- entrypoint: relativePath(commonAncestor, entryPath),
- });
-
- // Output configuration
- // https://vercel.com/docs/build-output-api/v3#build-output-configuration
- await writeJson(new URL(`./config.json`, _config.outDir), {
- version: 3,
- routes: [
- ...getRedirects(routes, _config),
- {
- src: `^/${_config.build.assets}/(.*)$`,
- headers: { 'cache-control': 'public, max-age=31536000, immutable' },
- continue: true,
- },
- { handle: 'filesystem' },
- { src: '/.*', dest: 'render' },
- ],
- ...(imageService || imagesConfig
- ? { images: imagesConfig ? imagesConfig : defaultImageConfig }
- : {}),
- });
- },
- },
- };
-}
diff --git a/packages/integrations/vercel/src/edge/entrypoint.ts b/packages/integrations/vercel/src/edge/entrypoint.ts
deleted file mode 100644
index 4b88bc793..000000000
--- a/packages/integrations/vercel/src/edge/entrypoint.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-// NOTE(fks): Side-effect -- shim.js must run first. This isn't guaranteed by
-// the language, but it is a Node.js behavior that we rely on here. Keep this
-// separate from the other imports so that it doesn't get organized & reordered.
-import './shim.js';
-
-// Normal Imports
-import type { SSRManifest } from 'astro';
-import { App } from 'astro/app';
-
-const clientAddressSymbol = Symbol.for('astro.clientAddress');
-
-export function createExports(manifest: SSRManifest) {
- const app = new App(manifest);
-
- const handler = async (request: Request): Promise<Response> => {
- const routeData = app.match(request);
- Reflect.set(request, clientAddressSymbol, request.headers.get('x-forwarded-for'));
- const response = await app.render(request, routeData);
- if (app.setCookieHeaders) {
- for (const setCookieHeader of app.setCookieHeaders(response)) {
- response.headers.append('Set-Cookie', setCookieHeader);
- }
- }
- return response;
- };
-
- return { default: handler };
-}
diff --git a/packages/integrations/vercel/src/edge/shim.ts b/packages/integrations/vercel/src/edge/shim.ts
deleted file mode 100644
index 1a73feb39..000000000
--- a/packages/integrations/vercel/src/edge/shim.ts
+++ /dev/null
@@ -1 +0,0 @@
-process.argv = [];
diff --git a/packages/integrations/vercel/test/static-assets.test.js b/packages/integrations/vercel/test/static-assets.test.js
index c22ad5019..7f360aebc 100644
--- a/packages/integrations/vercel/test/static-assets.test.js
+++ b/packages/integrations/vercel/test/static-assets.test.js
@@ -66,19 +66,4 @@ describe('Static Assets', () => {
checkValidCacheControl(assets);
});
});
-
- describe('edge adapter', async () => {
- const adapter = await import('@astrojs/vercel/edge');
-
- it('has cache control', async () => {
- await build({ adapter });
- checkValidCacheControl();
- });
-
- it('has cache control other assets', async () => {
- const assets = '_foo';
- await build({ adapter, assets });
- checkValidCacheControl(assets);
- });
- });
});