Skip to content

Commit

Permalink
Revert "feat(hybrid): unflag hybrid output (#7255)" (#7259)
Browse files Browse the repository at this point in the history
This reverts commit bc5d6ed.
  • Loading branch information
natemoo-re authored May 31, 2023
1 parent 4e653a4 commit e0ca0d8
Show file tree
Hide file tree
Showing 29 changed files with 139 additions and 65 deletions.
10 changes: 0 additions & 10 deletions .changeset/weak-wombats-swim.md

This file was deleted.

38 changes: 38 additions & 0 deletions packages/astro/src/@types/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,44 @@ export interface AstroUserConfig {
* ```
*/
middleware?: boolean;

/**
* @docs
* @name experimental.hybridOutput
* @type {boolean}
* @default `false`
* @version 2.5.0
* @description
* Enable experimental support for hybrid SSR with pre-rendering enabled by default.
*
* To enable this feature, first set `experimental.hybridOutput` to `true` in your Astro config, and set `output` to `hybrid`.
*
* ```js
* {
* output: 'hybrid',
* experimental: {
* hybridOutput: true,
* },
* }
* ```
* Then add `export const prerender = false` to any page or endpoint you want to opt-out of pre-rendering.
* ```astro
* ---
* // pages/contact.astro
* export const prerender = false
*
* if (Astro.request.method === 'POST') {
* // handle form submission
* }
* ---
* <form method="POST">
* <input type="text" name="name" />
* <input type="email" name="email" />
* <button type="submit">Submit</button>
* </form>
* ```
*/
hybridOutput?: boolean;
};

// Legacy options to be removed
Expand Down
4 changes: 2 additions & 2 deletions packages/astro/src/assets/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { basename, join } from 'node:path/posix';
import type { StaticBuildOptions } from '../core/build/types.js';
import { warn } from '../core/logger/core.js';
import { prependForwardSlash } from '../core/path.js';
import { isServerLikeOutput } from '../prerender/utils.js';
import { isHybridOutput } from '../prerender/utils.js';
import { getConfiguredImageService, isESMImportedImage } from './internal.js';
import type { LocalImageService } from './services/service.js';
import type { ImageTransform } from './types.js';
Expand Down Expand Up @@ -47,7 +47,7 @@ export async function generateImage(
}

let serverRoot: URL, clientRoot: URL;
if (isServerLikeOutput(buildOpts.settings.config)) {
if (buildOpts.settings.config.output === 'server' || isHybridOutput(buildOpts.settings.config)) {
serverRoot = buildOpts.settings.config.build.server;
clientRoot = buildOpts.settings.config.build.client;
} else {
Expand Down
8 changes: 4 additions & 4 deletions packages/astro/src/core/build/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
removeTrailingForwardSlash,
} from '../../core/path.js';
import { runHookBuildGenerated } from '../../integrations/index.js';
import { isServerLikeOutput } from '../../prerender/utils.js';
import { isHybridOutput } from '../../prerender/utils.js';
import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from '../../vite-plugin-scripts/index.js';
import { callEndpoint, createAPIContext, throwIfRedirectNotAllowed } from '../endpoint/index.js';
import { AstroError } from '../errors/index.js';
Expand Down Expand Up @@ -94,7 +94,7 @@ export function chunkIsPage(

export async function generatePages(opts: StaticBuildOptions, internals: BuildInternals) {
const timer = performance.now();
const ssr = isServerLikeOutput(opts.settings.config);
const ssr = opts.settings.config.output === 'server' || isHybridOutput(opts.settings.config); // hybrid mode is essentially SSR with prerender by default
const serverEntry = opts.buildConfig.serverEntry;
const outFolder = ssr ? opts.buildConfig.server : getOutDirWithinCwd(opts.settings.config.outDir);

Expand Down Expand Up @@ -237,7 +237,7 @@ async function getPathsForRoute(
route: pageData.route,
isValidate: false,
logging: opts.logging,
ssr: isServerLikeOutput(opts.settings.config),
ssr: opts.settings.config.output === 'server' || isHybridOutput(opts.settings.config),
})
.then((_result) => {
const label = _result.staticPaths.length === 1 ? 'page' : 'pages';
Expand Down Expand Up @@ -413,7 +413,7 @@ async function generatePath(
}
}

const ssr = isServerLikeOutput(settings.config);
const ssr = settings.config.output === 'server' || isHybridOutput(settings.config);
const url = getUrlForPath(
pathname,
opts.settings.config.base,
Expand Down
5 changes: 3 additions & 2 deletions packages/astro/src/core/build/plugins/plugin-ssr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { fileURLToPath } from 'url';
import type { Plugin as VitePlugin } from 'vite';
import type { AstroAdapter } from '../../../@types/astro';
import { runHookBuildSsr } from '../../../integrations/index.js';
import { isServerLikeOutput } from '../../../prerender/utils.js';
import { isHybridOutput } 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';
import { joinPaths, prependForwardSlash } from '../../path.js';
Expand Down Expand Up @@ -272,7 +272,8 @@ export function pluginSSR(
options: StaticBuildOptions,
internals: BuildInternals
): AstroBuildPlugin {
const ssr = isServerLikeOutput(options.settings.config);
const ssr =
options.settings.config.output === 'server' || isHybridOutput(options.settings.config);
return {
build: 'ssr',
hooks: {
Expand Down
22 changes: 12 additions & 10 deletions packages/astro/src/core/build/static-build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { emptyDir, removeEmptyDirs } from '../../core/fs/index.js';
import { appendForwardSlash, prependForwardSlash } from '../../core/path.js';
import { isModeServerWithNoAdapter } from '../../core/util.js';
import { runHookBuildSetup } from '../../integrations/index.js';
import { isServerLikeOutput } from '../../prerender/utils.js';
import { isHybridOutput } from '../../prerender/utils.js';
import { PAGE_SCRIPT_ID } from '../../vite-plugin-scripts/index.js';
import { AstroError, AstroErrorData } from '../errors/index.js';
import { info } from '../logger/core.js';
Expand Down Expand Up @@ -117,6 +117,7 @@ export async function viteBuild(opts: StaticBuildOptions) {

export async function staticBuild(opts: StaticBuildOptions, internals: BuildInternals) {
const { settings } = opts;
const hybridOutput = isHybridOutput(settings.config);
switch (true) {
case settings.config.output === 'static': {
settings.timer.start('Static generate');
Expand All @@ -125,7 +126,7 @@ export async function staticBuild(opts: StaticBuildOptions, internals: BuildInte
settings.timer.end('Static generate');
return;
}
case isServerLikeOutput(settings.config): {
case settings.config.output === 'server' || hybridOutput: {
settings.timer.start('Server generate');
await generatePages(opts, internals);
await cleanStaticOutput(opts, internals);
Expand All @@ -144,7 +145,7 @@ async function ssrBuild(
container: AstroBuildPluginContainer
) {
const { settings, viteConfig } = opts;
const ssr = isServerLikeOutput(settings.config);
const ssr = settings.config.output === 'server' || isHybridOutput(settings.config);
const out = ssr ? opts.buildConfig.server : getOutDirWithinCwd(settings.config.outDir);

const { lastVitePlugins, vitePlugins } = container.runBeforeHook('ssr', input);
Expand Down Expand Up @@ -224,7 +225,7 @@ async function clientBuild(
) {
const { settings, viteConfig } = opts;
const timer = performance.now();
const ssr = isServerLikeOutput(settings.config);
const ssr = settings.config.output === 'server' || isHybridOutput(settings.config);
const out = ssr ? opts.buildConfig.client : getOutDirWithinCwd(settings.config.outDir);

// Nothing to do if there is no client-side JS.
Expand Down Expand Up @@ -289,11 +290,12 @@ async function runPostBuildHooks(
const config = container.options.settings.config;
const buildConfig = container.options.settings.config.build;
for (const [fileName, mutation] of mutations) {
const root = isServerLikeOutput(config)
? mutation.build === 'server'
? buildConfig.server
: buildConfig.client
: config.outDir;
const root =
config.output === 'server' || isHybridOutput(config)
? mutation.build === 'server'
? buildConfig.server
: buildConfig.client
: config.outDir;
const fileURL = new URL(fileName, root);
await fs.promises.mkdir(new URL('./', fileURL), { recursive: true });
await fs.promises.writeFile(fileURL, mutation.code, 'utf-8');
Expand All @@ -310,7 +312,7 @@ async function cleanStaticOutput(opts: StaticBuildOptions, internals: BuildInter
if (pageData.route.prerender)
allStaticFiles.add(internals.pageToBundleMap.get(pageData.moduleSpecifier));
}
const ssr = isServerLikeOutput(opts.settings.config);
const ssr = opts.settings.config.output === 'server' || isHybridOutput(opts.settings.config);
const out = ssr ? opts.buildConfig.server : getOutDirWithinCwd(opts.settings.config.outDir);
// The SSR output is all .mjs files, the client output is not.
const files = await glob('**/*.mjs', {
Expand Down
7 changes: 7 additions & 0 deletions packages/astro/src/core/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as colors from 'kleur/colors';
import path from 'path';
import { fileURLToPath, pathToFileURL } from 'url';
import { mergeConfig as mergeViteConfig } from 'vite';
import { isHybridMalconfigured } from '../../prerender/utils.js';
import { AstroError, AstroErrorData } from '../errors/index.js';
import type { LogOptions } from '../logger/core.js';
import { arraify, isObject, isURL } from '../util.js';
Expand Down Expand Up @@ -223,6 +224,12 @@ export async function openConfig(configOptions: LoadConfigOptions): Promise<Open
}
const astroConfig = await resolveConfig(userConfig, root, flags, configOptions.cmd);

if (isHybridMalconfigured(astroConfig)) {
throw new Error(
`The "output" config option must be set to "hybrid" and "experimental.hybridOutput" must be set to true to use the hybrid output mode. Falling back to "static" output mode.`
);
}

return {
astroConfig,
userConfig,
Expand Down
2 changes: 2 additions & 0 deletions packages/astro/src/core/config/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const ASTRO_CONFIG_DEFAULTS: AstroUserConfig & any = {
legacy: {},
experimental: {
assets: false,
hybridOutput: false,
customClientDirectives: false,
inlineStylesheets: 'never',
middleware: false,
Expand Down Expand Up @@ -207,6 +208,7 @@ export const AstroConfigSchema = z.object({
.optional()
.default(ASTRO_CONFIG_DEFAULTS.experimental.inlineStylesheets),
middleware: z.oboolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.middleware),
hybridOutput: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.hybridOutput),
})
.passthrough()
.refine(
Expand Down
4 changes: 2 additions & 2 deletions packages/astro/src/core/config/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { fileURLToPath, pathToFileURL } from 'url';
import type { AstroConfig, AstroSettings, AstroUserConfig } from '../../@types/astro';
import { getContentPaths } from '../../content/index.js';
import jsxRenderer from '../../jsx/renderer.js';
import { isServerLikeOutput } from '../../prerender/utils.js';
import { isHybridOutput } from '../../prerender/utils.js';
import { markdownContentEntryType } from '../../vite-plugin-markdown/content-entry-type.js';
import { getDefaultClientDirectives } from '../client-directive/index.js';
import { AstroError, AstroErrorData } from '../errors/index.js';
Expand All @@ -23,7 +23,7 @@ export function createBaseSettings(config: AstroConfig): AstroSettings {

adapter: undefined,
injectedRoutes:
config.experimental.assets && isServerLikeOutput(config)
config.experimental.assets && (config.output === 'server' || isHybridOutput(config))
? [{ pattern: '/_image', entryPoint: 'astro/assets/image-endpoint' }]
: [],
pageExtensions: ['.astro', '.html', ...SUPPORTED_MARKDOWN_FILE_EXTENSIONS],
Expand Down
4 changes: 2 additions & 2 deletions packages/astro/src/core/endpoint/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type {
} from '../../@types/astro';
import type { Environment, RenderContext } from '../render/index';

import { isServerLikeOutput } from '../../prerender/utils.js';
import { isHybridOutput } from '../../prerender/utils.js';
import { renderEndpoint } from '../../runtime/server/index.js';
import { ASTRO_VERSION } from '../constants.js';
import { AstroCookies, attachToResponse } from '../cookies/index.js';
Expand Down Expand Up @@ -161,7 +161,7 @@ function isRedirect(statusCode: number) {
}

export function throwIfRedirectNotAllowed(response: Response, config: AstroConfig) {
if (!isServerLikeOutput(config) && isRedirect(response.status)) {
if (config.output !== 'server' && !isHybridOutput(config) && isRedirect(response.status)) {
throw new AstroError(AstroErrorData.StaticRedirectNotAvailable);
}
}
4 changes: 2 additions & 2 deletions packages/astro/src/core/render/dev/environment.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { AstroSettings, RuntimeMode } from '../../../@types/astro';
import { isServerLikeOutput } from '../../../prerender/utils.js';
import { isHybridOutput } from '../../../prerender/utils.js';
import type { LogOptions } from '../../logger/core.js';
import type { ModuleLoader } from '../../module-loader/index';
import type { Environment } from '../index';
Expand Down Expand Up @@ -30,7 +30,7 @@ export function createDevelopmentEnvironment(
resolve: createResolve(loader, settings.config.root),
routeCache: new RouteCache(logging, mode),
site: settings.config.site,
ssr: isServerLikeOutput(settings.config),
ssr: settings.config.output === 'server' || isHybridOutput(settings.config),
streaming: true,
telemetry: Boolean(settings.forceDisableTelemetry),
});
Expand Down
8 changes: 4 additions & 4 deletions packages/astro/src/core/routing/manifest/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { createRequire } from 'module';
import path from 'path';
import slash from 'slash';
import { fileURLToPath } from 'url';
import { getPrerenderDefault } from '../../../prerender/utils.js';
import { isHybridOutput } from '../../../prerender/utils.js';
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from '../../constants.js';
import { warn } from '../../logger/core.js';
import { removeLeadingForwardSlash } from '../../path.js';
Expand Down Expand Up @@ -228,7 +228,7 @@ export function createRouteManifest(
]);
const validEndpointExtensions: Set<string> = new Set(['.js', '.ts']);
const localFs = fsMod ?? nodeFs;
const prerender = getPrerenderDefault(settings.config);
const isPrerenderDefault = isHybridOutput(settings.config);

const foundInvalidFileExtensions: Set<string> = new Set();

Expand Down Expand Up @@ -341,7 +341,7 @@ export function createRouteManifest(
component,
generate,
pathname: pathname || undefined,
prerender,
prerender: isPrerenderDefault,
});
}
});
Expand Down Expand Up @@ -417,7 +417,7 @@ export function createRouteManifest(
component,
generate,
pathname: pathname || void 0,
prerender,
prerender: isPrerenderDefault,
});
});

Expand Down
6 changes: 4 additions & 2 deletions packages/astro/src/core/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import slash from 'slash';
import { fileURLToPath } from 'url';
import { normalizePath } from 'vite';
import type { AstroConfig, AstroSettings, RouteType } from '../@types/astro';
import { isServerLikeOutput } from '../prerender/utils.js';
import { isHybridOutput } from '../prerender/utils.js';
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './constants.js';
import type { ModuleLoader } from './module-loader';
import { prependForwardSlash, removeTrailingForwardSlash } from './path.js';
Expand Down Expand Up @@ -139,7 +139,9 @@ export function isEndpoint(file: URL, settings: AstroSettings): boolean {
}

export function isModeServerWithNoAdapter(settings: AstroSettings): boolean {
return isServerLikeOutput(settings.config) && !settings.adapter;
return (
(settings.config.output === 'server' || isHybridOutput(settings.config)) && !settings.adapter
);
}

export function relativeToSrcDir(config: AstroConfig, idOrUrl: URL | string) {
Expand Down
8 changes: 5 additions & 3 deletions packages/astro/src/integrations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type { PageBuildData } from '../core/build/types';
import { buildClientDirectiveEntrypoint } from '../core/client-directive/index.js';
import { mergeConfig } from '../core/config/config.js';
import { info, type LogOptions } from '../core/logger/core.js';
import { isServerLikeOutput } from '../prerender/utils.js';
import { isHybridOutput } from '../prerender/utils.js';
import { mdxContentEntryType } from '../vite-plugin-markdown/content-entry-type.js';

async function withTakingALongTimeMsg<T>({
Expand Down Expand Up @@ -339,7 +339,8 @@ export async function runHookBuildGenerated({
buildConfig: BuildConfig;
logging: LogOptions;
}) {
const dir = isServerLikeOutput(config) ? buildConfig.client : config.outDir;
const dir =
config.output === 'server' || isHybridOutput(config) ? buildConfig.client : config.outDir;

for (const integration of config.integrations) {
if (integration?.hooks?.['astro:build:generated']) {
Expand All @@ -365,7 +366,8 @@ export async function runHookBuildDone({
routes: RouteData[];
logging: LogOptions;
}) {
const dir = isServerLikeOutput(config) ? buildConfig.client : config.outDir;
const dir =
config.output === 'server' || isHybridOutput(config) ? buildConfig.client : config.outDir;
await fs.promises.mkdir(dir, { recursive: true });

for (const integration of config.integrations) {
Expand Down
10 changes: 6 additions & 4 deletions packages/astro/src/prerender/utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// TODO: remove after the experimetal phase when

import type { AstroConfig } from '../@types/astro';

export function isServerLikeOutput(config: AstroConfig) {
return config.output === 'server' || config.output === 'hybrid';
export function isHybridMalconfigured(config: AstroConfig) {
return config.experimental.hybridOutput ? config.output !== 'hybrid' : config.output === 'hybrid';
}

export function getPrerenderDefault(config: AstroConfig) {
return config.output === 'hybrid';
export function isHybridOutput(config: AstroConfig) {
return config.experimental.hybridOutput && config.output === 'hybrid';
}
Loading

0 comments on commit e0ca0d8

Please sign in to comment.