Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions packages/astro/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import type {
Locales,
SessionDriverName,
} from '../types/public/config.js';
import { createDevelopmentManifest } from '../vite-plugin-astro-server/plugin.js';

/**
* See the full Astro Configuration API Documentation
Expand Down Expand Up @@ -56,7 +55,6 @@ export function getViteConfig(
let settings = await createSettings(config, userViteConfig.root);
settings = await runHookConfigSetup({ settings, command: cmd, logger });
const routesList = await createRoutesList({ settings }, logger);
const manifest = createDevelopmentManifest(settings);
const viteConfig = await createVite(
{
plugins: config.legacy.collections
Expand All @@ -66,7 +64,7 @@ export function getViteConfig(
]
: [],
},
{ settings, command: cmd, logger, mode, sync: false, manifest, routesList },
{ settings, command: cmd, logger, mode, sync: false, routesList },
);
await runHookConfigDone({ settings, logger });
return mergeConfig(viteConfig, userViteConfig);
Expand Down
117 changes: 107 additions & 10 deletions packages/astro/src/core/app/common.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
import type { RoutesList } from '../../types/astro.js';
import type { AstroConfig } from '../../types/public/index.js';
import { decodeKey } from '../encryption.js';
import { NOOP_MIDDLEWARE_FN } from '../middleware/noop-middleware.js';
import { deserializeRouteData } from '../routing/manifest/serialization.js';
import type { RouteInfo, SerializedSSRManifest, SSRManifest } from './types.js';

export function deserializeManifest(serializedManifest: SerializedSSRManifest): SSRManifest {
export function deserializeManifest(
serializedManifest: SerializedSSRManifest,
routesList?: RoutesList,
): SSRManifest {
const routes: RouteInfo[] = [];
for (const serializedRoute of serializedManifest.routes) {
routes.push({
...serializedRoute,
routeData: deserializeRouteData(serializedRoute.routeData),
});

const route = serializedRoute as unknown as RouteInfo;
route.routeData = deserializeRouteData(serializedRoute.routeData);
}
if (serializedManifest.routes) {
for (const serializedRoute of serializedManifest.routes) {
routes.push({
...serializedRoute,
routeData: deserializeRouteData(serializedRoute.routeData),
});

const route = serializedRoute as unknown as RouteInfo;
route.routeData = deserializeRouteData(serializedRoute.routeData);
}
}
if (routesList) {
for (const route of routesList?.routes) {
routes.push({
file: '',
links: [],
scripts: [],
styles: [],
routeData: route,
});
}
}
const assets = new Set<string>(serializedManifest.assets);
const componentMetadata = new Map(serializedManifest.componentMetadata);
const inlinedScripts = new Map(serializedManifest.inlinedScripts);
Expand All @@ -37,3 +54,83 @@ export function deserializeManifest(serializedManifest: SerializedSSRManifest):
key,
};
}

export type RoutingStrategies =
| 'manual'
| 'pathname-prefix-always'
| 'pathname-prefix-other-locales'
| 'pathname-prefix-always-no-redirect'
| 'domains-prefix-always'
| 'domains-prefix-other-locales'
| 'domains-prefix-always-no-redirect';
export function toRoutingStrategy(
routing: NonNullable<AstroConfig['i18n']>['routing'],
domains: NonNullable<AstroConfig['i18n']>['domains'],
): RoutingStrategies {
let strategy: RoutingStrategies;
const hasDomains = domains ? Object.keys(domains).length > 0 : false;
if (routing === 'manual') {
strategy = 'manual';
} else {
if (!hasDomains) {
if (routing?.prefixDefaultLocale === true) {
if (routing.redirectToDefaultLocale) {
strategy = 'pathname-prefix-always';
} else {
strategy = 'pathname-prefix-always-no-redirect';
}
} else {
strategy = 'pathname-prefix-other-locales';
}
} else {
if (routing?.prefixDefaultLocale === true) {
if (routing.redirectToDefaultLocale) {
strategy = 'domains-prefix-always';
} else {
strategy = 'domains-prefix-always-no-redirect';
}
} else {
strategy = 'domains-prefix-other-locales';
}
}
}

return strategy;
}
export function toFallbackType(
routing: NonNullable<AstroConfig['i18n']>['routing'],
): 'redirect' | 'rewrite' {
if (routing === 'manual') {
return 'rewrite';
}
return routing.fallbackType;
}

const PREFIX_DEFAULT_LOCALE = new Set([
'pathname-prefix-always',
'domains-prefix-always',
'pathname-prefix-always-no-redirect',
'domains-prefix-always-no-redirect',
]);

const REDIRECT_TO_DEFAULT_LOCALE = new Set([
'pathname-prefix-always-no-redirect',
'domains-prefix-always-no-redirect',
]);

export function fromRoutingStrategy(
strategy: RoutingStrategies,
fallbackType: NonNullable<SSRManifest['i18n']>['fallbackType'],
): NonNullable<AstroConfig['i18n']>['routing'] {
let routing: NonNullable<AstroConfig['i18n']>['routing'];
if (strategy === 'manual') {
routing = 'manual';
} else {
routing = {
prefixDefaultLocale: PREFIX_DEFAULT_LOCALE.has(strategy),
redirectToDefaultLocale: !REDIRECT_TO_DEFAULT_LOCALE.has(strategy),
fallbackType,
};
}
return routing;
}
2 changes: 1 addition & 1 deletion packages/astro/src/core/app/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { App } from './app.js';
export { BaseApp, type RenderErrorOptions, type RenderOptions } from './base.js';
export { deserializeManifest } from './common.js';
export { deserializeManifest, fromRoutingStrategy, toRoutingStrategy } from './common.js';
export { AppPipeline } from './pipeline.js';
2 changes: 1 addition & 1 deletion packages/astro/src/core/app/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { ZodType } from 'zod';
import type { ActionAccept, ActionClient } from '../../actions/runtime/virtual/server.js';
import type { RoutingStrategies } from '../../i18n/utils.js';
import type { ComponentInstance, SerializedRouteData } from '../../types/astro.js';
import type { AstroMiddlewareInstance } from '../../types/public/common.js';
import type {
Expand All @@ -17,6 +16,7 @@ import type {
} from '../../types/public/internal.js';
import type { SinglePageBuiltModule } from '../build/types.js';
import type { CspDirective } from '../csp/config.js';
import type { RoutingStrategies } from './common.js';

type ComponentPath = string;

Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/build/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
removeTrailingForwardSlash,
trimSlashes,
} from '../../core/path.js';
import { toFallbackType, toRoutingStrategy } from '../../i18n/utils.js';
import { runHookBuildGenerated, toIntegrationResolvedRoute } from '../../integrations/hooks.js';
import { getServerOutputDirectory } from '../../prerender/utils.js';
import type { AstroSettings, ComponentInstance } from '../../types/astro.js';
Expand All @@ -29,6 +28,7 @@ import type {
SSRError,
SSRLoadedRenderer,
} from '../../types/public/internal.js';
import { toFallbackType, toRoutingStrategy } from '../app/common.js';
import type { SSRActions, SSRManifest, SSRManifestCSP, SSRManifestI18n } from '../app/types.js';
import {
getAlgorithm,
Expand Down
7 changes: 0 additions & 7 deletions packages/astro/src/core/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
} from '../../integrations/hooks.js';
import type { AstroSettings, RoutesList } from '../../types/astro.js';
import type { AstroInlineConfig, RuntimeMode } from '../../types/public/config.js';
import { createDevelopmentManifest } from '../../vite-plugin-astro-server/plugin.js';
import { resolveConfig } from '../config/config.js';
import { createNodeLogger } from '../config/logging.js';
import { createSettings } from '../config/settings.js';
Expand Down Expand Up @@ -123,10 +122,6 @@ class AstroBuilder {
command: 'build',
logger: logger,
});
// NOTE: this manifest is only used by the first build pass to make the `astro:manifest` function.
// After the first build, the BuildPipeline comes into play, and it creates the proper manifest for generating the pages.
const manifest = createDevelopmentManifest(this.settings);

this.routesList = await createRoutesList({ settings: this.settings }, this.logger);

await runHookConfigDone({ settings: this.settings, logger: logger, command: 'build' });
Expand All @@ -151,7 +146,6 @@ class AstroBuilder {
command: 'build',
sync: false,
routesList: this.routesList,
manifest,
},
);

Expand All @@ -163,7 +157,6 @@ class AstroBuilder {
fs,
routesList: this.routesList,
command: 'build',
manifest,
});

return { viteConfig };
Expand Down
3 changes: 2 additions & 1 deletion packages/astro/src/core/build/plugins/plugin-manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { type BuiltinDriverName, builtinDrivers } from 'unstorage';
import type { Plugin as VitePlugin } from 'vite';
import { getAssetsPrefix } from '../../../assets/utils/getAssetsPrefix.js';
import { normalizeTheLocale } from '../../../i18n/index.js';
import { toFallbackType, toRoutingStrategy } from '../../../i18n/utils.js';
import { runHookBuildSsr } from '../../../integrations/hooks.js';
import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from '../../../vite-plugin-scripts/index.js';
import { toFallbackType } from '../../app/common.js';
import { toRoutingStrategy } from '../../app/index.js';
import type {
SerializedRouteInfo,
SerializedSSRManifest,
Expand Down
12 changes: 5 additions & 7 deletions packages/astro/src/core/create-vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { createEnvLoader } from '../env/env-loader.js';
import { astroEnv } from '../env/vite-plugin-env.js';
import { importMetaEnv } from '../env/vite-plugin-import-meta-env.js';
import astroInternationalization from '../i18n/vite-plugin-i18n.js';
import { serializedManifestPlugin } from '../manifest/serialized.js';
import astroVirtualManifestPlugin from '../manifest/virtual-module.js';
import astroPrefetch from '../prefetch/vite-plugin-prefetch.js';
import astroDevToolbar from '../toolbar/vite-plugin-dev-toolbar.js';
Expand All @@ -36,7 +37,6 @@ import astroScannerPlugin from '../vite-plugin-scanner/index.js';
import astroScriptsPlugin from '../vite-plugin-scripts/index.js';
import astroScriptsPageSSRPlugin from '../vite-plugin-scripts/page-ssr.js';
import { vitePluginSSRManifest } from '../vite-plugin-ssr-manifest/index.js';
import type { SSRManifest } from './app/types.js';
import type { Logger } from './logger/core.js';
import { createViteLogger } from './logger/vite.js';
import { vitePluginMiddleware } from './middleware/vite-plugin.js';
Expand All @@ -51,15 +51,12 @@ type CreateViteOptions = {
fs?: typeof nodeFs;
sync: boolean;
routesList: RoutesList;
manifest: SSRManifest;
} & (
| {
command: 'dev';
manifest: SSRManifest;
}
| {
command: 'build';
manifest?: SSRManifest;
}
);

Expand Down Expand Up @@ -90,7 +87,7 @@ const ONLY_DEV_EXTERNAL = [
/** Return a base vite config as a common starting point for all Vite commands. */
export async function createVite(
commandConfig: vite.InlineConfig,
{ settings, logger, mode, command, fs = nodeFs, sync, routesList, manifest }: CreateViteOptions,
{ settings, logger, mode, command, fs = nodeFs, sync, routesList }: CreateViteOptions,
): Promise<vite.InlineConfig> {
const astroPkgsConfig = await crawlFrameworkPkgs({
root: fileURLToPath(settings.config.root),
Expand Down Expand Up @@ -147,14 +144,15 @@ export async function createVite(
exclude: ['astro', 'node-fetch'],
},
plugins: [
astroVirtualManifestPlugin({ manifest }),
await serializedManifestPlugin({ settings }),
astroVirtualManifestPlugin(),
configAliasVitePlugin({ settings }),
astroLoadFallbackPlugin({ fs, root: settings.config.root }),
astroVitePlugin({ settings, logger }),
astroScriptsPlugin({ settings }),
// The server plugin is for dev only and having it run during the build causes
// the build to run very slow as the filewatcher is triggered often.
command === 'dev' && vitePluginAstroServer({ settings, logger, fs, routesList, manifest }), // manifest is only required in dev mode, where it gets created before a Vite instance is created, and get passed to this function
command === 'dev' && vitePluginAstroServer({ settings, logger, fs, routesList }), // manifest is only required in dev mode, where it gets created before a Vite instance is created, and get passed to this function
importMetaEnv({ envLoader }),
astroEnv({ settings, sync, envLoader }),
markdownVitePlugin({ settings, logger }),
Expand Down
5 changes: 0 additions & 5 deletions packages/astro/src/core/dev/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
} from '../../integrations/hooks.js';
import type { AstroSettings } from '../../types/astro.js';
import type { AstroInlineConfig } from '../../types/public/config.js';
import { createDevelopmentManifest } from '../../vite-plugin-astro-server/plugin.js';
import { createVite } from '../create-vite.js';
import type { Logger } from '../logger/core.js';
import { apply as applyPolyfill } from '../polyfill.js';
Expand Down Expand Up @@ -82,8 +81,6 @@ export async function createContainer({

// Create the route manifest already outside of Vite so that `runHookConfigDone` can use it to inform integrations of the build output
const routesList = await createRoutesList({ settings, fsMod: fs }, logger, { dev: true });
const manifest = createDevelopmentManifest(settings);

await runHookConfigDone({ settings, logger, command: 'dev' });

warnMissingAdapter(logger, settings);
Expand All @@ -104,7 +101,6 @@ export async function createContainer({
fs,
sync: false,
routesList,
manifest,
},
);
const viteServer = await vite.createServer(viteConfig);
Expand All @@ -119,7 +115,6 @@ export async function createContainer({
},
force: inlineConfig?.force,
routesList,
manifest,
command: 'dev',
watcher: viteServer.watcher,
});
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/routing/manifest/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import { fileURLToPath } from 'node:url';
import { bold } from 'kleur/colors';
import pLimit from 'p-limit';
import { injectImageEndpoint } from '../../../assets/endpoint/config.js';
import { toRoutingStrategy } from '../../../i18n/utils.js';
import { runHookRoutesResolved } from '../../../integrations/hooks.js';
import { getPrerenderDefault } from '../../../prerender/utils.js';
import type { AstroSettings, RoutesList } from '../../../types/astro.js';
import type { AstroConfig } from '../../../types/public/config.js';
import type { RouteData, RoutePart } from '../../../types/public/internal.js';
import { toRoutingStrategy } from '../../app/index.js';
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from '../../constants.js';
import {
MissingIndexForInternationalization,
Expand Down
Loading
Loading