-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Vite 5 #9122
Support Vite 5 #9122
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
--- | ||
'@astrojs/svelte': major | ||
'@astrojs/react': patch | ||
'@astrojs/vue': patch | ||
'astro': major | ||
--- | ||
|
||
Adds Vite 5 support. There are no breaking changes from Astro. Check the [Vite migration guide](https://vitejs.dev/guide/migration.html) for details of the breaking changes from Vite instead. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@astrojs/svelte': major | ||
--- | ||
|
||
Drops support for Svelte 3 as `@sveltejs/vite-plugin-svelte` is updated to `3.0.0` which does not support Svelte 3 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); | ||
} | ||
Comment on lines
+60
to
67
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment above should clarify what this does. But to further explain why we're assigning to |
||
} | ||
} 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')); | ||
} | ||
}; | ||
} | ||
} | ||
}; | ||
}, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
import { defineConfig } from 'rollup' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lol |
||
import { defineConfig } from 'astro/config' | ||
import test from './integration.js' | ||
|
||
export default defineConfig({ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,6 +73,7 @@ async function getViteConfiguration({ | |
} | ||
|
||
if (!resolvedOptions.preprocess && !(await svelteConfigHasPreprocess(root))) { | ||
// @ts-expect-error there's a bug with the types where the first arg should be optional | ||
resolvedOptions.preprocess = vitePreprocess(); | ||
Comment on lines
+76
to
77
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've sent a PR upstream to fix it. If it's released, I'll update this part before merging. |
||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a world where we'd want to support https for the preview server? Unrelated to this, just wondering.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could! At the moment we have control over the config passed to Vite's
preview()
so we know this will always be a http server. If we open up to the config fromastro.config.mjs
in the future, they can create https servers.