-
-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathvite.config.ts
More file actions
101 lines (98 loc) · 4.08 KB
/
Copy pathvite.config.ts
File metadata and controls
101 lines (98 loc) · 4.08 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
import { readdirSync } from "node:fs";
import { fileURLToPath } from "node:url";
import mdx from "@mdx-js/rollup";
import tailwindcss from "@tailwindcss/vite";
import { devtools } from "@tanstack/devtools-vite";
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
import viteReact from "@vitejs/plugin-react";
import { nitro } from "nitro/vite";
import rehypeSlug from "rehype-slug";
import remarkFrontmatter from "remark-frontmatter";
import remarkGfm from "remark-gfm";
import remarkMdxFrontmatter from "remark-mdx-frontmatter";
import { defineConfig } from "vite";
// Static MDX articles: every src/content/<collection>/<slug>.mdx becomes /-/<collection>/<slug>.
// Listed here so the build prerenders them to plain HTML (no SSR invocation per crawl —
// see #70's cost concern) and emits them into the generated sitemap.
function contentSlugs(collection: string): string[] {
return readdirSync(
fileURLToPath(new URL(`./src/content/${collection}`, import.meta.url)),
)
.filter((f) => f.endsWith(".mdx"))
.map((f) => f.replace(/\.mdx$/, ""));
}
const metricSlugs = contentSlugs("metrics");
const orgSlugs = contentSlugs("organizations");
const postSlugs = contentSlugs("posts");
const config = defineConfig({
resolve: { tsconfigPaths: true },
// @resvg/resvg-js is a native Node addon (.node binary). The dev-mode dependency
// optimizer scans it via the OG route's imports and crashes trying to parse the
// binary as JS (UNLOADABLE_DEPENDENCY). It only ever runs in server handlers, so
// keep it out of prebundling; prod builds were never affected (handlers are
// tree-shaken out of the client there).
optimizeDeps: { exclude: ["@resvg/resvg-js"] },
plugins: [
devtools(),
tailwindcss(),
// MDX must transform before React; frontmatter is exported for head()/listings.
{
enforce: "pre",
...mdx({
remarkPlugins: [remarkFrontmatter, remarkMdxFrontmatter, remarkGfm],
rehypePlugins: [rehypeSlug],
}),
},
tanstackStart({
// Prerender config only. The sitemap is NOT generated here: a single-segment file
// like /sitemap.xml written into the client output isn't in nitro's static-asset
// manifest, so the `$user` catch-all shadows it at runtime. It's served instead by
// an explicit route (src/routes/sitemap[.]xml.tsx), the same trick robots.txt uses.
prerender: { autoStaticPathsDiscovery: false },
pages: [
// Homepage is DB-driven — never prerendered (and listed in the sitemap route).
{
path: "/",
prerender: { enabled: false },
},
// `enabled: true` must be explicit — it's what switches prerendering on for
// the whole build (a page relying on the schema default doesn't). And
// `crawlLinks` (default true) must be off, or in-article links to live pages
// (e.g. /torvalds,gaearon) get baked into stale static HTML at build time.
//
// All editorial content lives under the reserved /-/ namespace: "-" can never
// be a GitHub login (no leading/trailing hyphens), so nothing here can shadow
// the single-segment $user route — and inside the namespace sections may own
// their bare prefix, so the metrics hub is /-/metrics directly. Old URLs
// (/sponsoring, /metrics/*, /organizations/*) 301 via thin redirect routes
// and are deliberately absent from this list.
{
path: "/-/metrics",
prerender: { enabled: true, crawlLinks: false },
},
// The sponsor pitch page — static content, so prerendered like the explainers.
{
path: "/-/sponsoring",
prerender: { enabled: true, crawlLinks: false },
},
...metricSlugs.map((slug) => ({
path: `/-/metrics/${slug}`,
prerender: { enabled: true, crawlLinks: false },
})),
// Organization-context explainers.
...orgSlugs.map((slug) => ({
path: `/-/organizations/${slug}`,
prerender: { enabled: true, crawlLinks: false },
})),
// Standalone posts, flat under /-/ (leaderboard rankings etc).
...postSlugs.map((slug) => ({
path: `/-/${slug}`,
prerender: { enabled: true, crawlLinks: false },
})),
],
}),
nitro(),
viteReact(),
],
});
export default config;