74 lines
1.8 KiB
JavaScript
74 lines
1.8 KiB
JavaScript
import { createServer } from 'node:http'
|
|
import { readFile } from 'node:fs/promises'
|
|
import { join, extname } from 'node:path'
|
|
import { existsSync } from 'node:fs'
|
|
|
|
const PORT = process.env.PORT || 8080
|
|
const DIST_DIR = process.env.DIST_DIR || './dist'
|
|
|
|
const mimeTypes = {
|
|
'.html': 'text/html',
|
|
'.js': 'application/javascript',
|
|
'.css': 'text/css',
|
|
'.json': 'application/json',
|
|
'.png': 'image/png',
|
|
'.jpg': 'image/jpeg',
|
|
'.svg': 'image/svg+xml',
|
|
'.ico': 'image/x-icon',
|
|
'.woff': 'font/woff',
|
|
'.woff2': 'font/woff2',
|
|
}
|
|
|
|
async function serveFile(res, filePath) {
|
|
try {
|
|
const content = await readFile(filePath)
|
|
const ext = extname(filePath)
|
|
const contentType = mimeTypes[ext] || 'application/octet-stream'
|
|
res.writeHead(200, { 'Content-Type': contentType })
|
|
res.end(content)
|
|
} catch {
|
|
res.writeHead(404)
|
|
res.end('Not found')
|
|
}
|
|
}
|
|
|
|
const server = createServer(async (req, res) => {
|
|
let url = req.url.split('?')[0]
|
|
|
|
// Try exact file first
|
|
let filePath = join(DIST_DIR, url)
|
|
if (existsSync(filePath) && !existsSync(join(DIST_DIR, url, 'index.html'))) {
|
|
await serveFile(res, filePath)
|
|
return
|
|
}
|
|
|
|
// Try directory index
|
|
const indexPaths = [
|
|
join(DIST_DIR, url, 'index.html'),
|
|
join(DIST_DIR, 'index.html'),
|
|
]
|
|
for (const idx of indexPaths) {
|
|
if (existsSync(idx)) {
|
|
await serveFile(res, idx)
|
|
return
|
|
}
|
|
}
|
|
|
|
// Try with .html extension
|
|
if (!extname(url)) {
|
|
const htmlPath = join(DIST_DIR, url + '.html')
|
|
if (existsSync(htmlPath)) {
|
|
await serveFile(res, htmlPath)
|
|
return
|
|
}
|
|
}
|
|
|
|
// 404
|
|
res.writeHead(404)
|
|
res.end('Not found')
|
|
})
|
|
|
|
server.listen(PORT, '0.0.0.0', () => {
|
|
console.log(`Server running at http://0.0.0.0:${PORT}`)
|
|
console.log(`Serving files from ${DIST_DIR}`)
|
|
}) |