Skip to content

Commit

Permalink
refactor(vercel): Build Output API v3 (#3216)
Browse files Browse the repository at this point in the history
* Removed ignores

* Migration to v3

* More changes

* Remove legacy redirects

* Fail when there is no ENABLE_VC_BUILD

* Fix edge

* Updated readme

* Changeset

* Added static mode

* Updated documentation

* Updated shim

* Made edge work!

* Updated changeset

* Ensure empty dir

* Fixed redirects for dynamic paths

* Removed extra declaration

* Splited imports

* Updated readme

* Fixed some urls

* Deprecated shim!

* [test]: Vercel NFT

* Beautify

* Edge bundle to node 14.19

Vercel runs 14.19.1 (I've checked it manually)

* Re-added shim (#3304)

* Added `node:` prefix

* Use the same bundling as Deno for Edge

* Remove esbuild

* Fixed shim

* Moved nft

* Updated changeset

* Added note about Edge

* fix typo

* Added support for Node 16 (vercel/vercel#7772)
  • Loading branch information
JuanM04 authored May 11, 2022
1 parent 46cd8b9 commit 114bf63
Show file tree
Hide file tree
Showing 42 changed files with 659 additions and 231 deletions.
20 changes: 20 additions & 0 deletions .changeset/tiny-apes-shave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
'@astrojs/vercel': minor
---


**[BREAKING]** Now with Build Output API (v3)! [See the README to get started](https://github.com/withastro/astro/tree/main/packages/integrations/vercel#readme).

- `trailingSlash` redirects works without a `vercel.json` file: just configure them inside your `astro.config.mjs`
- Multiple deploy targets: `edge`, `serverless` and `static`!
- When building to `serverless`, your code isn't transpiled to CJS anymore.

**Migrate from v0.1**

1. Change the import inside `astro.config.mjs`:
```diff
- import vercel from '@astrojs/vercel';
+ import vercel from '@astrojs/vercel/serverless';
```
2. Rename the `ENABLE_FILE_SYSTEM_API` environment variable to `ENABLE_VC_BUILD`, as Vercel changed it.
3. The output folder changed from `.output` to `.vercel/output` — you may need to update your `.gitignore`.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
node_modules/
dist/
.output/
*.tsbuildinfo
.DS_Store
.vercel
Expand Down
1 change: 0 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

# Deep Directories
**/dist
**/.output
**/smoke
**/node_modules
**/fixtures
Expand Down
1 change: 0 additions & 1 deletion examples/blog-multiple-authors/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/blog/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/component/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/docs/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/env-vars/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/framework-alpine/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/framework-lit/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/framework-multiple/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/framework-preact/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/framework-react/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/framework-solid/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/framework-svelte/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/framework-vue/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/integrations-playground/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/minimal/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/non-html-pages/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/portfolio/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/starter/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/subpath/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/with-markdown-plugins/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/with-markdown-shiki/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/with-markdown/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/with-nanostores/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/with-tailwindcss/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
1 change: 0 additions & 1 deletion examples/with-vite-plugin-pwa/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# build output
dist/
.output/

# dependencies
node_modules/
Expand Down
49 changes: 41 additions & 8 deletions packages/integrations/vercel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,71 @@ Use this integration in your Astro configuration file:

```js
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel';
import vercel from '@astrojs/vercel/serverless';

export default defineConfig({
adapter: vercel()
});
```

When you build your project, Astro will know to use the `.output` folder format that Vercel expects.
When you build your project, Astro will know to use the `.vercel/output` folder format that Vercel expects.

```
astro build
```
## Deploying

That's it! You can deploy by CLI (`vercel deploy`) or by connecting your new repo in the [Vercel Dashboard](https://vercel.com/).
You can deploy by CLI (`vercel deploy`) or by connecting your new repo in the [Vercel Dashboard](https://vercel.com/). Alternatively, you can create a production build locally:

```sh
ENABLE_VC_BUILD=1 astro build
vercel deploy --prebuilt
```

## Requirements

**Vercel's [File System API](https://vercel.com/docs/file-system-api/v2) must be enabled.** You must enable it yourself by setting the environment variable: `ENABLE_FILE_SYSTEM_API=1`.
**Vercel's [Build Output API](https://vercel.com/docs/build-output-api/v3) must be enabled.** You must enable it yourself by setting the environment variable: `ENABLE_VC_BUILD=1`.

```js
// vercel.json
{
"build": {
"env": {
"ENABLE_FILE_SYSTEM_API": "1"
"ENABLE_VC_BUILD": "1"
}
}
}
```

[Learn more about setting enviroment variables in Vercel](https://vercel.com/docs/concepts/projects/environment-variables).

## Targets

You can deploy to different targes:

- `edge`: SSR inside a [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) — they 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';
```

### Node.js version

When deploying to `serverless` you can choose what version of Node.js you want to target: `12.x`, `14.x` or `16.x` (default).

```js
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';

export default defineConfig({
adapter: vercel({ nodeVersion: '14.x' })
});
```

## Limitations

Expand Down
9 changes: 6 additions & 3 deletions packages/integrations/vercel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@
"bugs": "https://github.com/withastro/astro/issues",
"homepage": "https://astro.build",
"exports": {
".": "./dist/index.js",
"./server-entrypoint": "./dist/server-entrypoint.js",
"./edge": "./dist/edge/adapter.js",
"./edge/entrypoint": "./dist/edge/entrypoint.js",
"./serverless": "./dist/serverless/adapter.js",
"./serverless/entrypoint": "./dist/serverless/entrypoint.js",
"./static": "./dist/serverless/adapter.js",
"./package.json": "./package.json"
},
"scripts": {
Expand All @@ -25,7 +28,7 @@
},
"dependencies": {
"@astrojs/webapi": "^0.11.1",
"esbuild": "^0.14.38"
"@vercel/nft": "^0.18.2"
},
"devDependencies": {
"astro": "workspace:*",
Expand Down
74 changes: 74 additions & 0 deletions packages/integrations/vercel/src/edge/adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import type { AstroAdapter, AstroConfig, AstroIntegration } from 'astro';

import { writeJson, getVercelOutput } 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'],
};
}

export default function vercelEdge(): AstroIntegration {
let _config: AstroConfig;
let functionFolder: URL;
let serverEntry: string;

return {
name: PACKAGE_NAME,
hooks: {
'astro:config:setup': ({ config }) => {
config.outDir = getVercelOutput(config.root);
},
'astro:config:done': ({ setAdapter, config }) => {
setAdapter(getAdapter());
_config = config;
},
'astro:build:setup': ({ vite, target }) => {
if (target === 'server') {
vite.resolve ||= {};
vite.resolve.alias ||= {};
const alias = vite.resolve.alias as Record<string, string>;
alias['react-dom/server'] = 'react-dom/server.browser';
vite.ssr = {
noExternal: true,
};
}
},
'astro:build:start': async ({ buildConfig }) => {
if (String(process.env.ENABLE_VC_BUILD) !== '1') {
throw new Error(
`The enviroment variable "ENABLE_VC_BUILD" was not found. Make sure you have it set to "1" in your Vercel project.\nLearn how to set enviroment variables here: https://vercel.com/docs/concepts/projects/environment-variables`
);
}

buildConfig.serverEntry = serverEntry = 'entry.mjs';
buildConfig.client = new URL('./static/', _config.outDir);
buildConfig.server = functionFolder = new URL('./functions/render.func/', _config.outDir);
},
'astro:build:done': async ({ routes }) => {
// 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: serverEntry,
});

// 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),
{ handle: 'filesystem' },
{ src: '/.*', middlewarePath: 'render' },
],
});
},
},
};
}
Loading

0 comments on commit 114bf63

Please sign in to comment.