Skip to content

Commit 15d3d95

Browse files
committed
docs: 重构各模块首页与侧边栏,新增子目录索引页
1 parent 354db22 commit 15d3d95

47 files changed

Lines changed: 3682 additions & 330 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/.vuepress/sidebar/index.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ export default sidebar({
3939
collapsible: true,
4040
prefix: "interview-preparation/",
4141
children: [
42+
{
43+
text: "面试准备知识体系",
44+
link: "/interview-preparation/",
45+
},
4246
"backend-interview-plan",
4347
"teach-you-how-to-prepare-for-the-interview-hand-in-hand",
4448
"resume-guide",
@@ -56,6 +60,10 @@ export default sidebar({
5660
collapsible: true,
5761
prefix: "java/",
5862
children: [
63+
{
64+
text: "Java 知识体系",
65+
link: "/java/",
66+
},
5967
{
6068
text: "基础",
6169
prefix: "basis/",
@@ -180,6 +188,10 @@ export default sidebar({
180188
prefix: "database/",
181189
collapsible: true,
182190
children: [
191+
{
192+
text: "数据库知识体系",
193+
link: "/database/",
194+
},
183195
{
184196
text: "基础",
185197
icon: ICONS.BASIC,
@@ -272,6 +284,10 @@ export default sidebar({
272284
prefix: "tools/",
273285
collapsible: true,
274286
children: [
287+
{
288+
text: "开发工具知识体系",
289+
link: "/tools/",
290+
},
275291
{
276292
text: "Maven",
277293
icon: ICONS.MAVEN,
@@ -337,6 +353,10 @@ export default sidebar({
337353
prefix: "system-design/",
338354
collapsible: true,
339355
children: [
356+
{
357+
text: "系统设计知识体系",
358+
link: "/system-design/",
359+
},
340360
{
341361
text: "基础知识",
342362
prefix: "basis/",
@@ -394,6 +414,10 @@ export default sidebar({
394414
prefix: "distributed-system/",
395415
collapsible: true,
396416
children: [
417+
{
418+
text: "分布式系统知识体系",
419+
link: "/distributed-system/",
420+
},
397421
{
398422
text: "⭐分布式高频面试题",
399423
link: "distributed-system-interview-questions",
@@ -487,6 +511,10 @@ export default sidebar({
487511
prefix: "high-performance/",
488512
collapsible: true,
489513
children: [
514+
{
515+
text: "高性能系统知识体系",
516+
link: "/high-performance/",
517+
},
490518
{
491519
text: "⭐高性能系统设计高频面试题",
492520
link: "high-performance-interview-questions",
@@ -532,6 +560,10 @@ export default sidebar({
532560
prefix: "high-availability/",
533561
collapsible: true,
534562
children: [
563+
{
564+
text: "高可用系统知识体系",
565+
link: "/high-availability/",
566+
},
535567
{
536568
text: "⭐高可用系统面试题总结",
537569
link: "high-availability-interview-questions",

docs/.vuepress/theme.ts

Lines changed: 182 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { getText } from "@vuepress/helper";
12
import { getDirname, path } from "vuepress/utils";
23
import { hopeTheme } from "vuepress-theme-hope";
34

@@ -21,6 +22,176 @@ const docsearchOptions =
2122
},
2223
}
2324
: null;
25+
const MIN_META_DESCRIPTION_LENGTH = 150;
26+
const MAX_META_DESCRIPTION_LENGTH = 160;
27+
28+
const segmentDisplayNames = {
29+
ai: "AI",
30+
"ai-coding": "AI 编程",
31+
algorithms: "算法",
32+
basis: "基础知识",
33+
books: "技术书籍",
34+
collection: "Java 集合",
35+
concurrent: "Java 并发",
36+
"cs-basics": "计算机基础",
37+
"data-structure": "数据结构",
38+
database: "数据库",
39+
"distributed-process-coordination": "分布式协调",
40+
"distributed-system": "分布式系统",
41+
docker: "Docker",
42+
elasticsearch: "Elasticsearch",
43+
framework: "开发框架",
44+
git: "Git",
45+
gradle: "Gradle",
46+
"high-availability": "高可用",
47+
"high-performance": "高性能",
48+
"interview-preparation": "面试准备",
49+
io: "Java IO",
50+
java: "Java",
51+
javaguide: "JavaGuide",
52+
jvm: "JVM",
53+
"message-queue": "消息队列",
54+
mysql: "MySQL",
55+
network: "计算机网络",
56+
"new-features": "Java 新特性",
57+
"open-source-project": "开源项目",
58+
"operating-system": "操作系统",
59+
protocol: "分布式协议与算法",
60+
rag: "RAG",
61+
redis: "Redis",
62+
rpc: "RPC",
63+
security: "安全",
64+
sql: "SQL",
65+
"system-design": "系统设计",
66+
tools: "开发工具",
67+
zookeeper: "ZooKeeper",
68+
};
69+
70+
const normalizeDescriptionText = (value) =>
71+
String(value ?? "")
72+
.replace(/<[^>]+>/g, " ")
73+
.replace(/&nbsp;/g, " ")
74+
.replace(/&amp;/g, "&")
75+
.replace(/&lt;/g, "<")
76+
.replace(/&gt;/g, ">")
77+
.replace(/&quot;/g, '"')
78+
.replace(/&#39;/g, "'")
79+
.replace(/\s+/g, " ")
80+
.trim();
81+
82+
const toArray = (value) => {
83+
if (Array.isArray(value)) return value;
84+
return value ? [value] : [];
85+
};
86+
87+
const formatPathSegment = (segment) =>
88+
segmentDisplayNames[segment] ??
89+
decodeURIComponent(segment)
90+
.replace(/-/g, " ")
91+
.replace(/\b\w/g, (char) => char.toUpperCase());
92+
93+
const getPathTopic = (page) =>
94+
page.path.split("/").filter(Boolean).map(formatPathSegment).join(" / ");
95+
96+
const getHeaderTitles = (page) =>
97+
toArray(page.headers)
98+
.map(({ title }) => normalizeDescriptionText(title))
99+
.filter(Boolean)
100+
.slice(0, 4);
101+
102+
const getPageText = (page, app) =>
103+
normalizeDescriptionText(
104+
getText(
105+
page.data.excerpt ?? page.contentRendered ?? page.content ?? "",
106+
app.siteData.base,
107+
{
108+
length: 220,
109+
singleLine: true,
110+
},
111+
),
112+
);
113+
114+
const trimDescription = (description) => {
115+
if (description.length <= MAX_META_DESCRIPTION_LENGTH) return description;
116+
117+
const trimmed = description.slice(0, MAX_META_DESCRIPTION_LENGTH);
118+
const lastStop = Math.max(
119+
trimmed.lastIndexOf("。"),
120+
trimmed.lastIndexOf("!"),
121+
trimmed.lastIndexOf("?"),
122+
trimmed.lastIndexOf(";"),
123+
trimmed.lastIndexOf(";"),
124+
);
125+
126+
if (lastStop >= MIN_META_DESCRIPTION_LENGTH - 5)
127+
return trimmed.slice(0, lastStop + 1);
128+
129+
const lastSoftStop = Math.max(
130+
trimmed.lastIndexOf(","),
131+
trimmed.lastIndexOf("、"),
132+
trimmed.lastIndexOf(","),
133+
);
134+
135+
if (lastSoftStop >= MIN_META_DESCRIPTION_LENGTH - 5) {
136+
const base = trimmed.slice(0, lastSoftStop).replace(/[,;\s]+$/, "");
137+
const result = `${base}等核心内容。`;
138+
139+
return result.length <= MAX_META_DESCRIPTION_LENGTH
140+
? result
141+
: `${result.slice(0, MAX_META_DESCRIPTION_LENGTH - 1)}。`;
142+
}
143+
144+
return `${description.slice(0, MAX_META_DESCRIPTION_LENGTH - 1)}。`;
145+
};
146+
147+
const buildSeoDescription = (page, app) => {
148+
const existingDescription = normalizeDescriptionText(
149+
page.frontmatter.description,
150+
);
151+
152+
if (existingDescription.length >= MIN_META_DESCRIPTION_LENGTH)
153+
return trimDescription(existingDescription);
154+
155+
if (page.path === "/")
156+
return trimDescription(
157+
"JavaGuide 是一份面向 Java 后端开发者和面试准备人群的学习指南,系统覆盖 Java 基础、集合、并发、JVM、MySQL、Redis、分布式、高并发、高可用、系统设计、消息队列、计算机基础和 AI 应用开发等核心知识,适合校招社招复习、查缺补漏和规划学习路线。",
158+
);
159+
160+
if (page.path === "/home.html")
161+
return trimDescription(
162+
"JavaGuide 首页聚合 Java 后端学习路线、核心知识体系和高频面试题入口,覆盖 Java 基础、并发、JVM、数据库、Redis、分布式、系统设计、高性能、高可用、计算机基础和 AI 应用开发,帮助读者快速定位重点内容。",
163+
);
164+
165+
if (page.path === "/404.html")
166+
return trimDescription(
167+
"JavaGuide 页面未找到提示页,帮助读者返回 Java 面试指南、后端通用面试知识、计算机基础、数据库、Redis、分布式、系统设计和 AI 应用开发等核心内容入口,继续定位学习资料、面试题总结和实践文章。",
168+
);
169+
170+
const title = normalizeDescriptionText(page.title);
171+
const category = toArray(page.frontmatter.category)
172+
.map(normalizeDescriptionText)
173+
.filter(Boolean);
174+
const tags = toArray(page.frontmatter.tag ?? page.frontmatter.tags)
175+
.map(normalizeDescriptionText)
176+
.filter(Boolean)
177+
.slice(0, 4);
178+
const headers = getHeaderTitles(page);
179+
const focusItems = [...headers, ...tags].filter(Boolean).slice(0, 5);
180+
const topic = getPathTopic(page) || title || category[0] || "JavaGuide";
181+
const pageText = getPageText(page, app);
182+
const parts = [
183+
existingDescription || (title ? `${title}:` : ""),
184+
focusItems.length ? `重点围绕 ${focusItems.join("、")} 等内容展开。` : "",
185+
`结合 JavaGuide 知识体系梳理 ${topic} 的核心概念、实践方法、常见问题和高频面试考点,覆盖原理分析、使用场景、方案对比与经验总结,适合后端开发者系统学习、面试复习、快速定位重点内容和查缺补漏。`,
186+
pageText && !existingDescription.includes(pageText.slice(0, 24))
187+
? pageText
188+
: "",
189+
];
190+
191+
return trimDescription(
192+
normalizeDescriptionText(parts.filter(Boolean).join("")),
193+
);
194+
};
24195

25196
export default hopeTheme({
26197
hostname: "https://javaguide.cn/",
@@ -80,7 +251,17 @@ export default hopeTheme({
80251
seo: {
81252
canonical: "https://javaguide.cn",
82253
fallBackImage: "https://javaguide.cn/logo.png",
83-
customHead: (head, page) => {
254+
ogp: (ogp, page, app) => ({
255+
...ogp,
256+
"og:description": buildSeoDescription(page, app),
257+
}),
258+
jsonLd: (jsonLD, page, app) => ({
259+
...jsonLD,
260+
description: buildSeoDescription(page, app),
261+
}),
262+
customHead: (head, page, app) => {
263+
page.frontmatter.description = buildSeoDescription(page, app);
264+
84265
if (page.path === "/")
85266
head.push([
86267
"script",

0 commit comments

Comments
 (0)