feat(@astrojs/netlify): Add on-demand builders Netlify functions (#5874)
* Add on-demand builders option * chore: add changeset * docs: add documentation in configuration section * Update packages/integrations/netlify/README.md Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> * Update packages/integrations/netlify/README.md Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> * Update packages/integrations/netlify/README.md Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> * Update .changeset/twenty-pans-agree.md Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> --------- Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
This commit is contained in:
parent
2565bc453e
commit
1c230f1037
6 changed files with 40 additions and 7 deletions
5
.changeset/twenty-pans-agree.md
Normal file
5
.changeset/twenty-pans-agree.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@astrojs/netlify': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Add `builders` config option for Netlify On-demand Builders.
|
|
@ -117,6 +117,27 @@ And then point to the dist in your `netlify.toml`:
|
||||||
directory = "dist/functions"
|
directory = "dist/functions"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### builders
|
||||||
|
|
||||||
|
[Netlify On-demand Builders](https://docs.netlify.com/configure-builds/on-demand-builders/) are serverless functions used to build and cache page content on Netlify’s Edge CDN. You can enable these functions with the `builders` option:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// astro.config.mjs
|
||||||
|
import { defineConfig } from 'astro/config';
|
||||||
|
import netlify from '@astrojs/netlify/functions';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
output: 'server',
|
||||||
|
adapter: netlify({
|
||||||
|
builders: true
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
On-demand Builders are only available with the `@astrojs/netlify/functions` adapter and are not compatible with Edge Functions.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### binaryMediaTypes
|
### binaryMediaTypes
|
||||||
|
|
||||||
> This option is only needed for the Functions adapter and is not needed for Edge Functions.
|
> This option is only needed for the Functions adapter and is not needed for Edge Functions.
|
||||||
|
|
|
@ -163,7 +163,7 @@ export function netlifyEdgeFunctions({ dist }: NetlifyEdgeFunctionsOptions = {})
|
||||||
'astro:build:done': async ({ routes, dir }) => {
|
'astro:build:done': async ({ routes, dir }) => {
|
||||||
await bundleServerEntry(_buildConfig, _vite);
|
await bundleServerEntry(_buildConfig, _vite);
|
||||||
await createEdgeManifest(routes, entryFile, _config.root);
|
await createEdgeManifest(routes, entryFile, _config.root);
|
||||||
await createRedirects(_config, routes, dir, entryFile, true);
|
await createRedirects(_config, routes, dir, entryFile, 'edge-functions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,11 +13,13 @@ export function getAdapter(args: Args = {}): AstroAdapter {
|
||||||
|
|
||||||
interface NetlifyFunctionsOptions {
|
interface NetlifyFunctionsOptions {
|
||||||
dist?: URL;
|
dist?: URL;
|
||||||
|
builders?: boolean;
|
||||||
binaryMediaTypes?: string[];
|
binaryMediaTypes?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
function netlifyFunctions({
|
function netlifyFunctions({
|
||||||
dist,
|
dist,
|
||||||
|
builders,
|
||||||
binaryMediaTypes,
|
binaryMediaTypes,
|
||||||
}: NetlifyFunctionsOptions = {}): AstroIntegration {
|
}: NetlifyFunctionsOptions = {}): AstroIntegration {
|
||||||
let _config: AstroConfig;
|
let _config: AstroConfig;
|
||||||
|
@ -36,7 +38,7 @@ function netlifyFunctions({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
'astro:config:done': ({ config, setAdapter }) => {
|
'astro:config:done': ({ config, setAdapter }) => {
|
||||||
setAdapter(getAdapter({ binaryMediaTypes }));
|
setAdapter(getAdapter({ binaryMediaTypes, builders }));
|
||||||
_config = config;
|
_config = config;
|
||||||
entryFile = config.build.serverEntry.replace(/\.m?js/, '');
|
entryFile = config.build.serverEntry.replace(/\.m?js/, '');
|
||||||
|
|
||||||
|
@ -48,7 +50,8 @@ function netlifyFunctions({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'astro:build:done': async ({ routes, dir }) => {
|
'astro:build:done': async ({ routes, dir }) => {
|
||||||
await createRedirects(_config, routes, dir, entryFile, false);
|
const type = builders ? 'builders' : 'functions'
|
||||||
|
await createRedirects(_config, routes, dir, entryFile, type);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { polyfill } from '@astrojs/webapi';
|
import { polyfill } from '@astrojs/webapi';
|
||||||
import type { Handler } from '@netlify/functions';
|
import { builder, Handler } from '@netlify/functions';
|
||||||
import { SSRManifest } from 'astro';
|
import { SSRManifest } from 'astro';
|
||||||
import { App } from 'astro/app';
|
import { App } from 'astro/app';
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ polyfill(globalThis, {
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface Args {
|
export interface Args {
|
||||||
|
builders?: boolean;
|
||||||
binaryMediaTypes?: string[];
|
binaryMediaTypes?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +21,7 @@ const clientAddressSymbol = Symbol.for('astro.clientAddress');
|
||||||
export const createExports = (manifest: SSRManifest, args: Args) => {
|
export const createExports = (manifest: SSRManifest, args: Args) => {
|
||||||
const app = new App(manifest);
|
const app = new App(manifest);
|
||||||
|
|
||||||
|
const builders = args.builders ?? false;
|
||||||
const binaryMediaTypes = args.binaryMediaTypes ?? [];
|
const binaryMediaTypes = args.binaryMediaTypes ?? [];
|
||||||
const knownBinaryMediaTypes = new Set([
|
const knownBinaryMediaTypes = new Set([
|
||||||
'audio/3gpp',
|
'audio/3gpp',
|
||||||
|
@ -53,7 +55,7 @@ export const createExports = (manifest: SSRManifest, args: Args) => {
|
||||||
...binaryMediaTypes,
|
...binaryMediaTypes,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const handler: Handler = async (event) => {
|
const myHandler: Handler = async (event) => {
|
||||||
const { httpMethod, headers, rawUrl, body: requestBody, isBase64Encoded } = event;
|
const { httpMethod, headers, rawUrl, body: requestBody, isBase64Encoded } = event;
|
||||||
const init: RequestInit = {
|
const init: RequestInit = {
|
||||||
method: httpMethod,
|
method: httpMethod,
|
||||||
|
@ -143,6 +145,8 @@ export const createExports = (manifest: SSRManifest, args: Args) => {
|
||||||
return fnResponse;
|
return fnResponse;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handler = builders ? builder(myHandler) : myHandler
|
||||||
|
|
||||||
return { handler };
|
return { handler };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,10 @@ export async function createRedirects(
|
||||||
routes: RouteData[],
|
routes: RouteData[],
|
||||||
dir: URL,
|
dir: URL,
|
||||||
entryFile: string,
|
entryFile: string,
|
||||||
edge: boolean
|
type: 'functions' | 'edge-functions' | 'builders'
|
||||||
) {
|
) {
|
||||||
const _redirectsURL = new URL('./_redirects', dir);
|
const _redirectsURL = new URL('./_redirects', dir);
|
||||||
const kind = edge ? 'edge-functions' : 'functions';
|
const kind = type ?? 'functions';
|
||||||
|
|
||||||
const definitions: RedirectDefinition[] = [];
|
const definitions: RedirectDefinition[] = [];
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue