diff --git a/.changeset/unlucky-spoons-poke.md b/.changeset/unlucky-spoons-poke.md new file mode 100644 index 0000000..e847bf4 --- /dev/null +++ b/.changeset/unlucky-spoons-poke.md @@ -0,0 +1,5 @@ +--- +'@hono/vite-dev-server': minor +--- + +feat: exlude files in `public` dir diff --git a/packages/dev-server/e2e/e2e.test.ts b/packages/dev-server/e2e/e2e.test.ts index 59d36bd..2ead110 100644 --- a/packages/dev-server/e2e/e2e.test.ts +++ b/packages/dev-server/e2e/e2e.test.ts @@ -101,3 +101,8 @@ test('Should set `cf` properties', async ({ page }) => { expect(res?.ok()).toBe(true) expect(await res?.json()).toEqual({ cf: true }) }) + +test('Should return files in the public directory', async ({ page }) => { + const res = await page.goto('/hono-logo.png') + expect(res?.status()).toBe(200) +}) diff --git a/packages/dev-server/e2e/public/hono-logo.png b/packages/dev-server/e2e/public/hono-logo.png new file mode 100644 index 0000000..562a3b5 Binary files /dev/null and b/packages/dev-server/e2e/public/hono-logo.png differ diff --git a/packages/dev-server/src/dev-server.ts b/packages/dev-server/src/dev-server.ts index ab34fcc..d90ec26 100644 --- a/packages/dev-server/src/dev-server.ts +++ b/packages/dev-server/src/dev-server.ts @@ -1,7 +1,9 @@ import { getRequestListener } from '@hono/node-server' import { minimatch } from 'minimatch' import type { Plugin as VitePlugin, ViteDevServer, Connect } from 'vite' +import fs from 'fs' import type http from 'http' +import path from 'path' import type { Env, Fetch, EnvFunc, Adapter, LoadModule } from './types.js' export type DevServerOptions = { @@ -61,9 +63,13 @@ export const defaultOptions: Required { async function createMiddleware(server: ViteDevServer): Promise { return async function ( @@ -71,8 +77,18 @@ export function devServer(options?: DevServerOptions): VitePlugin { res: http.ServerResponse, next: Connect.NextFunction ): Promise { - const exclude = options?.exclude ?? defaultOptions.exclude + if (req.url) { + const filePath = path.join(publicDirPath, req.url) + try { + if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) { + return next() + } + } catch { + // do nothing + } + } + const exclude = options?.exclude ?? defaultOptions.exclude for (const pattern of exclude) { if (req.url) { if (pattern instanceof RegExp) {