-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
135 lines (121 loc) · 4.04 KB
/
Copy pathserver.js
File metadata and controls
135 lines (121 loc) · 4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
const express = require('express');
const path = require('path');
const fs = require('fs');
const compression = require('compression');
require('dotenv').config();
const app = express();
const PORT = process.env.PORT || 3000;
const BASE_URL = process.env.BASE_URL || 'https://sua-url.vercel.app';
// Simple in-memory cache for HTML pages (LRU-like with max size)
const cache = new Map();
const MAX_CACHE_ITEMS = 20;
function getFromCache(key) {
return cache.get(key);
}
function setToCache(key, value) {
if (cache.has(key)) {
cache.delete(key);
}
cache.set(key, value);
if (cache.size > MAX_CACHE_ITEMS) {
// Evict the oldest inserted
const firstKey = cache.keys().next().value;
cache.delete(firstKey);
}
}
app.use(compression());
// Serve static assets with long-term caching
app.use('/assets', express.static(path.join(__dirname, 'assets'), {
etag: true,
maxAge: '1d',
setHeaders: (res, filePath) => {
if (/\.(svg|png|jpg|jpeg|gif|css|js)$/i.test(filePath)) {
res.setHeader('Cache-Control', 'public, max-age=86400, immutable');
}
}
}));
// Serve src folder for CSS, JSON, etc.
app.use('/src', express.static(path.join(__dirname, 'src')));
app.get('/', (req, res) => {
const index = path.join(__dirname, 'src', 'pages', 'index.html');
if (fs.existsSync(index)) {
res.setHeader('Content-Type', 'text/html; charset=utf-8');
return res.sendFile(index);
}
return res.redirect('/roadmap');
});
app.get('/roadmap', (req, res) => {
const roadmap = path.join(__dirname, 'src', 'pages', 'roadmap.html');
if (fs.existsSync(roadmap)) {
res.setHeader('Content-Type', 'text/html; charset=utf-8');
return res.sendFile(roadmap);
}
return res.redirect('/');
});
app.get(['/ferramentas', '/tools'], (req, res) => {
const tools = path.join(__dirname, 'src', 'pages', 'tools.html');
if (fs.existsSync(tools)) {
res.setHeader('Content-Type', 'text/html; charset=utf-8');
return res.sendFile(tools);
}
return res.redirect('/');
});
app.get('/infografico/:id', (req, res) => {
const id = req.params.id;
if (!/^\d+$/.test(id)) {
return res.status(400).send('ID inválido');
}
let file = path.join(__dirname, 'src', 'pages', `${id}.page.html`);
if (!fs.existsSync(file)) {
file = path.join(__dirname, `${id}.page.html`);
}
try {
let html = getFromCache(file);
if (!html) {
if (!fs.existsSync(file)) {
return res.status(404).send('Infográfico não encontrado');
}
html = fs.readFileSync(file, 'utf-8');
setToCache(file, html);
}
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.setHeader('Cache-Control', 'public, max-age=300'); // cache de página por 5 min
return res.send(html);
} catch (err) {
console.error('Erro ao servir página:', err);
return res.status(500).send('Erro interno do servidor');
}
});
// Sitemap XML para SEO
app.get('/sitemap.xml', (req, res) => {
const sitemapPath = path.join(__dirname, 'sitemap.xml');
if (fs.existsSync(sitemapPath)) {
let sitemap = fs.readFileSync(sitemapPath, 'utf-8');
// Substitui a URL base se necessário
if (BASE_URL !== 'https://example.com') {
sitemap = sitemap.replace(/https:\/\/example\.com/g, BASE_URL);
}
res.setHeader('Content-Type', 'application/xml; charset=utf-8');
res.setHeader('Cache-Control', 'public, max-age=3600'); // cache por 1 hora
return res.send(sitemap);
}
return res.status(404).send('Sitemap não encontrado');
});
// Robots.txt para SEO
app.get('/robots.txt', (req, res) => {
const robotsTxt = `User-agent: *
Allow: /
Disallow: /node_modules/
Disallow: /package.json
Disallow: /package-lock.json
Sitemap: ${BASE_URL}/sitemap.xml
`;
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
res.setHeader('Cache-Control', 'public, max-age=86400'); // cache por 1 dia
return res.send(robotsTxt);
});
app.listen(PORT, () => {
console.log(`Servidor iniciado em http://localhost:${PORT}`);
console.log(`URL base configurada: ${BASE_URL}`);
console.log(`Sitemap disponível em: ${BASE_URL}/sitemap.xml`);
});