From ea80c14a3ea84a7431930b1b42919d8184fbe0dd Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Mon, 21 Aug 2023 13:53:55 +0100 Subject: [PATCH 1/5] feat: document adapter features (#3917) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Elian ☕️ Co-authored-by: Sarah Rainsberger --- .../docs/en/reference/adapter-reference.mdx | 190 +++++++++++++++--- 1 file changed, 163 insertions(+), 27 deletions(-) diff --git a/src/content/docs/en/reference/adapter-reference.mdx b/src/content/docs/en/reference/adapter-reference.mdx index 54974665714f2..d059d5ccfbca7 100644 --- a/src/content/docs/en/reference/adapter-reference.mdx +++ b/src/content/docs/en/reference/adapter-reference.mdx @@ -43,44 +43,58 @@ The object passed into `setAdapter` is defined as: ```ts interface AstroAdapter { - name: string; - serverEntrypoint?: string; - exports?: string[]; + name: string; + serverEntrypoint?: string; + exports?: string[]; + adapterFeatures: AstroAdapterFeatures; supportedAstroFeatures: AstroFeatureMap; -} -export type SupportsKind = 'unsupported' | 'stable' | 'experimental' | 'deprecated'; +} -export type AstroFeatureMap = { - /** - * The adapter is able to serve static pages - */ - staticOutput?: SupportsKind; +export interface AstroAdapterFeatures { /** - * The adapter is able to serve pages that are static or rendered via server + * Creates an edge function that will communicate with the Astro middleware. */ - hybridOutput?: SupportsKind; + edgeMiddleware: boolean; /** - * The adapter is able to serve SSR pages + * SSR only. Each route becomes its own function/file. */ - serverOutput?: SupportsKind; - /** - * The adapter can emit static assets - */ - assets?: AstroAssetsFeature; + functionPerRoute: boolean; +} + +export type SupportsKind = 'unsupported' | 'stable' | 'experimental' | 'deprecated'; + +export type AstroFeatureMap = { + /** + * The adapter is able to serve static pages + */ + staticOutput?: SupportsKind; + /** + * The adapter is able to serve pages that are static or rendered via server + */ + hybridOutput?: SupportsKind; + /** + * The adapter is able to serve SSR pages + */ + serverOutput?: SupportsKind; + /** + * The adapter can emit static assets + */ + assets?: AstroAssetsFeature; }; export interface AstroAssetsFeature { - supportKind?: SupportsKind; - /** - * Whether or not this adapter deploys files in an environment that is compatible with the library `sharp` - */ - isSharpCompatible?: boolean; - /** - * Whether or not this adapter deploys files in an environment that is compatible with the library `squoosh` - */ - isSquooshCompatible?: boolean; + supportKind?: SupportsKind; + /** + * Whether this adapter deploys files in an environment that is compatible with the library `sharp` + */ + isSharpCompatible?: boolean; + /** + * Whether this adapter deploys files in an environment that is compatible with the library `squoosh` + */ + isSquooshCompatible?: boolean; } + ``` The properties are: @@ -88,6 +102,8 @@ The properties are: * __name__: A unique name for your adapter, used for logging. * __serverEntrypoint__: The entrypoint for server-side rendering. * __exports__: An array of named exports when used in conjunction with `createExports` (explained below). +* __adapterFeatures__: An object that enables specific features that must be supported by the adapter. + These features will change the built output, and the adapter must implement the proper logic to handle the different output. * __supportedAstroFeatures__: A map of Astro built-in features. This allows Astro to determine which features an adapter is unable or unwilling to support so appropriate error messages can be provided. ### Server Entrypoint @@ -278,3 +294,123 @@ and an error if the service used for assets is not compatible with the adapter: ``` [@matthewp/my-adapter] The currently selected adapter `@matthewp/my-adapter` is not compatible with the service "Sharp". Your project will NOT be able to build. ``` + +## Adapter features + +A set of features that changes the output of the emitted files. When an adapter opts in to these features, they will get additional information inside specific hooks. + +### `functionPerRoute` + +This is a feature that is enabled when using SSR only. By default, Astro emits a single `entry.mjs` file, which is responsible for emitting the rendered page on each request. + +When `functionPerRoute` is `true`, Astro will instead create a separate file for each route defined in the project. +Each file emitted will only render one page. The pages will be emitted inside a `dist/pages/` directory, and the emitted files will keep the same file paths of the `src/pages/` directory. + +Enable the feature by passing `true` to the adapter. + +```js title="my-adapter.mjs" ins={9-11} +export default function createIntegration() { + return { + name: '@matthewp/my-adapter', + hooks: { + 'astro:config:done': ({ setAdapter }) => { + setAdapter({ + name: '@matthewp/my-adapter', + serverEntrypoint: '@matthewp/my-adapter/server.js', + adapterFeatures: { + functionPerRoute: true + } + }); + }, + }, + }; +} +``` + +Then, consume the hook [`astro:build:ssr`](/en/reference/integrations-reference/#astrobuildssr), which will give you an `entryPoints` object that maps a page route to the physical file emitted after the build. + +```js title="my-adapter.mjs" ins={15-19} +export default function createIntegration() { + return { + name: '@matthewp/my-adapter', + hooks: { + 'astro:config:done': ({ setAdapter }) => { + setAdapter({ + name: '@matthewp/my-adapter', + serverEntrypoint: '@matthewp/my-adapter/server.js', + adapterFeatures: { + functionPerRoute: true + } + }); + }, + + 'astro:build:ssr': ({ entryPoints }) => { + for (const [route, entryFile] of entryPoints) { + // do something with route and entryFile + } + } + }, + }; +} +``` + +:::caution +The `entryFile` is of type `URL` and represents the physical path of the file in the file system. This means that the paths change based on the OS where the code runs. +::: + +### `edgeMiddleware` + +Defines whether any SSR middleware code will be bundled when built. + +When enabled, this prevents middleware code from being bundled and imported by all pages during the build: + +```js title="my-adapter.mjs" ins={9-11} +export default function createIntegration() { + return { + name: '@matthewp/my-adapter', + hooks: { + 'astro:config:done': ({ setAdapter }) => { + setAdapter({ + name: '@matthewp/my-adapter', + serverEntrypoint: '@matthewp/my-adapter/server.js', + adapterFeatures: { + edgeMiddleware: true + } + }); + }, + }, + }; +} +``` + +Then, consume the hook [`astro:build:ssr`](/en/reference/integrations-reference/#astrobuildssr), which will give you a `middlewareEntryPoint`, an `URL` to the physical file on the file system. + +```js title="my-adapter.mjs" ins={15-19} +export default function createIntegration() { + return { + name: '@matthewp/my-adapter', + hooks: { + 'astro:config:done': ({ setAdapter }) => { + setAdapter({ + name: '@matthewp/my-adapter', + serverEntrypoint: '@matthewp/my-adapter/server.js', + adapterFeatures: { + edgeMiddleware: true + } + }); + }, + + 'astro:build:ssr': ({ middlewareEntryPoint }) => { + // remember to check if this property exits, it will be `undefined` if the adapter doesn't opt in to the feature + if (middlewareEntryPoint) { + createEdgeMiddleware(middlewareEntryPoint) + } + } + }, + }; +} + +function createEdgeMiddleware(middlewareEntryPoint) { + // emit a new physical file using your bundler +} +``` From e58d9d9b392e44b94ed8663ea5f19cd7bdb8db65 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 21 Aug 2023 15:29:55 +0100 Subject: [PATCH 2/5] Update capitalisation of GET --- src/content/docs/en/guides/integrations-guide/cloudflare.mdx | 2 +- src/content/docs/en/guides/integrations-guide/netlify.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/docs/en/guides/integrations-guide/cloudflare.mdx b/src/content/docs/en/guides/integrations-guide/cloudflare.mdx index 0d5d4b4cf0dfa..5ca718d01f493 100644 --- a/src/content/docs/en/guides/integrations-guide/cloudflare.mdx +++ b/src/content/docs/en/guides/integrations-guide/cloudflare.mdx @@ -109,7 +109,7 @@ See Cloudflare's documentation for [working with environment variables](https:// ```js // pages/[id].json.js -export function get({ params }) { +export function GET({ params }) { // Access environment variables per request inside a function const serverUrl = import.meta.env.SERVER_URL; const result = await fetch(serverUrl + "/user/" + params.id); diff --git a/src/content/docs/en/guides/integrations-guide/netlify.mdx b/src/content/docs/en/guides/integrations-guide/netlify.mdx index bd5e6fd987ec5..7cd84245495bf 100644 --- a/src/content/docs/en/guides/integrations-guide/netlify.mdx +++ b/src/content/docs/en/guides/integrations-guide/netlify.mdx @@ -274,7 +274,7 @@ We check for common mime types for audio, image, and video files. To include spe import fs from 'node:fs'; -export function get() { +export function GET() { const buffer = fs.readFileSync('../image.jpg'); // Return the buffer directly, @astrojs/netlify will base64 encode the body From 873d99c93911092080a1c2788a6d249decbec4de Mon Sep 17 00:00:00 2001 From: Sarah Rainsberger Date: Mon, 21 Aug 2023 16:56:59 -0300 Subject: [PATCH 3/5] Apply suggestions from EVERYONE's code review! Co-authored-by: Yan Thomas <61414485+Yan-Thomas@users.noreply.github.com> Co-authored-by: Kevin Zuniga Cuellar <46791833+kevinzunigacuellar@users.noreply.github.com> Co-authored-by: Bjorn Lu Co-authored-by: Erika <3019731+Princesseuh@users.noreply.github.com> Co-authored-by: Shinya Fujino --- src/content/docs/en/guides/upgrade-to/v3.mdx | 50 ++++++++++---------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/content/docs/en/guides/upgrade-to/v3.mdx b/src/content/docs/en/guides/upgrade-to/v3.mdx index 8369d51831045..dba1ae50cd648 100644 --- a/src/content/docs/en/guides/upgrade-to/v3.mdx +++ b/src/content/docs/en/guides/upgrade-to/v3.mdx @@ -80,11 +80,11 @@ See [the changelog](https://github.com/withastro/astro/blob/main/packages/astro/ Node 16 is scheduled to reach its End of Life in September 2023. -Astro v3.0 drops Node 16 support entirely, so that all Astro users can take advantage of Node's more modern features. +Astro v3.0 drops Node 16 support entirely so that all Astro users can take advantage of Node's more modern features. #### What should I do? - Check that both your development environment and your deployment environment are using **Node `18.14.1` or later**. + Check that both your development environment and your deployment environment are using **Node `18.14.1` or higher**. 1. Check your local version of Node using: @@ -92,13 +92,15 @@ Astro v3.0 drops Node 16 support entirely, so that all Astro users can take adva node -v ``` - If your local development environment needs upgrading, [install Node](https://nodejs.org/en/download/). 2. Check your [deployment environment's](/en/guides/deploy/) own documentation to verify that they support Node 18. - You can specify Node `18.14.1` for your Astro project either in a dashboard configuration setting, or a `.nvmrc` file. + You can specify Node `18.14.1` for your Astro project either in a dashboard configuration setting or a `.nvmrc` file. +```bash title=".nvmrc" +18.14.1 +``` ### Removed: Support for TypeScript 4 In Astro v2.x, the `tsconfig.json` presets include support for both TypeScript 4.x and 5.x. @@ -121,7 +123,7 @@ Astro v3.0 removes this integration from the codebase entirely. Astro's new solu #### What should I do? -Remove the `@astrojs/image` integration from your project. You will need to not only uninstall the integration, but also update or remove any import statements and existing `` and `` components. You might also need to configure a preferred default image processing service. +Remove the `@astrojs/image` integration from your project. You will need to not only uninstall the integration but also update or remove any import statements and existing `` and `` components. You might also need to configure a preferred default image processing service. You will find [complete, step-by-step instructions for removing the old image integration](/en/guides/images/#remove-astrojsimage) in our Images guide. @@ -141,7 +143,7 @@ export default defineConfig({ ### Removed: `` component -In Astro v2.x, Astro deprecated the `` component and moved it to an external package. +In Astro v1.x, Astro deprecated the `` component and moved it to an external package. Astro v3.0 completely removes the package `@astrojs/markdown-component`. Astro's `` component will no longer work in your project. @@ -277,7 +279,7 @@ If you were relying on Astro to transform kebab-case in your styles, update your Do we want an example of returning an array of an array, requiring flattening? ::: -In Astro v2.x, the return value of [`getStaticPaths()`](/en/reference/api-reference/#getstaticpaths) was automatically flattened to allow you to return an array of array without errors. +In Astro v2.x, the return value of [`getStaticPaths()`](/en/reference/api-reference/#getstaticpaths) was automatically flattened to allow you to return an array of arrays without errors. Astro v3.0 removes automatic flattening of `getStaticPaths()`'s result. @@ -287,9 +289,9 @@ If you're returning an array of arrays instead of an array of _objects_ (as is e An [error message indicating that `getStaticPath()`'s return value must be an array of objects](/en/reference/errors/invalid-get-static-paths-entry/#what-went-wrong) will be provided if you need to update your code. -### Moved: `astro check` is now an external package +### Moved: `astro check` now requires an external package -In Astro v2.x, [`astro check`](/en/reference/cli-reference/#astro-check) was included in Astro by default and its dependencies were bundled in Astro. This meant a larger package whether or not you ever used `astro check`. This also prevented you from having control over the version of TypeScript and the Astro Language Server to use. +In Astro v2.x, [`astro check`](/en/reference/cli-reference/#astro-check) was included in Astro by default, and its dependencies were bundled in Astro. This meant a larger package whether or not you ever used `astro check`. This also prevented you from having control over the version of TypeScript and the Astro Language Server to use. Astro v3.0 moves the `astro check` command out of Astro core and now requires an external package `@astrojs/check`. Additionally, you must install `typescript` in your project to use the `astro check` command. @@ -311,7 +313,7 @@ Update any existing references to `localhost:3000`, for example in tests or in y ### Changed default: import.meta.env.BASE_URL `trailingSlash` -In Astro v2.x, `import.meta.env.BASE_URL` appended your [`base`](/en/reference/configuration-reference/#base) setting with a [trailingSlash](/en/reference/configuration-reference/#trailingslash) by default. `trailingSlash: "ignore"`also appended a trailing slash. +In Astro v2.x, `import.meta.env.BASE_URL` appended your [`base`](/en/reference/configuration-reference/#base) setting with a [trailingSlash](/en/reference/configuration-reference/#trailingslash) by default. `trailingSlash: "ignore"` also appended a trailing slash. Astro v3.0 no longer appends `import.meta.env.BASE_URL` with a trailing slash by default, nor when `trailingSlash: "ignore"` is set. (The existing behavior of `base` in combination with `trailingSlash: "always"` or `trailingSlash: "never"` is unchanged.) @@ -319,7 +321,7 @@ Astro v3.0 no longer appends `import.meta.env.BASE_URL` with a trailing slash by If your `base` already has a trailing slash, no change is needed. -If your `base` does not have a trailing slash, add one if you wish to preserve the previous default (or `trailingSlash: "ignore"`) behaviour: +If your `base` does not have a trailing slash, add one if you wish to preserve the previous default (or `trailingSlash: "ignore"`) behavior: ```js title="astro.config.mjs" del={4} ins={5} import { defineConfig } from "astro/config"; @@ -371,7 +373,7 @@ export default defineConfig({ ### Changed default: `inlineStyleSheets` -In Astro v2.x, all project stylesheets were sent as link tags by default. You could opt in to `"always"` inlining them into `