epicweb-dev / epicweb-dev/epic-stack
/img/* and /favicons/* 404 handler prevents static file serving when placed before dev/prod middleware
- Ngôn ngữ chính
- TypeScript
- Star
- 5.5k
- Fork
- 460
- Merge trung bình
- 2 giờ 43 phút
- Pull request đã merge (30 ngày)
- 1
Mô tả
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')
})
```
Hướng dẫn đóng góp
Hướng nghiên cứu
Bắt đầu với entry của server chứa block middleware phát triển/sản xuất có IS_DEV và xem xét cách nó tải server/app.ts trong môi trường phát triển. Xác minh rằng Vite hoặc express.static xử lý /img/* và /favicons/* trước fallback handler; hoàn tất khi các tệp tĩnh hiện có được phục vụ và các tệp không tồn tại vẫn nhận được phản hồi 404.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- express, typescript, vite
- Lĩnh vực
- backend, web-dev
- Loại issue
- Lỗi
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức độ hoạt động
- Đình trệ
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức phù hợp với người mới
- 55/100