diff options
Diffstat (limited to 'packages/astro/src')
5 files changed, 50 insertions, 33 deletions
diff --git a/packages/astro/src/core/preview/static-preview-server.ts b/packages/astro/src/core/preview/static-preview-server.ts index 937ba1c99..68a700b6d 100644 --- a/packages/astro/src/core/preview/static-preview-server.ts +++ b/packages/astro/src/core/preview/static-preview-server.ts @@ -72,8 +72,6 @@ export default async function createStaticPreviewServer( host: getResolvedHostForHttpServer(settings.config.server.host), port: settings.config.server.port, closed, - // In Vite 5, `httpServer` may be a `Http2SecureServer`, but we know we are only starting a HTTP server - // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion server: previewServer.httpServer as http.Server, stop: async () => { await new Promise((resolve, reject) => { diff --git a/packages/astro/src/core/preview/vite-plugin-astro-preview.ts b/packages/astro/src/core/preview/vite-plugin-astro-preview.ts index 7f9979275..aafd69cb4 100644 --- a/packages/astro/src/core/preview/vite-plugin-astro-preview.ts +++ b/packages/astro/src/core/preview/vite-plugin-astro-preview.ts @@ -1,13 +1,13 @@ import fs from 'node:fs'; +import type { IncomingMessage, ServerResponse } from 'node:http'; import { fileURLToPath } from 'node:url'; import type { Connect, Plugin } from 'vite'; -import { version } from 'vite'; import type { AstroSettings } from '../../@types/astro.js'; import { notFoundTemplate, subpathNotUsedTemplate } from '../../template/4xx.js'; +import { cleanUrl } from '../../vite-plugin-utils/index.js'; import { stripBase } from './util.js'; const HAS_FILE_EXTENSION_REGEXP = /^.*\.[^\\]+$/; -const IS_VITE_5 = version.startsWith('5.'); export function vitePluginAstroPreview(settings: AstroSettings): Plugin { const { base, outDir, trailingSlash } = settings.config; @@ -24,8 +24,7 @@ export function vitePluginAstroPreview(settings: AstroSettings): Plugin { return; } - const strippedPathname = stripBase(req.url!, base); - const pathname = new URL(strippedPathname, 'https://a.b').pathname; + const pathname = cleanUrl(stripBase(req.url!, base)); const isRoot = pathname === '/'; // Validate trailingSlash @@ -53,29 +52,49 @@ export function vitePluginAstroPreview(settings: AstroSettings): Plugin { }); return () => { - const fourOhFourMiddleware: Connect.NextHandleFunction = (req, res) => { - const errorPagePath = fileURLToPath(outDir + '/404.html'); - if (fs.existsSync(errorPagePath)) { - res.statusCode = 404; - res.setHeader('Content-Type', 'text/html;charset=utf-8'); - res.end(fs.readFileSync(errorPagePath)); - } else { - const pathname = stripBase(req.url!, base); - res.statusCode = 404; - res.end(notFoundTemplate(pathname, 'Not Found')); - } - }; + // NOTE: the `base` is stripped from `req.url` for post middlewares - // Vite 5 has its own 404 middleware, we replace it with ours instead. - if (IS_VITE_5) { - for (const middleware of server.middlewares.stack) { - // This hardcoded name will not break between Vite versions - if ((middleware.handle as Connect.HandleFunction).name === 'vite404Middleware') { - middleware.handle = fourOhFourMiddleware; + server.middlewares.use((req, res, next) => { + const pathname = cleanUrl(req.url!); + + // Vite doesn't handle /foo/ if /foo.html exists, we handle it anyways + if (pathname.endsWith('/')) { + const pathnameWithoutSlash = pathname.slice(0, -1); + const htmlPath = fileURLToPath(outDir + pathnameWithoutSlash + '.html'); + if (fs.existsSync(htmlPath)) { + req.url = pathnameWithoutSlash + '.html'; + return next(); } } - } else { - server.middlewares.use(fourOhFourMiddleware); + // Vite doesn't handle /foo if /foo/index.html exists, we handle it anyways + else { + const htmlPath = fileURLToPath(outDir + pathname + '/index.html'); + if (fs.existsSync(htmlPath)) { + req.url = pathname + '/index.html'; + return next(); + } + } + + next(); + }); + + // Vite has its own 404 middleware, we replace it with ours instead. + for (const middleware of server.middlewares.stack) { + // This hardcoded name will not break between Vite versions + if ((middleware.handle as Connect.HandleFunction).name === 'vite404Middleware') { + // Fallback to 404 page if it exists + middleware.handle = (req: IncomingMessage, res: ServerResponse) => { + const errorPagePath = fileURLToPath(outDir + '/404.html'); + if (fs.existsSync(errorPagePath)) { + res.statusCode = 404; + res.setHeader('Content-Type', 'text/html;charset=utf-8'); + res.end(fs.readFileSync(errorPagePath)); + } else { + res.statusCode = 404; + res.end(notFoundTemplate(req.url!, 'Not Found')); + } + }; + } } }; }, diff --git a/packages/astro/src/vite-plugin-load-fallback/index.ts b/packages/astro/src/vite-plugin-load-fallback/index.ts index e11f317ca..80db39edd 100644 --- a/packages/astro/src/vite-plugin-load-fallback/index.ts +++ b/packages/astro/src/vite-plugin-load-fallback/index.ts @@ -2,6 +2,7 @@ import nodeFs from 'node:fs'; import npath from 'node:path'; import type * as vite from 'vite'; import { slash } from '../core/path.js'; +import { cleanUrl } from '../vite-plugin-utils/index.js'; type NodeFileSystemModule = typeof nodeFs; @@ -77,8 +78,3 @@ export default function loadFallbackPlugin({ }, ]; } - -const queryRE = /\?.*$/s; -const hashRE = /#.*$/s; - -const cleanUrl = (url: string): string => url.replace(hashRE, '').replace(queryRE, ''); diff --git a/packages/astro/src/vite-plugin-scripts/index.ts b/packages/astro/src/vite-plugin-scripts/index.ts index 0066b98f5..9b2848923 100644 --- a/packages/astro/src/vite-plugin-scripts/index.ts +++ b/packages/astro/src/vite-plugin-scripts/index.ts @@ -50,8 +50,7 @@ export default function astroScriptsPlugin({ settings }: { settings: AstroSettin }, buildStart() { const hasHydrationScripts = settings.scripts.some((s) => s.stage === 'before-hydration'); - // @ts-expect-error Vite 5 renamed `ssrBuild` to `isSsrBuild` - const isSsrBuild = env?.ssrBuild || env?.isSsrBuild; + const isSsrBuild = env?.isSsrBuild; if (hasHydrationScripts && env?.command === 'build' && !isSsrBuild) { this.emitFile({ type: 'chunk', diff --git a/packages/astro/src/vite-plugin-utils/index.ts b/packages/astro/src/vite-plugin-utils/index.ts index 51f0e6cc4..7bf9f092f 100644 --- a/packages/astro/src/vite-plugin-utils/index.ts +++ b/packages/astro/src/vite-plugin-utils/index.ts @@ -56,3 +56,8 @@ export function normalizeFilename(filename: string, root: URL) { } return removeLeadingForwardSlashWindows(filename); } + +const postfixRE = /[?#].*$/s; +export function cleanUrl(url: string): string { + return url.replace(postfixRE, ''); +} |