summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/fair-emus-divide.md39
-rw-r--r--.changeset/tricky-candles-suffer.md39
-rw-r--r--packages/astro/src/@types/astro.ts12
-rw-r--r--packages/astro/src/core/build/plugins/plugin-pages.ts6
-rw-r--r--packages/astro/src/core/build/plugins/plugin-ssr.ts26
-rw-r--r--packages/astro/src/core/config/schema.ts8
-rw-r--r--packages/astro/src/integrations/index.ts17
-rw-r--r--packages/integrations/netlify/src/integration-functions.ts12
-rw-r--r--packages/integrations/netlify/src/netlify-functions.ts2
-rw-r--r--packages/integrations/netlify/test/functions/edge-middleware.test.js1
-rw-r--r--packages/integrations/netlify/test/functions/split-support.test.js4
-rw-r--r--packages/integrations/vercel/src/serverless/adapter.ts18
-rw-r--r--packages/integrations/vercel/test/fixtures/basic/astro.config.mjs4
-rw-r--r--packages/integrations/vercel/test/fixtures/functionPerRoute/astro.config.mjs9
-rw-r--r--packages/integrations/vercel/test/fixtures/functionPerRoute/package.json9
-rw-r--r--packages/integrations/vercel/test/fixtures/functionPerRoute/src/pages/one.astro8
-rw-r--r--packages/integrations/vercel/test/fixtures/functionPerRoute/src/pages/two.astro8
-rw-r--r--packages/integrations/vercel/test/fixtures/middleware-with-edge-file/astro.config.mjs9
-rw-r--r--packages/integrations/vercel/test/fixtures/middleware-without-edge-file/astro.config.mjs9
-rw-r--r--packages/integrations/vercel/test/split.test.js5
20 files changed, 214 insertions, 31 deletions
diff --git a/.changeset/fair-emus-divide.md b/.changeset/fair-emus-divide.md
new file mode 100644
index 000000000..e8d40120b
--- /dev/null
+++ b/.changeset/fair-emus-divide.md
@@ -0,0 +1,39 @@
+---
+'astro': major
+'@astrojs/netlify': minor
+---
+
+The configuration `build.split` and `build.excludeMiddleware` are deprecated.
+
+Configuration that were inside the astro configuration, are now moved inside the adapter:
+
+```diff
+import {defineConfig} from "astro/config";
+import netlify from "@astrojs/netlify/functions";
+
+export default defineConfig({
+- build: {
+- excludeMiddleware: true
+- },
+- adapter: netlify()
++ adapter: netlify({
++ edgeMiddleware: true
++ })
+})
+```
+
+```diff
+import {defineConfig} from "astro/config";
+import netlify from "@astrojs/netlify/functions";
+
+export default defineConfig({
+- build: {
+- split: true
+- },
+- adapter: netlify()
++ adapter: netlify({
++ functionPerRoute: true
++ })
+})
+```
+
diff --git a/.changeset/tricky-candles-suffer.md b/.changeset/tricky-candles-suffer.md
new file mode 100644
index 000000000..e1f04f193
--- /dev/null
+++ b/.changeset/tricky-candles-suffer.md
@@ -0,0 +1,39 @@
+---
+'astro': major
+'@astrojs/vercel': minor
+---
+
+The configuration `build.split` and `build.excludeMiddleware` are deprecated.
+
+Configuration that were inside the astro configuration, are now moved inside the adapter:
+
+```diff
+import {defineConfig} from "astro/config";
+import vercel from "@astrojs/vercel/serverless";
+
+export default defineConfig({
+- build: {
+- excludeMiddleware: true
+- },
+- adapter: vercel()
++ adapter: vercel({
++ edgeMiddleware: true
++ })
+})
+```
+
+```diff
+import {defineConfig} from "astro/config";
+import vercel from "@astrojs/vercel/serverless";
+
+export default defineConfig({
+- build: {
+- split: true
+- },
+- adapter: vercel()
++ adapter: vercel({
++ functionPerRoute: true
++ })
+})
+```
+
diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts
index 8803cb575..eb19900d3 100644
--- a/packages/astro/src/@types/astro.ts
+++ b/packages/astro/src/@types/astro.ts
@@ -1415,6 +1415,17 @@ export interface DataEntryType {
export type GetDataEntryInfoReturnType = { data: Record<string, unknown>; rawData?: string };
+export interface AstroAdapterFeatures {
+ /**
+ * Creates and edge function that will communiate with the Astro middleware
+ */
+ edgeMiddleware: boolean;
+ /**
+ * SSR only. Each route becomes its own function/file.
+ */
+ functionPerRoute: boolean;
+}
+
export interface AstroSettings {
config: AstroConfig;
adapter: AstroAdapter | undefined;
@@ -1680,6 +1691,7 @@ export interface AstroAdapter {
previewEntrypoint?: string;
exports?: string[];
args?: any;
+ adapterFeatures?: AstroAdapterFeatures;
}
type Body = string;
diff --git a/packages/astro/src/core/build/plugins/plugin-pages.ts b/packages/astro/src/core/build/plugins/plugin-pages.ts
index 2ee438a6a..966426439 100644
--- a/packages/astro/src/core/build/plugins/plugin-pages.ts
+++ b/packages/astro/src/core/build/plugins/plugin-pages.ts
@@ -74,7 +74,11 @@ function vitePluginPages(opts: StaticBuildOptions, internals: BuildInternals): V
exports.push(`export { renderers };`);
// The middleware should not be imported by the pages
- if (!opts.settings.config.build.excludeMiddleware) {
+ if (
+ // TODO: remover in Astro 4.0
+ !opts.settings.config.build.excludeMiddleware ||
+ opts.settings.adapter?.adapterFeatures?.edgeMiddleware === true
+ ) {
const middlewareModule = await this.resolve(MIDDLEWARE_MODULE_ID);
if (middlewareModule) {
imports.push(`import { onRequest } from "${middlewareModule.id}";`);
diff --git a/packages/astro/src/core/build/plugins/plugin-ssr.ts b/packages/astro/src/core/build/plugins/plugin-ssr.ts
index 514fe2409..b1fc0e4c2 100644
--- a/packages/astro/src/core/build/plugins/plugin-ssr.ts
+++ b/packages/astro/src/core/build/plugins/plugin-ssr.ts
@@ -3,7 +3,7 @@ import { join } from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
import type { Plugin as VitePlugin } from 'vite';
import type { AstroAdapter, AstroConfig } from '../../../@types/astro';
-import { runHookBuildSsr } from '../../../integrations/index.js';
+import { isFunctionPerRouteEnabled, runHookBuildSsr } from '../../../integrations/index.js';
import { isServerLikeOutput } from '../../../prerender/utils.js';
import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from '../../../vite-plugin-scripts/index.js';
import type { SerializedRouteInfo, SerializedSSRManifest } from '../../app/types';
@@ -103,12 +103,16 @@ export function pluginSSR(
internals: BuildInternals
): AstroBuildPlugin {
const ssr = isServerLikeOutput(options.settings.config);
+ const functionPerRouteEnabled = isFunctionPerRouteEnabled(options.settings.adapter);
return {
build: 'ssr',
hooks: {
'build:before': () => {
let vitePlugin =
- ssr && !options.settings.config.build.split
+ ssr &&
+ // TODO: Remove in Astro 4.0
+ options.settings.config.build.split === false &&
+ functionPerRouteEnabled === false
? vitePluginSSR(internals, options.settings.adapter!, options)
: undefined;
@@ -122,7 +126,7 @@ export function pluginSSR(
return;
}
- if (options.settings.config.build.split) {
+ if (options.settings.config.build.split || functionPerRouteEnabled) {
return;
}
@@ -155,11 +159,12 @@ function vitePluginSSRSplit(
adapter: AstroAdapter,
options: StaticBuildOptions
): VitePlugin {
+ const functionPerRouteEnabled = isFunctionPerRouteEnabled(options.settings.adapter);
return {
name: '@astrojs/vite-plugin-astro-ssr-split',
enforce: 'post',
options(opts) {
- if (options.settings.config.build.split) {
+ if (options.settings.config.build.split || functionPerRouteEnabled) {
const inputs = new Set<string>();
for (const path of Object.keys(options.allPages)) {
@@ -229,12 +234,14 @@ export function pluginSSRSplit(
internals: BuildInternals
): AstroBuildPlugin {
const ssr = isServerLikeOutput(options.settings.config);
+ const functionPerRouteEnabled = isFunctionPerRouteEnabled(options.settings.adapter);
+
return {
build: 'ssr',
hooks: {
'build:before': () => {
let vitePlugin =
- ssr && options.settings.config.build.split
+ ssr && (options.settings.config.build.split || functionPerRouteEnabled)
? vitePluginSSRSplit(internals, options.settings.adapter!, options)
: undefined;
@@ -247,7 +254,7 @@ export function pluginSSRSplit(
if (!ssr) {
return;
}
- if (!options.settings.config.build.split) {
+ if (!options.settings.config.build.split && !functionPerRouteEnabled) {
return;
}
@@ -276,7 +283,7 @@ function generateSSRCode(config: AstroConfig, adapter: AstroAdapter) {
const imports: string[] = [];
const contents: string[] = [];
let pageMap;
- if (config.build.split) {
+ if (config.build.split || isFunctionPerRouteEnabled(adapter)) {
pageMap = 'pageModule';
} else {
pageMap = 'pageMap';
@@ -337,7 +344,10 @@ export async function createManifest(
buildOpts: StaticBuildOptions,
internals: BuildInternals
): Promise<SerializedSSRManifest> {
- if (buildOpts.settings.config.build.split) {
+ if (
+ buildOpts.settings.config.build.split ||
+ isFunctionPerRouteEnabled(buildOpts.settings.adapter)
+ ) {
if (internals.ssrSplitEntryChunks.size === 0) {
throw new Error(`Did not generate an entry chunk for SSR in serverless mode`);
}
diff --git a/packages/astro/src/core/config/schema.ts b/packages/astro/src/core/config/schema.ts
index 34c1e5549..c57f8b95a 100644
--- a/packages/astro/src/core/config/schema.ts
+++ b/packages/astro/src/core/config/schema.ts
@@ -124,7 +124,15 @@ export const AstroConfigSchema = z.object({
.optional()
.default(ASTRO_CONFIG_DEFAULTS.build.inlineStylesheets),
+ /**
+ * @deprecated
+ * Use the adapter feature instead
+ */
split: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.build.split),
+ /**
+ * @deprecated
+ * Use the adapter feature instead
+ */
excludeMiddleware: z
.boolean()
.optional()
diff --git a/packages/astro/src/integrations/index.ts b/packages/astro/src/integrations/index.ts
index d54ac3803..ab9898523 100644
--- a/packages/astro/src/integrations/index.ts
+++ b/packages/astro/src/integrations/index.ts
@@ -4,6 +4,7 @@ import type { AddressInfo } from 'node:net';
import { fileURLToPath } from 'node:url';
import type { InlineConfig, ViteDevServer } from 'vite';
import type {
+ AstroAdapter,
AstroConfig,
AstroIntegration,
AstroRenderer,
@@ -410,3 +411,19 @@ export async function runHookBuildDone({ config, pages, routes, logging }: RunHo
}
}
}
+
+export function isFunctionPerRouteEnabled(adapter: AstroAdapter | undefined): boolean {
+ if (adapter?.adapterFeatures?.functionPerRoute === true) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+export function isEdgeMiddlewareEnabled(adapter: AstroAdapter | undefined): boolean {
+ if (adapter?.adapterFeatures?.edgeMiddleware === true) {
+ return true;
+ } else {
+ return false;
+ }
+}
diff --git a/packages/integrations/netlify/src/integration-functions.ts b/packages/integrations/netlify/src/integration-functions.ts
index a950167e5..3b10e096c 100644
--- a/packages/integrations/netlify/src/integration-functions.ts
+++ b/packages/integrations/netlify/src/integration-functions.ts
@@ -8,12 +8,16 @@ import { createRedirects } from './shared.js';
export const NETLIFY_EDGE_MIDDLEWARE_FILE = 'netlify-edge-middleware';
export const ASTRO_LOCALS_HEADER = 'x-astro-locals';
-export function getAdapter(args: Args = {}): AstroAdapter {
+export function getAdapter({ functionPerRoute, edgeMiddleware, ...args }: Args): AstroAdapter {
return {
name: '@astrojs/netlify/functions',
serverEntrypoint: '@astrojs/netlify/netlify-functions.js',
exports: ['handler'],
args,
+ adapterFeatures: {
+ functionPerRoute,
+ edgeMiddleware,
+ },
};
}
@@ -21,12 +25,16 @@ interface NetlifyFunctionsOptions {
dist?: URL;
builders?: boolean;
binaryMediaTypes?: string[];
+ edgeMiddleware?: boolean;
+ functionPerRoute?: boolean;
}
function netlifyFunctions({
dist,
builders,
binaryMediaTypes,
+ functionPerRoute = false,
+ edgeMiddleware = false,
}: NetlifyFunctionsOptions = {}): AstroIntegration {
let _config: AstroConfig;
let _entryPoints: Map<RouteData, URL>;
@@ -53,7 +61,7 @@ function netlifyFunctions({
_entryPoints = entryPoints;
},
'astro:config:done': ({ config, setAdapter }) => {
- setAdapter(getAdapter({ binaryMediaTypes, builders }));
+ setAdapter(getAdapter({ binaryMediaTypes, builders, functionPerRoute, edgeMiddleware }));
_config = config;
ssrEntryFile = config.build.serverEntry.replace(/\.m?js/, '');
diff --git a/packages/integrations/netlify/src/netlify-functions.ts b/packages/integrations/netlify/src/netlify-functions.ts
index 91c4f1ef7..3da0718b0 100644
--- a/packages/integrations/netlify/src/netlify-functions.ts
+++ b/packages/integrations/netlify/src/netlify-functions.ts
@@ -9,6 +9,8 @@ applyPolyfills();
export interface Args {
builders?: boolean;
binaryMediaTypes?: string[];
+ edgeMiddleware: boolean;
+ functionPerRoute: boolean;
}
function parseContentType(header?: string) {
diff --git a/packages/integrations/netlify/test/functions/edge-middleware.test.js b/packages/integrations/netlify/test/functions/edge-middleware.test.js
index 219fd1ced..a83720a4d 100644
--- a/packages/integrations/netlify/test/functions/edge-middleware.test.js
+++ b/packages/integrations/netlify/test/functions/edge-middleware.test.js
@@ -10,6 +10,7 @@ describe('Middleware', () => {
output: 'server',
adapter: netlifyAdapter({
dist: new URL('./fixtures/middleware-with-handler-file/dist/', import.meta.url),
+ edgeMiddleware: true,
}),
site: `http://example.com`,
integrations: [testIntegration()],
diff --git a/packages/integrations/netlify/test/functions/split-support.test.js b/packages/integrations/netlify/test/functions/split-support.test.js
index 217b3c0d3..fde8b5eb1 100644
--- a/packages/integrations/netlify/test/functions/split-support.test.js
+++ b/packages/integrations/netlify/test/functions/split-support.test.js
@@ -13,6 +13,7 @@ describe('Split support', () => {
output: 'server',
adapter: netlifyAdapter({
dist: new URL('./fixtures/split-support/dist/', import.meta.url),
+ functionPerRoute: true,
}),
site: `http://example.com`,
integrations: [
@@ -22,9 +23,6 @@ describe('Split support', () => {
},
}),
],
- build: {
- split: true,
- },
});
await fixture.build();
});
diff --git a/packages/integrations/vercel/src/serverless/adapter.ts b/packages/integrations/vercel/src/serverless/adapter.ts
index 1a2f9d82a..4fd7e22a4 100644
--- a/packages/integrations/vercel/src/serverless/adapter.ts
+++ b/packages/integrations/vercel/src/serverless/adapter.ts
@@ -29,11 +29,21 @@ const SUPPORTED_NODE_VERSIONS: Record<
18: { status: 'current' },
};
-function getAdapter(): AstroAdapter {
+function getAdapter({
+ edgeMiddleware,
+ functionPerRoute,
+}: {
+ edgeMiddleware: boolean;
+ functionPerRoute: boolean;
+}): AstroAdapter {
return {
name: PACKAGE_NAME,
serverEntrypoint: `${PACKAGE_NAME}/entrypoint`,
exports: ['default'],
+ adapterFeatures: {
+ edgeMiddleware,
+ functionPerRoute,
+ },
};
}
@@ -43,6 +53,8 @@ export interface VercelServerlessConfig {
analytics?: boolean;
imageService?: boolean;
imagesConfig?: VercelImageConfig;
+ edgeMiddleware?: boolean;
+ functionPerRoute?: boolean;
}
export default function vercelServerless({
@@ -51,6 +63,8 @@ export default function vercelServerless({
analytics,
imageService,
imagesConfig,
+ functionPerRoute = false,
+ edgeMiddleware = false,
}: VercelServerlessConfig = {}): AstroIntegration {
let _config: AstroConfig;
let buildTempFolder: URL;
@@ -112,7 +126,7 @@ export default function vercelServerless({
},
'astro:config:done': ({ setAdapter, config }) => {
throwIfAssetsNotEnabled(config, imageService);
- setAdapter(getAdapter());
+ setAdapter(getAdapter({ functionPerRoute, edgeMiddleware }));
_config = config;
buildTempFolder = config.build.server;
serverEntry = config.build.serverEntry;
diff --git a/packages/integrations/vercel/test/fixtures/basic/astro.config.mjs b/packages/integrations/vercel/test/fixtures/basic/astro.config.mjs
index 664b64d56..6e2e304d9 100644
--- a/packages/integrations/vercel/test/fixtures/basic/astro.config.mjs
+++ b/packages/integrations/vercel/test/fixtures/basic/astro.config.mjs
@@ -2,5 +2,7 @@ import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';
export default defineConfig({
- adapter: vercel()
+ adapter: vercel({
+ functionPerRoute: true
+ })
});
diff --git a/packages/integrations/vercel/test/fixtures/functionPerRoute/astro.config.mjs b/packages/integrations/vercel/test/fixtures/functionPerRoute/astro.config.mjs
new file mode 100644
index 000000000..fefc69a83
--- /dev/null
+++ b/packages/integrations/vercel/test/fixtures/functionPerRoute/astro.config.mjs
@@ -0,0 +1,9 @@
+import { defineConfig } from 'astro/config';
+import vercel from '@astrojs/vercel/serverless';
+
+export default defineConfig({
+ adapter: vercel({
+ functionPerRoute: true
+ }),
+ output: "server"
+});
diff --git a/packages/integrations/vercel/test/fixtures/functionPerRoute/package.json b/packages/integrations/vercel/test/fixtures/functionPerRoute/package.json
new file mode 100644
index 000000000..e33f178bb
--- /dev/null
+++ b/packages/integrations/vercel/test/fixtures/functionPerRoute/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/astro-vercel-function-per-route",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/vercel": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/vercel/test/fixtures/functionPerRoute/src/pages/one.astro b/packages/integrations/vercel/test/fixtures/functionPerRoute/src/pages/one.astro
new file mode 100644
index 000000000..0c7fb90a7
--- /dev/null
+++ b/packages/integrations/vercel/test/fixtures/functionPerRoute/src/pages/one.astro
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <title>One</title>
+ </head>
+ <body>
+ <h1>One</h1>
+ </body>
+</html>
diff --git a/packages/integrations/vercel/test/fixtures/functionPerRoute/src/pages/two.astro b/packages/integrations/vercel/test/fixtures/functionPerRoute/src/pages/two.astro
new file mode 100644
index 000000000..e7ba9910e
--- /dev/null
+++ b/packages/integrations/vercel/test/fixtures/functionPerRoute/src/pages/two.astro
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <title>Two</title>
+ </head>
+ <body>
+ <h1>Two</h1>
+ </body>
+</html>
diff --git a/packages/integrations/vercel/test/fixtures/middleware-with-edge-file/astro.config.mjs b/packages/integrations/vercel/test/fixtures/middleware-with-edge-file/astro.config.mjs
index 321a8bde3..33910b50a 100644
--- a/packages/integrations/vercel/test/fixtures/middleware-with-edge-file/astro.config.mjs
+++ b/packages/integrations/vercel/test/fixtures/middleware-with-edge-file/astro.config.mjs
@@ -2,9 +2,8 @@ import {defineConfig} from "astro/config";
import vercel from "@astrojs/vercel/serverless";
export default defineConfig({
- adapter: vercel(),
- build: {
- excludeMiddleware: true
- },
+ adapter: vercel({
+ edgeMiddleware: true
+ }),
output: 'server'
-}); \ No newline at end of file
+});
diff --git a/packages/integrations/vercel/test/fixtures/middleware-without-edge-file/astro.config.mjs b/packages/integrations/vercel/test/fixtures/middleware-without-edge-file/astro.config.mjs
index 321a8bde3..33910b50a 100644
--- a/packages/integrations/vercel/test/fixtures/middleware-without-edge-file/astro.config.mjs
+++ b/packages/integrations/vercel/test/fixtures/middleware-without-edge-file/astro.config.mjs
@@ -2,9 +2,8 @@ import {defineConfig} from "astro/config";
import vercel from "@astrojs/vercel/serverless";
export default defineConfig({
- adapter: vercel(),
- build: {
- excludeMiddleware: true
- },
+ adapter: vercel({
+ edgeMiddleware: true
+ }),
output: 'server'
-}); \ No newline at end of file
+});
diff --git a/packages/integrations/vercel/test/split.test.js b/packages/integrations/vercel/test/split.test.js
index 9044954f2..85affb3ff 100644
--- a/packages/integrations/vercel/test/split.test.js
+++ b/packages/integrations/vercel/test/split.test.js
@@ -7,11 +7,8 @@ describe('build: split', () => {
before(async () => {
fixture = await loadFixture({
- root: './fixtures/basic/',
+ root: './fixtures/functionPerRoute/',
output: 'server',
- build: {
- split: true,
- },
});
await fixture.build();
});