mirror of
https://github.com/withastro/astro.git
synced 2025-01-06 22:10:10 -05:00
fix: make root serializable (#11489)
* fix: use config root to build default routes * fix: make root serializable * fix regression * Use stringified URLs * Fix unit tests --------- Co-authored-by: Matthew Phillips <matthew@skypack.dev>
This commit is contained in:
parent
6ad02b5902
commit
061f1f4d0c
13 changed files with 44 additions and 11 deletions
5
.changeset/cuddly-days-relate.md
Normal file
5
.changeset/cuddly-days-relate.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Move root inside the manifest and make serialisable
|
|
@ -105,6 +105,7 @@ function createManifest(
|
|||
};
|
||||
|
||||
return {
|
||||
hrefRoot: import.meta.url,
|
||||
rewritingEnabled: false,
|
||||
trailingSlash: manifest?.trailingSlash ?? ASTRO_CONFIG_DEFAULTS.trailingSlash,
|
||||
buildFormat: manifest?.buildFormat ?? ASTRO_CONFIG_DEFAULTS.build.format,
|
||||
|
|
|
@ -20,10 +20,11 @@ import {
|
|||
} from '../path.js';
|
||||
import { RenderContext } from '../render-context.js';
|
||||
import { createAssetLink } from '../render/ssr-element.js';
|
||||
import { injectDefaultRoutes } from '../routing/default.js';
|
||||
import { createDefaultRoutes, injectDefaultRoutes } from '../routing/default.js';
|
||||
import { matchRoute } from '../routing/match.js';
|
||||
import { createOriginCheckMiddleware } from './middlewares.js';
|
||||
import { AppPipeline } from './pipeline.js';
|
||||
|
||||
export { deserializeManifest } from './common.js';
|
||||
|
||||
export interface RenderOptions {
|
||||
|
@ -122,6 +123,7 @@ export class App {
|
|||
manifest: this.#manifest,
|
||||
mode: 'production',
|
||||
renderers: this.#manifest.renderers,
|
||||
defaultRoutes: createDefaultRoutes(this.#manifest),
|
||||
resolve: async (specifier: string) => {
|
||||
if (!(specifier in this.#manifest.entryModules)) {
|
||||
throw new Error(`Unable to resolve [${specifier}]`);
|
||||
|
@ -145,6 +147,7 @@ export class App {
|
|||
set setManifestData(newManifestData: ManifestData) {
|
||||
this.#manifestData = newManifestData;
|
||||
}
|
||||
|
||||
removeBase(pathname: string) {
|
||||
if (pathname.startsWith(this.#manifest.base)) {
|
||||
return pathname.slice(this.#baseWithoutTrailingSlash.length + 1);
|
||||
|
|
|
@ -25,9 +25,17 @@ export class AppPipeline extends Pipeline {
|
|||
resolve,
|
||||
serverLike,
|
||||
streaming,
|
||||
defaultRoutes,
|
||||
}: Pick<
|
||||
AppPipeline,
|
||||
'logger' | 'manifest' | 'mode' | 'renderers' | 'resolve' | 'serverLike' | 'streaming'
|
||||
| 'logger'
|
||||
| 'manifest'
|
||||
| 'mode'
|
||||
| 'renderers'
|
||||
| 'resolve'
|
||||
| 'serverLike'
|
||||
| 'streaming'
|
||||
| 'defaultRoutes'
|
||||
>
|
||||
) {
|
||||
const pipeline = new AppPipeline(
|
||||
|
@ -46,7 +54,8 @@ export class AppPipeline extends Pipeline {
|
|||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
false
|
||||
false,
|
||||
defaultRoutes
|
||||
);
|
||||
pipeline.#manifestData = manifestData;
|
||||
return pipeline;
|
||||
|
@ -75,6 +84,7 @@ export class AppPipeline extends Pipeline {
|
|||
}
|
||||
|
||||
componentMetadata() {}
|
||||
|
||||
async getComponentByRoute(routeData: RouteData): Promise<ComponentInstance> {
|
||||
const module = await this.getModuleForRoute(routeData);
|
||||
return module.page();
|
||||
|
|
|
@ -44,6 +44,7 @@ export type AssetsPrefix =
|
|||
| undefined;
|
||||
|
||||
export type SSRManifest = {
|
||||
hrefRoot: string;
|
||||
adapterName: string;
|
||||
routes: RouteInfo[];
|
||||
site?: string;
|
||||
|
|
|
@ -58,7 +58,7 @@ export abstract class Pipeline {
|
|||
* Array of built-in, internal, routes.
|
||||
* Used to find the route module
|
||||
*/
|
||||
readonly defaultRoutes = createDefaultRoutes(manifest, new URL(import.meta.url))
|
||||
readonly defaultRoutes = createDefaultRoutes(manifest)
|
||||
) {
|
||||
this.internalMiddleware = [];
|
||||
// We do use our middleware only if the user isn't using the manual setup
|
||||
|
@ -77,6 +77,7 @@ export abstract class Pipeline {
|
|||
}
|
||||
|
||||
abstract headElements(routeData: RouteData): Promise<HeadElements> | HeadElements;
|
||||
|
||||
abstract componentMetadata(routeData: RouteData): Promise<SSRResult['componentMetadata']> | void;
|
||||
|
||||
/**
|
||||
|
|
|
@ -417,6 +417,7 @@ interface GeneratePathOptions {
|
|||
styles: StylesheetAsset[];
|
||||
mod: ComponentInstance;
|
||||
}
|
||||
|
||||
async function generatePath(
|
||||
pathname: string,
|
||||
pipeline: BuildPipeline,
|
||||
|
@ -552,6 +553,7 @@ function createBuildManifest(
|
|||
};
|
||||
}
|
||||
return {
|
||||
hrefRoot: settings.config.root.toString(),
|
||||
trailingSlash: settings.config.trailingSlash,
|
||||
assets: new Set(),
|
||||
entryModules: Object.fromEntries(internals.entrySpecifierToBundleMap.entries()),
|
||||
|
|
|
@ -55,9 +55,10 @@ export class BuildPipeline extends Pipeline {
|
|||
readonly options: StaticBuildOptions,
|
||||
readonly config = options.settings.config,
|
||||
readonly settings = options.settings,
|
||||
readonly defaultRoutes = createDefaultRoutes(manifest, config.root)
|
||||
readonly defaultRoutes = createDefaultRoutes(manifest)
|
||||
) {
|
||||
const resolveCache = new Map<string, string>();
|
||||
|
||||
async function resolve(specifier: string) {
|
||||
if (resolveCache.has(specifier)) {
|
||||
return resolveCache.get(specifier)!;
|
||||
|
@ -76,6 +77,7 @@ export class BuildPipeline extends Pipeline {
|
|||
resolveCache.set(specifier, assetLink);
|
||||
return assetLink;
|
||||
}
|
||||
|
||||
const serverLike = isServerLikeOutput(config);
|
||||
// We can skip streaming in SSG for performance as writing as strings are faster
|
||||
const streaming = serverLike;
|
||||
|
|
|
@ -27,7 +27,7 @@ const replaceExp = new RegExp(`['"]${manifestReplace}['"]`, 'g');
|
|||
export const SSR_MANIFEST_VIRTUAL_MODULE_ID = '@astrojs-manifest';
|
||||
export const RESOLVED_SSR_MANIFEST_VIRTUAL_MODULE_ID = '\0' + SSR_MANIFEST_VIRTUAL_MODULE_ID;
|
||||
|
||||
function vitePluginManifest(options: StaticBuildOptions, internals: BuildInternals): VitePlugin {
|
||||
function vitePluginManifest(_options: StaticBuildOptions, internals: BuildInternals): VitePlugin {
|
||||
return {
|
||||
name: '@astro/plugin-build-manifest',
|
||||
enforce: 'post',
|
||||
|
@ -262,6 +262,7 @@ function buildManifest(
|
|||
}
|
||||
|
||||
return {
|
||||
hrefRoot: opts.settings.config.root.toString(),
|
||||
adapterName: opts.settings.adapter?.name ?? '',
|
||||
routes,
|
||||
site: settings.config.site,
|
||||
|
|
|
@ -25,17 +25,20 @@ type DefaultRouteParams = {
|
|||
component: string;
|
||||
};
|
||||
|
||||
export function createDefaultRoutes(manifest: SSRManifest, root: URL): DefaultRouteParams[] {
|
||||
export function createDefaultRoutes(manifest: SSRManifest): DefaultRouteParams[] {
|
||||
const root = new URL(manifest.hrefRoot);
|
||||
return [
|
||||
{
|
||||
instance: default404Instance,
|
||||
matchesComponent: (filePath) => filePath.href === new URL(DEFAULT_404_COMPONENT, root).href,
|
||||
matchesComponent: (filePath) =>
|
||||
filePath.href === new URL(DEFAULT_404_COMPONENT, root).href,
|
||||
route: DEFAULT_404_ROUTE.route,
|
||||
component: DEFAULT_404_COMPONENT,
|
||||
},
|
||||
{
|
||||
instance: createServerIslandEndpoint(manifest),
|
||||
matchesComponent: (filePath) => filePath.href === new URL(SERVER_ISLAND_COMPONENT, root).href,
|
||||
matchesComponent: (filePath) =>
|
||||
filePath.href === new URL(SERVER_ISLAND_COMPONENT, root).href,
|
||||
route: SERVER_ISLAND_ROUTE,
|
||||
component: SERVER_ISLAND_COMPONENT,
|
||||
},
|
||||
|
|
|
@ -46,7 +46,7 @@ export class DevPipeline extends Pipeline {
|
|||
readonly manifest: SSRManifest,
|
||||
readonly settings: AstroSettings,
|
||||
readonly config = settings.config,
|
||||
readonly defaultRoutes = createDefaultRoutes(manifest, config.root)
|
||||
readonly defaultRoutes = createDefaultRoutes(manifest)
|
||||
) {
|
||||
const mode = 'development';
|
||||
const resolve = createResolve(loader, config.root);
|
||||
|
|
|
@ -50,6 +50,7 @@ export default function createVitePluginAstroServer({
|
|||
pipeline.setManifestData(manifestData);
|
||||
}
|
||||
}
|
||||
|
||||
// Rebuild route manifest on file change, if needed.
|
||||
viteServer.watcher.on('add', rebuildManifest.bind(null, true));
|
||||
viteServer.watcher.on('unlink', rebuildManifest.bind(null, true));
|
||||
|
@ -128,6 +129,7 @@ export function createDevelopmentManifest(settings: AstroSettings): SSRManifest
|
|||
};
|
||||
}
|
||||
return {
|
||||
hrefRoot: settings.config.root.toString(),
|
||||
trailingSlash: settings.config.trailingSlash,
|
||||
buildFormat: settings.config.build.format,
|
||||
compressHTML: settings.config.compressHTML,
|
||||
|
|
|
@ -188,7 +188,9 @@ export function createBasicPipeline(options = {}) {
|
|||
const mode = options.mode ?? 'development';
|
||||
const pipeline = new Pipeline(
|
||||
options.logger ?? defaultLogger,
|
||||
options.manifest ?? {},
|
||||
options.manifest ?? {
|
||||
hrefRoot: import.meta.url
|
||||
},
|
||||
options.mode ?? 'development',
|
||||
options.renderers ?? [],
|
||||
options.resolve ?? ((s) => Promise.resolve(s)),
|
||||
|
|
Loading…
Reference in a new issue