-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathvite.config.ts
More file actions
118 lines (106 loc) · 3.94 KB
/
Copy pathvite.config.ts
File metadata and controls
118 lines (106 loc) · 3.94 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
import {defineConfig, loadEnv} from 'vite'
import react from '@vitejs/plugin-react-swc'
import path from "path"
import svgr from "vite-plugin-svgr";
import sitemap from 'vite-plugin-sitemap';
import fs from "node:fs/promises";
const DIST_DIR = path.resolve("dist");
const STATIC_ROUTES = ['/', '/statistics', '/instances'];
function routeToDir(route: string) {
if (route === "/") return DIST_DIR;
return path.join(DIST_DIR, route.replace(/^\//, ""));
}
async function writeStaticRouteFile(route: string) {
if (route === "/") return;
const baseHtmlPath = path.join(DIST_DIR, "index.html");
const dir = routeToDir(route);
const linkPath = path.join(dir, "index.html");
const relativeTarget = path.relative(dir, baseHtmlPath);
await fs.mkdir(dir, { recursive: true });
await fs.symlink(relativeTarget, linkPath, "file");
}
async function addTrailingSlashToSitemapLocs() {
const sitemapPath = path.join(DIST_DIR, "sitemap.xml");
try {
const sitemap = await fs.readFile(sitemapPath, "utf-8");
const updated = sitemap.replace(/<loc>([^<]+)<\/loc>/g, (_match, loc: string) => {
const normalizedLoc = loc.endsWith("/") ? loc : `${loc}/`;
return `<loc>${normalizedLoc}</loc>`;
});
if (updated !== sitemap) {
await fs.writeFile(sitemapPath, updated, "utf-8");
}
} catch (error) {
console.warn(`⚠️ Failed to post-process sitemap.xml: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
const fetchInstanceRoutes = async (apiUrl: string) => {
try {
const response = await fetch(`${apiUrl}/instances`);
if (!response.ok) throw new Error(`API returned ${response.status}`);
const data = await response.json();
return data.instances.map((instance: { name: string }) => {
const normalized = instance.name.replace(/^https?:\/\//i, "");
const encoded = encodeURIComponent(normalized).replace(/\./g, "%2E");
return `/instances/${encoded}`;
});
} catch (error) {
console.warn(`⚠️ Failed to fetch instances for sitemap: ${error instanceof Error ? error.message : 'Unknown error'}`);
return [];
}
};
// https://vitejs.dev/config/
export default defineConfig(async ({mode}) => {
const env = loadEnv(mode, process.cwd(), "");
const instanceRoutes = await fetchInstanceRoutes(env.VITE_APP_API_URL);
const dynamicRoutes = [...STATIC_ROUTES, ...instanceRoutes];
return {
plugins: [
svgr(),
react(),
sitemap({
hostname: 'https://scanner.etherpad.org',
dynamicRoutes,
exclude: ['/404', '/'],
priority: {
'*': 0.8,
'/instances': 1.0,
'/statistics': 1.0,
},
changefreq: {
'*': 'weekly',
'/instances': 'daily',
'/statistics': 'daily',
}
}),
{
name: "create-route-symlinks",
closeBundle: async () => {
await Promise.all(dynamicRoutes.map((route) => writeStaticRouteFile(route.replaceAll("%2E", "."))));
},
},
{
name: "add-slash-location-end",
closeBundle: async () => {
await addTrailingSlashToSitemapLocs();
},
},
],
base: '/',
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
server: {
host: '0.0.0.0',
proxy: {
"/api": {
target: "https://ether-scan.stefans-entwicklerecke.de/api",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, "")
},
},
}
}
})