From d8132626b05f150341c0628d6078fdd86b89aaed Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Thu, 12 Sep 2024 11:34:11 -0400 Subject: [PATCH] Unflag Server Islands (#11955) * Unflag Server Islands * update example * Add changeset * Only append serverIslands route if there is one * Update .changeset/strange-sheep-film.md Co-authored-by: Sarah Rainsberger * check buildoutput instead * Update packages/astro/src/core/errors/errors-data.ts Co-authored-by: Erika <3019731+Princesseuh@users.noreply.github.com> * remove flag --------- Co-authored-by: Sarah Rainsberger Co-authored-by: Erika <3019731+Princesseuh@users.noreply.github.com> --- .changeset/strange-sheep-film.md | 40 +++++++++++++++++++ examples/server-islands/astro.config.mjs | 3 -- .../server-islands-key/astro.config.mjs | 3 -- .../fixtures/server-islands/astro.config.mjs | 3 -- packages/astro/src/core/build/index.ts | 13 +++--- .../src/core/build/plugins/plugin-ssr.ts | 5 +-- packages/astro/src/core/config/schema.ts | 5 --- packages/astro/src/core/create-vite.ts | 2 +- packages/astro/src/core/errors/errors-data.ts | 13 ++++++ .../server-islands/hybrid/astro.config.mjs | 3 -- .../server-islands/ssr/astro.config.mjs | 3 -- packages/astro/test/server-islands.test.js | 18 ++++++++- 12 files changed, 79 insertions(+), 32 deletions(-) create mode 100644 .changeset/strange-sheep-film.md diff --git a/.changeset/strange-sheep-film.md b/.changeset/strange-sheep-film.md new file mode 100644 index 0000000000..dc55ad03af --- /dev/null +++ b/.changeset/strange-sheep-film.md @@ -0,0 +1,40 @@ +--- +'astro': minor +--- + +[Server Islands](https://astro.build/blog/future-of-astro-server-islands/) introduced behind an experimental flag in [v4.12.0](https://github.com/withastro/astro/blob/main/packages/astro/CHANGELOG.md#4120) is no longer experimental and is available for general use. + +Server islands are Astro's solution for highly cacheable pages of mixed static and dynamic content. They allow you to specify components that should run on the server, allowing the rest of the page to be more aggressively cached, or even generated statically. + +Turn any `.astro` component into a server island by adding the `server:defer` directive and optionally, fallback placeholder content. It will be rendered dynamically at runtime outside the context of the rest of the page, allowing you to add longer cache headers for the pages, or even prerender them. + +```astro +--- +import Avatar from '../components/Avatar.astro'; +import GenericUser from '../components/GenericUser.astro'; +--- +
+

Page Title

+
+ + + +
+
+``` + +If you were previously using this feature, please remove the experimental flag from your Astro config: + +```diff +import { defineConfig } from 'astro/config'; + +export default defineConfig({ + experimental { +- serverIslands: true, + }, +}); +``` + +If you have been waiting for stabilization before using server islands, you can now do so. + +Please see the [server island documentation](https://docs.astro.build/en/guides/server-islands/) for more about this feature. diff --git a/examples/server-islands/astro.config.mjs b/examples/server-islands/astro.config.mjs index c0d6b918a5..ef62b52077 100644 --- a/examples/server-islands/astro.config.mjs +++ b/examples/server-islands/astro.config.mjs @@ -12,7 +12,4 @@ export default defineConfig({ tailwind({ applyBaseStyles: false }) ], devToolbar: { enabled: false }, - experimental: { - serverIslands: true, - } }); diff --git a/packages/astro/e2e/fixtures/server-islands-key/astro.config.mjs b/packages/astro/e2e/fixtures/server-islands-key/astro.config.mjs index db1a7b4524..b6b0d1b113 100644 --- a/packages/astro/e2e/fixtures/server-islands-key/astro.config.mjs +++ b/packages/astro/e2e/fixtures/server-islands-key/astro.config.mjs @@ -6,7 +6,4 @@ export default defineConfig({ output: 'server', adapter: node({ mode: 'standalone' }), integrations: [], - experimental: { - serverIslands: true, - } }); diff --git a/packages/astro/e2e/fixtures/server-islands/astro.config.mjs b/packages/astro/e2e/fixtures/server-islands/astro.config.mjs index 6b3c2a146e..6b3e596c4c 100644 --- a/packages/astro/e2e/fixtures/server-islands/astro.config.mjs +++ b/packages/astro/e2e/fixtures/server-islands/astro.config.mjs @@ -10,7 +10,4 @@ export default defineConfig({ adapter: nodejs({ mode: 'standalone' }), integrations: [react(), mdx()], trailingSlash: process.env.TRAILING_SLASH ?? 'always', - experimental: { - serverIslands: true, - } }); diff --git a/packages/astro/src/core/build/index.ts b/packages/astro/src/core/build/index.ts index 440ed6028f..c420e85c41 100644 --- a/packages/astro/src/core/build/index.ts +++ b/packages/astro/src/core/build/index.ts @@ -210,6 +210,13 @@ class AstroBuilder { }; const { internals, ssrOutputChunkNames, contentFileNames } = await viteBuild(opts); + + const hasServerIslands = this.settings.serverIslandNameMap.size > 0; + // Error if there are server islands but no adapter provided. + if(hasServerIslands && this.settings.buildOutput !== 'server') { + throw new AstroError(AstroErrorData.NoAdapterInstalledServerIslands); + } + await staticBuild(opts, internals, ssrOutputChunkNames, contentFileNames); // Write any additionally generated assets to disk. @@ -230,11 +237,7 @@ class AstroBuilder { routes: Object.values(allPages) .flat() .map((pageData) => pageData.route) - .concat( - this.settings.config.experimental.serverIslands - ? [getServerIslandRouteData(this.settings.config)] - : [], - ), + .concat(hasServerIslands ? getServerIslandRouteData(this.settings.config) : []), logging: this.logger, cacheManifest: internals.cacheManifestUsed, }); diff --git a/packages/astro/src/core/build/plugins/plugin-ssr.ts b/packages/astro/src/core/build/plugins/plugin-ssr.ts index 3ddd1d1274..dab617d82f 100644 --- a/packages/astro/src/core/build/plugins/plugin-ssr.ts +++ b/packages/astro/src/core/build/plugins/plugin-ssr.ts @@ -171,13 +171,10 @@ function generateSSRCode(settings: AstroSettings, adapter: AstroAdapter, middlew `import * as serverEntrypointModule from '${ADAPTER_VIRTUAL_MODULE_ID}';`, `import { manifest as defaultManifest } from '${SSR_MANIFEST_VIRTUAL_MODULE_ID}';`, edgeMiddleware ? `` : `import { onRequest as middleware } from '${middlewareId}';`, - settings.config.experimental.serverIslands - ? `import { serverIslandMap } from '${VIRTUAL_ISLAND_MAP_ID}';` - : '', + `import { serverIslandMap } from '${VIRTUAL_ISLAND_MAP_ID}';`, ]; const contents = [ - settings.config.experimental.serverIslands ? '' : `const serverIslandMap = new Map()`, edgeMiddleware ? `const middleware = (_, next) => next()` : '', `const _manifest = Object.assign(defaultManifest, {`, ` pageMap,`, diff --git a/packages/astro/src/core/config/schema.ts b/packages/astro/src/core/config/schema.ts index 924c10f8fa..b89af4f46c 100644 --- a/packages/astro/src/core/config/schema.ts +++ b/packages/astro/src/core/config/schema.ts @@ -92,7 +92,6 @@ export const ASTRO_CONFIG_DEFAULTS = { experimental: { contentCollectionCache: false, clientPrerender: false, - serverIslands: false, contentIntellisense: false, }, } satisfies AstroUserConfig & { server: { open: boolean } }; @@ -530,10 +529,6 @@ export const AstroConfigSchema = z.object({ .boolean() .optional() .default(ASTRO_CONFIG_DEFAULTS.experimental.clientPrerender), - serverIslands: z - .boolean() - .optional() - .default(ASTRO_CONFIG_DEFAULTS.experimental.serverIslands), contentIntellisense: z .boolean() .optional() diff --git a/packages/astro/src/core/create-vite.ts b/packages/astro/src/core/create-vite.ts index e8d9edfe36..eb27657271 100644 --- a/packages/astro/src/core/create-vite.ts +++ b/packages/astro/src/core/create-vite.ts @@ -158,7 +158,7 @@ export async function createVite( astroInternationalization({ settings }), vitePluginActions({ fs, settings }), vitePluginUserActions({ settings }), - settings.config.experimental.serverIslands && vitePluginServerIslands({ settings }), + vitePluginServerIslands({ settings }), astroContainer(), ], publicDir: fileURLToPath(settings.config.publicDir), diff --git a/packages/astro/src/core/errors/errors-data.ts b/packages/astro/src/core/errors/errors-data.ts index 2a41209828..09dc51e0f0 100644 --- a/packages/astro/src/core/errors/errors-data.ts +++ b/packages/astro/src/core/errors/errors-data.ts @@ -412,6 +412,19 @@ export const AdapterSupportOutputMismatch = { `The \`${adapterName}\` adapter is configured to output a static website, but the project contains server-rendered pages. Please install and configure the appropriate server adapter for your final deployment.`, } satisfies ErrorData; +/** + * @docs + * @see + * - [Server-side Rendering](https://docs.astro.build/en/guides/server-side-rendering/) + * @description + * To use server islands, the same constraints exist as for sever-side rendering, so an adapter is needed. + */ +export const NoAdapterInstalledServerIslands = { + name: 'NoAdapterInstalledServerIslands', + title: 'Cannot use Server Islands without an adapter.', + message: `Cannot use server islands without an adapter. Please install and configure the appropriate server adapter for your final deployment.`, + hint: 'See https://docs.astro.build/en/guides/server-side-rendering/ for more information.', +} satisfies ErrorData; /** * @docs * @description diff --git a/packages/astro/test/fixtures/server-islands/hybrid/astro.config.mjs b/packages/astro/test/fixtures/server-islands/hybrid/astro.config.mjs index b01b674f53..c6efdc2a23 100644 --- a/packages/astro/test/fixtures/server-islands/hybrid/astro.config.mjs +++ b/packages/astro/test/fixtures/server-islands/hybrid/astro.config.mjs @@ -6,7 +6,4 @@ export default defineConfig({ integrations: [ svelte() ], - experimental: { - serverIslands: true, - } }); diff --git a/packages/astro/test/fixtures/server-islands/ssr/astro.config.mjs b/packages/astro/test/fixtures/server-islands/ssr/astro.config.mjs index 79ce4c497a..e0fdc9ef23 100644 --- a/packages/astro/test/fixtures/server-islands/ssr/astro.config.mjs +++ b/packages/astro/test/fixtures/server-islands/ssr/astro.config.mjs @@ -8,8 +8,5 @@ export default defineConfig({ integrations: [ svelte() ], - experimental: { - serverIslands: true, - } }); diff --git a/packages/astro/test/server-islands.test.js b/packages/astro/test/server-islands.test.js index 8806f35115..86956f0d1a 100644 --- a/packages/astro/test/server-islands.test.js +++ b/packages/astro/test/server-islands.test.js @@ -63,13 +63,14 @@ describe('Server islands', () => { before(async () => { fixture = await loadFixture({ root: './fixtures/server-islands/hybrid', - adapter: testAdapter(), }); }); describe('build', () => { before(async () => { - await fixture.build(); + await fixture.build({ + adapter: testAdapter() + }); }); it('Omits the island HTML from the static HTML', async () => { @@ -83,5 +84,18 @@ describe('Server islands', () => { assert.equal(serverIslandScript.length, 1, 'has the island script'); }); }); + + describe('build (no adapter)', () => { + it('Errors during the build', async () => { + try { + await fixture.build({ + adapter: undefined + }); + assert.equal(true, false, 'should not have succeeded'); + } catch(err) { + assert.equal(err.title, 'Cannot use Server Islands without an adapter.'); + } + }); + }); }); });