From c916db97a9647b20af9cfadbb1e4693ff4384caa Mon Sep 17 00:00:00 2001 From: Romuald Brillout Date: Sat, 7 May 2022 09:39:06 +0200 Subject: [PATCH] feat: option to disable SPA catch-all --- packages/vite/src/node/http.ts | 8 ++++++++ packages/vite/src/node/preview.ts | 19 +++++++++++++++++-- packages/vite/src/node/server/index.ts | 5 ++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/packages/vite/src/node/http.ts b/packages/vite/src/node/http.ts index bfc2ddbe32a302..8129f6e3bb5687 100644 --- a/packages/vite/src/node/http.ts +++ b/packages/vite/src/node/http.ts @@ -69,6 +69,14 @@ export interface CommonServerOptions { * Specify server response headers. */ headers?: HttpServerHeaders + /** + * Disable SPA catch-all routing. + * + * By default, Vite's dev/preview server redirects all routes to the root + * URL `/`. (In order to enable client-side routed SPAs.) For SSR or MPA apps, + * this behavior should be disabled and this option allows you to do so. + */ + disableSPACatchAll?: boolean } /** diff --git a/packages/vite/src/node/preview.ts b/packages/vite/src/node/preview.ts index c1670c5d7efa72..6c6d1ec30b2ca4 100644 --- a/packages/vite/src/node/preview.ts +++ b/packages/vite/src/node/preview.ts @@ -1,4 +1,5 @@ import path from 'path' +import fs from 'fs' import sirv from 'sirv' import connect from 'connect' import compression from './server/middlewares/compression' @@ -34,7 +35,8 @@ export function resolvePreviewOptions( open: preview?.open ?? server.open, proxy: preview?.proxy ?? server.proxy, cors: preview?.cors ?? server.cors, - headers: preview?.headers ?? server.headers + headers: preview?.headers ?? server.headers, + disableSPACatchAll: preview?.disableSPACatchAll ?? server.disableSPACatchAll } } @@ -83,16 +85,29 @@ export async function preview( app.use(compression()) + const { disableSPACatchAll } = config.preview const distDir = path.resolve(config.root, config.build.outDir) app.use( config.base, sirv(distDir, { etag: true, dev: true, - single: true + single: !disableSPACatchAll }) ) + if (disableSPACatchAll) { + app.use(config.base, (_, res, next) => { + const file = path.join(distDir, './404.html') + if (fs.existsSync(file)) { + res.statusCode = 404 + res.end(fs.readFileSync(file)) + } else { + next() + } + }) + } + const options = config.preview const hostname = resolveHostname(options.host) const port = options.port ?? 4173 diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index b8f1c3330a9b48..a0600cb464241b 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -524,7 +524,10 @@ export async function createServer( middlewares.use(serveStaticMiddleware(root, server)) // spa fallback - if (!middlewareMode || middlewareMode === 'html') { + if ( + !serverConfig.disableSPACatchAll && + (!middlewareMode || middlewareMode === 'html') + ) { middlewares.use(spaFallbackMiddleware(root)) }