Skip to content

Commit

Permalink
Require the experimental flag to use server islands (#11432)
Browse files Browse the repository at this point in the history
* Require the experimental flag to use server islands

* Add flag to tests/examples

* Protect SSR against SI not being enabled
  • Loading branch information
matthewp authored Jul 9, 2024
1 parent 62609b4 commit 3f8f074
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 9 deletions.
3 changes: 3 additions & 0 deletions examples/server-islands/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ export default defineConfig({
tailwind({ applyBaseStyles: false })
],
devToolbar: { enabled: false },
experimental: {
serverIslands: true,
}
});
3 changes: 3 additions & 0 deletions packages/astro/e2e/fixtures/server-islands/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ export default defineConfig({
output: 'hybrid',
adapter: nodejs({ mode: 'standalone' }),
integrations: [react(), mdx()],
experimental: {
serverIslands: true,
}
});
28 changes: 28 additions & 0 deletions packages/astro/src/@types/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2163,6 +2163,34 @@ export interface AstroUserConfig {
*/
schema?: EnvSchema;
};

/**
* @docs
* @name experimental.serverIslands
* @type {boolean}
* @default `false`
* @version 4.12.0
* @description
*
* Enables Server Islands, the ability to defer a component to render asynchronously after the page has already rendered.
*
* ```js
* {
* experimental: {
* serverIslands: true,
* },
* }
* ```
*
* Use the `server:defer` directive on any component, Astro or framework, and the component will not render initially.
*
* ```astro "server:defer"
* <Avatar server:defer />
* ```
*
* For a complete overview, and to give feedback on this experimental API, see the [Server Islands RFC](https://github.com/withastro/roadmap/pull/963).
*/
serverIslands?: boolean;
};
}

Expand Down
11 changes: 6 additions & 5 deletions packages/astro/src/core/build/plugins/plugin-ssr.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { join } from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
import type { Plugin as VitePlugin } from 'vite';
import type { AstroAdapter } from '../../../@types/astro.js';
import type { AstroAdapter, AstroSettings } from '../../../@types/astro.js';
import { isFunctionPerRouteEnabled } from '../../../integrations/hooks.js';
import { routeIsRedirect } from '../../redirects/index.js';
import { isServerLikeOutput } from '../../util.js';
Expand Down Expand Up @@ -78,7 +78,7 @@ function vitePluginSSR(
contents.push(`const pageMap = new Map([\n ${pageMap.join(',\n ')}\n]);`);
exports.push(`export { pageMap }`);
const middleware = await this.resolve(MIDDLEWARE_MODULE_ID);
const ssrCode = generateSSRCode(adapter, middleware!.id);
const ssrCode = generateSSRCode(options.settings, adapter, middleware!.id);
imports.push(...ssrCode.imports);
contents.push(...ssrCode.contents);
return [...imports, ...contents, ...exports].join('\n');
Expand Down Expand Up @@ -184,7 +184,7 @@ function vitePluginSSRSplit(
imports.push(`import * as pageModule from "${virtualModuleName}";`);
}
const middleware = await this.resolve(MIDDLEWARE_MODULE_ID);
const ssrCode = generateSSRCode(adapter, middleware!.id);
const ssrCode = generateSSRCode(options.settings, adapter, middleware!.id);
imports.push(...ssrCode.imports);
contents.push(...ssrCode.contents);

Expand Down Expand Up @@ -241,7 +241,7 @@ export function pluginSSRSplit(
};
}

function generateSSRCode(adapter: AstroAdapter, middlewareId: string) {
function generateSSRCode(settings: AstroSettings, adapter: AstroAdapter, middlewareId: string) {
const edgeMiddleware = adapter?.adapterFeatures?.edgeMiddleware ?? false;
const pageMap = isFunctionPerRouteEnabled(adapter) ? 'pageModule' : 'pageMap';

Expand All @@ -250,10 +250,11 @@ function generateSSRCode(adapter: AstroAdapter, middlewareId: string) {
`import { manifest as defaultManifest } from '${SSR_MANIFEST_VIRTUAL_MODULE_ID}';`,
`import * as serverEntrypointModule from '${adapter.serverEntrypoint}';`,
edgeMiddleware ? `` : `import { onRequest as middleware } from '${middlewareId}';`,
`import { serverIslandMap } from '${VIRTUAL_ISLAND_MAP_ID}';`
settings.config.experimental.serverIslands ? `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},`,
Expand Down
4 changes: 3 additions & 1 deletion packages/astro/src/core/config/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export const ASTRO_CONFIG_DEFAULTS = {
clientPrerender: false,
globalRoutePriority: false,
rewriting: false,
serverIslands: false,
},
} satisfies AstroUserConfig & { server: { open: boolean } };

Expand Down Expand Up @@ -529,6 +530,7 @@ export const AstroConfigSchema = z.object({
})
.strict()
.optional(),
serverIslands: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.serverIslands),
})
.strict(
`Invalid or outdated experimental feature.\nCheck for incorrect spelling or outdated Astro version.\nSee https://docs.astro.build/en/reference/configuration-reference/#experimental-flags for a list of all current experiments.`
Expand Down Expand Up @@ -667,7 +669,7 @@ export function createRelativeSchema(cmd: string, fileProtocolRoot: string) {
'The value of `outDir` must not point to a path within the folder set as `publicDir`, this will cause an infinite loop',
})
.superRefine((configuration, ctx) => {
const { site, experimental, i18n, output } = configuration;
const { site, i18n, output } = configuration;
const hasDomains = i18n?.domains ? Object.keys(i18n.domains).length > 0 : false;
if (hasDomains) {
if (!site) {
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/create-vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export async function createVite(
astroDevToolbar({ settings, logger }),
vitePluginFileURL({}),
astroInternationalization({ settings }),
vitePluginServerIslands({ settings }),
settings.config.experimental.serverIslands && vitePluginServerIslands({ settings }),
astroContainer(),
],
publicDir: fileURLToPath(settings.config.publicDir),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ export default defineConfig({
output: 'hybrid',
integrations: [
svelte()
]
],
experimental: {
serverIslands: true,
}
});

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ export default defineConfig({
output: 'server',
integrations: [
svelte()
]
],
experimental: {
serverIslands: true,
}
});

0 comments on commit 3f8f074

Please sign in to comment.