epicweb-dev / epicweb-dev/epic-stack

/img/* and /favicons/* 404 handler prevents static file serving when placed before dev/prod middleware

Abierto
#1,079 1 comentario 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
TypeScript
Estrellas
5.5k
Forks
460
Merge medio
2 h 43 min
PR fusionados (30 d)
1

Descripción

Problem
The 404 handler for /img/* and /favicons/* routes intercepts requests before the static file serving middleware can handle them, causing images and favicons to return 404 errors.

```
app.get(['/img/*splat', '/favicons/*splat'], (_req, res) => {
// if we made it past the express.static for these, then we're missing something.
// So we'll just send a 404 and won't bother calling other middleware.
res.status(404).send('Not found')
})

```
Current Behavior
When this handler is placed before the dev/prod server setup static files at /img/* and /favicons/* paths return 404 errors, unless the full /public/img path is used.

Expected Behavior
The 404 handler should only trigger after Express has attempted to serve static files from the public directory.

Solution

The 404 handler needs to be moved after the static file middleware setup block , so that:

In development: Vite middleware attempts to serve the files first
In production: express.static attempts to serve the files first
Only if neither finds the file, the 404 handler responds

Example:
```
if (IS_DEV) {
console.log('Starting development server')
const viteDevServer = await import('vite').then((vite) =>
vite.createServer({
server: { middlewareMode: true },
// We tell Vite we are running a custom app instead of
// the SPA default so it doesn't run HTML middleware
appType: 'custom',
}),
)
app.use(viteDevServer.middlewares)
app.use(async (req, res, next) => {
try {
const source = await viteDevServer.ssrLoadModule('./server/app.ts')
return await source.app(req, res, next)
} catch (error) {
if (typeof error === 'object' && error instanceof Error) {
viteDevServer.ssrFixStacktrace(error)
}
next(error)
}
})
} else {
console.log('Starting production server')
// React Router fingerprints its assets so we can cache forever.
app.use(
'/assets',
express.static('build/client/assets', {
immutable: true,
maxAge: '1y',
fallthrough: false,
}),
)
// Everything else (like favicon.ico) is cached for an hour. You may want to be
// more aggressive with this caching.
app.use(express.static('build/client', { maxAge: '1h' }))
app.use(await import(BUILD_PATH).then((mod) => mod.app))
}

app.get(['/img/*splat', '/favicons/*splat'], (_req, res) => {
// if we made it past the express.static for these, then we're missing something.
// So we'll just send a 404 and won't bother calling other middleware.
res.status(404).send('Not found')
})
```

Guía de contribución

Abrir la guía de contribución

Línea de trabajo

Comienza con la entrada del servidor que contiene el bloque de middleware de desarrollo/producción con IS_DEV y revisa cómo carga server/app.ts en desarrollo. Verifica que Vite o express.static gestione /img/* y /favicons/* antes del controlador de fallback; se considera terminado cuando los archivos estáticos existentes se sirven y los archivos inexistentes siguen recibiendo la respuesta 404.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
express, typescript, vite
Área
backend, web-dev
Tipo de issue
Error
Dificultad
2/5
Tiempo estimado
1-3 horas
Estado de actividad
Estancado
Claridad
Bien especificado
Aptitud para principiantes
55/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.