fix: --experimental-ssr
fixes (#2937)
* Replaced `--experimental-ssr` with `isBuildingToSSR` * changest * Improved `isBuildingToSSR` a bit * Added `isBuildingToSSR` to more places!!1! * Added `@deprecated` tag * Replaced missing experimentalSsr * Added failing test * Removed test * Re-added experimental ssr flag * Fixed typo Co-authored-by: Matthew Phillips <matthew@skypack.dev> * Fixed deno tests Co-authored-by: Matthew Phillips <matthew@skypack.dev>
This commit is contained in:
parent
e860408692
commit
d10c3dea21
17 changed files with 54 additions and 32 deletions
5
.changeset/flat-radios-cheer.md
Normal file
5
.changeset/flat-radios-cheer.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
`--experimental-ssr` now is only required when using a 3rd-party adapter
|
|
@ -3,9 +3,9 @@
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev --experimental-ssr",
|
"dev": "astro dev",
|
||||||
"start": "astro dev",
|
"start": "astro dev",
|
||||||
"build": "astro build --experimental-ssr",
|
"build": "astro build",
|
||||||
"server": "node server/server.mjs"
|
"server": "node server/server.mjs"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -345,7 +345,8 @@ export interface AstroUserConfig {
|
||||||
*/
|
*/
|
||||||
experimentalStaticBuild?: boolean;
|
experimentalStaticBuild?: boolean;
|
||||||
/**
|
/**
|
||||||
* Enable a build for SSR support.
|
* Enable SSR support for 3rd-party adapters.
|
||||||
|
* Not required when using a built-in adapter.
|
||||||
* Default: false
|
* Default: false
|
||||||
*/
|
*/
|
||||||
experimentalSsr?: boolean;
|
experimentalSsr?: boolean;
|
||||||
|
|
|
@ -39,7 +39,7 @@ function printAstroHelp() {
|
||||||
['--project-root <path>', 'Specify the path to the project root folder.'],
|
['--project-root <path>', 'Specify the path to the project root folder.'],
|
||||||
['--no-sitemap', 'Disable sitemap generation (build only).'],
|
['--no-sitemap', 'Disable sitemap generation (build only).'],
|
||||||
['--legacy-build', 'Use the build strategy prior to 0.24.0'],
|
['--legacy-build', 'Use the build strategy prior to 0.24.0'],
|
||||||
['--experimental-ssr', 'Enable SSR compilation.'],
|
['--experimental-ssr', 'Enable SSR compilation fot 3rd-party adapters.'],
|
||||||
['--drafts', 'Include markdown draft pages in the build.'],
|
['--drafts', 'Include markdown draft pages in the build.'],
|
||||||
['--verbose', 'Enable verbose logging'],
|
['--verbose', 'Enable verbose logging'],
|
||||||
['--silent', 'Disable logging'],
|
['--silent', 'Disable logging'],
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { BEFORE_HYDRATION_SCRIPT_ID } from '../../vite-plugin-scripts/index.js';
|
||||||
import { call as callEndpoint } from '../endpoint/index.js';
|
import { call as callEndpoint } from '../endpoint/index.js';
|
||||||
import { render } from '../render/core.js';
|
import { render } from '../render/core.js';
|
||||||
import { createLinkStylesheetElementSet, createModuleScriptElementWithSrcSet } from '../render/ssr-element.js';
|
import { createLinkStylesheetElementSet, createModuleScriptElementWithSrcSet } from '../render/ssr-element.js';
|
||||||
import { getOutputFilename } from '../util.js';
|
import { getOutputFilename, isBuildingToSSR } from '../util.js';
|
||||||
import { getOutFile, getOutFolder } from './common.js';
|
import { getOutFile, getOutFolder } from './common.js';
|
||||||
import { eachPageData, getPageDataByComponent } from './internal.js';
|
import { eachPageData, getPageDataByComponent } from './internal.js';
|
||||||
import type { PageBuildData, SingleFileBuiltModule, StaticBuildOptions } from './types';
|
import type { PageBuildData, SingleFileBuiltModule, StaticBuildOptions } from './types';
|
||||||
|
@ -71,7 +71,7 @@ export async function generatePages(result: RollupOutput, opts: StaticBuildOptio
|
||||||
const timer = performance.now();
|
const timer = performance.now();
|
||||||
info(opts.logging, null, `\n${bgGreen(black(' generating static routes '))}`);
|
info(opts.logging, null, `\n${bgGreen(black(' generating static routes '))}`);
|
||||||
|
|
||||||
const ssr = !!opts.astroConfig._ctx.adapter?.serverEntrypoint;
|
const ssr = isBuildingToSSR(opts.astroConfig);
|
||||||
const serverEntry = opts.buildConfig.serverEntry;
|
const serverEntry = opts.buildConfig.serverEntry;
|
||||||
const outFolder = ssr ? opts.buildConfig.server : opts.astroConfig.dist;
|
const outFolder = ssr ? opts.buildConfig.server : opts.astroConfig.dist;
|
||||||
const ssrEntryURL = new URL('./' + serverEntry + `?time=${Date.now()}`, outFolder);
|
const ssrEntryURL = new URL('./' + serverEntry + `?time=${Date.now()}`, outFolder);
|
||||||
|
@ -197,7 +197,7 @@ async function generatePath(pathname: string, opts: StaticBuildOptions, gopts: G
|
||||||
route: pageData.route,
|
route: pageData.route,
|
||||||
routeCache,
|
routeCache,
|
||||||
site: astroConfig.buildOptions.site,
|
site: astroConfig.buildOptions.site,
|
||||||
ssr: opts.astroConfig.buildOptions.experimentalSsr,
|
ssr: isBuildingToSSR(opts.astroConfig),
|
||||||
};
|
};
|
||||||
|
|
||||||
let body: string;
|
let body: string;
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { staticBuild } from './static-build.js';
|
||||||
import { RouteCache } from '../render/route-cache.js';
|
import { RouteCache } from '../render/route-cache.js';
|
||||||
import { runHookBuildDone, runHookBuildStart, runHookConfigDone, runHookConfigSetup } from '../../integrations/index.js';
|
import { runHookBuildDone, runHookBuildStart, runHookConfigDone, runHookConfigSetup } from '../../integrations/index.js';
|
||||||
import { getTimeStat } from './util.js';
|
import { getTimeStat } from './util.js';
|
||||||
import { createSafeError } from '../util.js';
|
import { createSafeError, isBuildingToSSR } from '../util.js';
|
||||||
import { fixViteErrorMessage } from '../errors.js';
|
import { fixViteErrorMessage } from '../errors.js';
|
||||||
|
|
||||||
export interface BuildOptions {
|
export interface BuildOptions {
|
||||||
|
@ -101,7 +101,7 @@ class AstroBuilder {
|
||||||
origin,
|
origin,
|
||||||
routeCache: this.routeCache,
|
routeCache: this.routeCache,
|
||||||
viteServer,
|
viteServer,
|
||||||
ssr: this.config.buildOptions.experimentalSsr,
|
ssr: isBuildingToSSR(this.config),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Filter pages by using conditions based on their frontmatter.
|
// Filter pages by using conditions based on their frontmatter.
|
||||||
|
@ -182,7 +182,7 @@ class AstroBuilder {
|
||||||
await runHookBuildDone({ config: this.config, pages: pageNames, routes: Object.values(allPages).map((pd) => pd.route) });
|
await runHookBuildDone({ config: this.config, pages: pageNames, routes: Object.values(allPages).map((pd) => pd.route) });
|
||||||
|
|
||||||
if (this.logging.level && levels[this.logging.level] <= levels['info']) {
|
if (this.logging.level && levels[this.logging.level] <= levels['info']) {
|
||||||
const buildMode = this.config.buildOptions.experimentalSsr ? 'ssr' : 'static';
|
const buildMode = isBuildingToSSR(this.config) ? 'ssr' : 'static';
|
||||||
await this.printStats({ logging: this.logging, timeStart: this.timer.init, pageCount: pageNames.length, buildMode });
|
await this.printStats({ logging: this.logging, timeStart: this.timer.init, pageCount: pageNames.length, buildMode });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { debug } from '../logger/core.js';
|
||||||
import { preload as ssrPreload } from '../render/dev/index.js';
|
import { preload as ssrPreload } from '../render/dev/index.js';
|
||||||
import { generateRssFunction } from '../render/rss.js';
|
import { generateRssFunction } from '../render/rss.js';
|
||||||
import { callGetStaticPaths, RouteCache, RouteCacheEntry } from '../render/route-cache.js';
|
import { callGetStaticPaths, RouteCache, RouteCacheEntry } from '../render/route-cache.js';
|
||||||
|
import { isBuildingToSSR } from '../util.js';
|
||||||
|
|
||||||
export interface CollectPagesDataOptions {
|
export interface CollectPagesDataOptions {
|
||||||
astroConfig: AstroConfig;
|
astroConfig: AstroConfig;
|
||||||
|
@ -33,7 +34,7 @@ export async function collectPagesData(opts: CollectPagesDataOptions): Promise<C
|
||||||
const assets: Record<string, string> = {};
|
const assets: Record<string, string> = {};
|
||||||
const allPages: AllPagesData = {};
|
const allPages: AllPagesData = {};
|
||||||
|
|
||||||
const buildMode = astroConfig.buildOptions.experimentalSsr ? 'ssr' : 'static';
|
const buildMode = isBuildingToSSR(astroConfig) ? 'ssr' : 'static';
|
||||||
|
|
||||||
const dataCollectionLogTimeout = setInterval(() => {
|
const dataCollectionLogTimeout = setInterval(() => {
|
||||||
info(opts.logging, 'build', 'The data collection step may take longer for larger projects...');
|
info(opts.logging, 'build', 'The data collection step may take longer for larger projects...');
|
||||||
|
|
|
@ -111,7 +111,7 @@ export async function staticBuild(opts: StaticBuildOptions) {
|
||||||
|
|
||||||
async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, input: Set<string>) {
|
async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, input: Set<string>) {
|
||||||
const { astroConfig, viteConfig } = opts;
|
const { astroConfig, viteConfig } = opts;
|
||||||
const ssr = astroConfig.buildOptions.experimentalSsr;
|
const ssr = isBuildingToSSR(astroConfig);
|
||||||
const out = ssr ? opts.buildConfig.server : astroConfig.dist;
|
const out = ssr ? opts.buildConfig.server : astroConfig.dist;
|
||||||
|
|
||||||
const viteBuildConfig = {
|
const viteBuildConfig = {
|
||||||
|
|
|
@ -261,12 +261,7 @@ function mergeCLIFlags(astroConfig: AstroUserConfig, flags: CLIFlags) {
|
||||||
if (typeof flags.host === 'string' || typeof flags.host === 'boolean') astroConfig.devOptions.host = flags.host;
|
if (typeof flags.host === 'string' || typeof flags.host === 'boolean') astroConfig.devOptions.host = flags.host;
|
||||||
if (typeof flags.hostname === 'string') astroConfig.devOptions.hostname = flags.hostname;
|
if (typeof flags.hostname === 'string') astroConfig.devOptions.hostname = flags.hostname;
|
||||||
if (typeof flags.legacyBuild === 'boolean') astroConfig.buildOptions.legacyBuild = flags.legacyBuild;
|
if (typeof flags.legacyBuild === 'boolean') astroConfig.buildOptions.legacyBuild = flags.legacyBuild;
|
||||||
if (typeof flags.experimentalSsr === 'boolean') {
|
if (typeof flags.experimentalSsr === 'boolean') astroConfig.buildOptions.experimentalSsr = flags.experimentalSsr;
|
||||||
astroConfig.buildOptions.experimentalSsr = flags.experimentalSsr;
|
|
||||||
if (flags.experimentalSsr) {
|
|
||||||
astroConfig.buildOptions.legacyBuild = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (typeof flags.experimentalIntegrations === 'boolean') astroConfig.experimentalIntegrations = flags.experimentalIntegrations;
|
if (typeof flags.experimentalIntegrations === 'boolean') astroConfig.experimentalIntegrations = flags.experimentalIntegrations;
|
||||||
if (typeof flags.drafts === 'boolean') astroConfig.buildOptions.drafts = flags.drafts;
|
if (typeof flags.drafts === 'boolean') astroConfig.buildOptions.drafts = flags.drafts;
|
||||||
return astroConfig;
|
return astroConfig;
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
import type { EndpointHandler } from '../../../@types/astro';
|
import type { EndpointHandler } from '../../../@types/astro';
|
||||||
import type { SSROptions } from '../../render/dev';
|
import type { SSROptions } from '../../render/dev';
|
||||||
import { preload } from '../../render/dev/index.js';
|
import { preload } from '../../render/dev/index.js';
|
||||||
|
import { isBuildingToSSR } from '../../util.js';
|
||||||
import { call as callEndpoint } from '../index.js';
|
import { call as callEndpoint } from '../index.js';
|
||||||
|
|
||||||
export async function call(ssrOpts: SSROptions) {
|
export async function call(ssrOpts: SSROptions) {
|
||||||
const [, mod] = await preload(ssrOpts);
|
const [, mod] = await preload(ssrOpts);
|
||||||
return await callEndpoint(mod as unknown as EndpointHandler, {
|
return await callEndpoint(mod as unknown as EndpointHandler, {
|
||||||
...ssrOpts,
|
...ssrOpts,
|
||||||
ssr: ssrOpts.astroConfig.buildOptions.experimentalSsr,
|
ssr: isBuildingToSSR(ssrOpts.astroConfig),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ import { createModuleScriptElementWithSrcSet } from '../ssr-element.js';
|
||||||
import { getStylesForURL } from './css.js';
|
import { getStylesForURL } from './css.js';
|
||||||
import { getHmrScript } from './hmr.js';
|
import { getHmrScript } from './hmr.js';
|
||||||
import { injectTags } from './html.js';
|
import { injectTags } from './html.js';
|
||||||
|
import { isBuildingToSSR } from '../../util.js';
|
||||||
|
|
||||||
export interface SSROptions {
|
export interface SSROptions {
|
||||||
/** an instance of the AstroConfig */
|
/** an instance of the AstroConfig */
|
||||||
astroConfig: AstroConfig;
|
astroConfig: AstroConfig;
|
||||||
|
@ -146,7 +148,7 @@ export async function render(renderers: SSRLoadedRenderer[], mod: ComponentInsta
|
||||||
route,
|
route,
|
||||||
routeCache,
|
routeCache,
|
||||||
site: astroConfig.buildOptions.site,
|
site: astroConfig.buildOptions.site,
|
||||||
ssr: astroConfig.buildOptions.experimentalSsr,
|
ssr: isBuildingToSSR(astroConfig),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (route?.type === 'endpoint' || content.type === 'response') {
|
if (route?.type === 'endpoint' || content.type === 'response') {
|
||||||
|
|
|
@ -139,7 +139,27 @@ export function emptyDir(_dir: URL, skip?: Set<string>): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isBuildingToSSR(config: AstroConfig): boolean {
|
export function isBuildingToSSR(config: AstroConfig): boolean {
|
||||||
return !!config._ctx.adapter?.serverEntrypoint;
|
const adapter = config._ctx.adapter;
|
||||||
|
if (!adapter) return false;
|
||||||
|
|
||||||
|
if (typeof adapter.serverEntrypoint === 'string') {
|
||||||
|
if (!adapter.name.startsWith('@astrojs/') && !config.buildOptions.experimentalSsr) {
|
||||||
|
throw new Error(
|
||||||
|
[
|
||||||
|
`Server-side rendering (SSR) is still experimental.`,
|
||||||
|
``,
|
||||||
|
`Only official "@astrojs/*" adapters are currently supported.`,
|
||||||
|
`To enable SSR for 3rd-party adapters, use the "--experimental-ssr" flag.`,
|
||||||
|
`Breaking changes may occur in this API before Astro v1.0 is released.`,
|
||||||
|
``,
|
||||||
|
].join('\n')
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function emoji(char: string, fallback: string) {
|
export function emoji(char: string, fallback: string) {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { debug, info, warn, error, LogOptions } from '../core/logger/core.js';
|
||||||
import { getParamsAndProps, GetParamsAndPropsError } from '../core/render/core.js';
|
import { getParamsAndProps, GetParamsAndPropsError } from '../core/render/core.js';
|
||||||
import { createRouteManifest, matchRoute } from '../core/routing/index.js';
|
import { createRouteManifest, matchRoute } from '../core/routing/index.js';
|
||||||
import stripAnsi from 'strip-ansi';
|
import stripAnsi from 'strip-ansi';
|
||||||
import { createSafeError } from '../core/util.js';
|
import { createSafeError, isBuildingToSSR } from '../core/util.js';
|
||||||
import { ssr, preload } from '../core/render/dev/index.js';
|
import { ssr, preload } from '../core/render/dev/index.js';
|
||||||
import { call as callEndpoint } from '../core/endpoint/dev/index.js';
|
import { call as callEndpoint } from '../core/endpoint/dev/index.js';
|
||||||
import * as msg from '../core/messages.js';
|
import * as msg from '../core/messages.js';
|
||||||
|
@ -123,7 +123,7 @@ async function handleRequest(
|
||||||
const site = config.buildOptions.site ? new URL(config.buildOptions.site) : undefined;
|
const site = config.buildOptions.site ? new URL(config.buildOptions.site) : undefined;
|
||||||
const devRoot = site ? site.pathname : '/';
|
const devRoot = site ? site.pathname : '/';
|
||||||
const origin = `${viteServer.config.server.https ? 'https' : 'http'}://${req.headers.host}`;
|
const origin = `${viteServer.config.server.https ? 'https' : 'http'}://${req.headers.host}`;
|
||||||
const buildingToSSR = !!config._ctx.adapter?.serverEntrypoint;
|
const buildingToSSR = isBuildingToSSR(config);
|
||||||
const url = new URL(origin + req.url);
|
const url = new URL(origin + req.url);
|
||||||
const pathname = decodeURI(url.pathname);
|
const pathname = decodeURI(url.pathname);
|
||||||
const rootRelativeUrl = pathname.substring(devRoot.length - 1);
|
const rootRelativeUrl = pathname.substring(devRoot.length - 1);
|
||||||
|
@ -185,7 +185,7 @@ async function handleRequest(
|
||||||
routeCache,
|
routeCache,
|
||||||
pathname: rootRelativeUrl,
|
pathname: rootRelativeUrl,
|
||||||
logging,
|
logging,
|
||||||
ssr: config.buildOptions.experimentalSsr,
|
ssr: isBuildingToSSR(config),
|
||||||
});
|
});
|
||||||
if (paramsAndPropsRes === GetParamsAndPropsError.NoMatchingStaticPath) {
|
if (paramsAndPropsRes === GetParamsAndPropsError.NoMatchingStaticPath) {
|
||||||
warn(logging, 'getStaticPaths', `Route pattern matched, but no matching static path found. (${pathname})`);
|
warn(logging, 'getStaticPaths', `Route pattern matched, but no matching static path found. (${pathname})`);
|
||||||
|
|
|
@ -10,9 +10,7 @@ describe('API routes in SSR', () => {
|
||||||
before(async () => {
|
before(async () => {
|
||||||
fixture = await loadFixture({
|
fixture = await loadFixture({
|
||||||
projectRoot: './fixtures/ssr-api-route/',
|
projectRoot: './fixtures/ssr-api-route/',
|
||||||
buildOptions: {
|
buildOptions: { experimentalSsr: true },
|
||||||
experimentalSsr: true,
|
|
||||||
},
|
|
||||||
adapter: testAdapter(),
|
adapter: testAdapter(),
|
||||||
});
|
});
|
||||||
await fixture.build();
|
await fixture.build();
|
||||||
|
|
|
@ -11,9 +11,7 @@ describe('Dynamic pages in SSR', () => {
|
||||||
before(async () => {
|
before(async () => {
|
||||||
fixture = await loadFixture({
|
fixture = await loadFixture({
|
||||||
projectRoot: './fixtures/ssr-dynamic/',
|
projectRoot: './fixtures/ssr-dynamic/',
|
||||||
buildOptions: {
|
buildOptions: { experimentalSsr: true },
|
||||||
experimentalSsr: true,
|
|
||||||
},
|
|
||||||
adapter: testAdapter(),
|
adapter: testAdapter(),
|
||||||
});
|
});
|
||||||
await fixture.build();
|
await fixture.build();
|
||||||
|
|
|
@ -2,5 +2,6 @@ import { defineConfig } from 'astro/config';
|
||||||
import deno from '@astrojs/deno';
|
import deno from '@astrojs/deno';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
adapter: deno()
|
adapter: deno(),
|
||||||
|
buildOptions: { experimentalSsr: true }
|
||||||
})
|
})
|
||||||
|
|
|
@ -13,7 +13,7 @@ export async function runBuild(fixturePath) {
|
||||||
export async function runBuildAndStartApp(fixturePath, cb) {
|
export async function runBuildAndStartApp(fixturePath, cb) {
|
||||||
const url = new URL(fixturePath, dir);
|
const url = new URL(fixturePath, dir);
|
||||||
const close = await runBuild(fixturePath);
|
const close = await runBuild(fixturePath);
|
||||||
const mod = await import(new URL('./dist/entry.mjs', url));
|
const mod = await import(new URL('./dist/server/entry.mjs', url));
|
||||||
await cb();
|
await cb();
|
||||||
await mod.stop();
|
await mod.stop();
|
||||||
await close();
|
await close();
|
||||||
|
|
Loading…
Reference in a new issue