Compare commits

...

4 Commits

Author SHA1 Message Date
Chuyaoyuan 783779f4ae update menu 2026-05-07 12:03:58 +08:00
Chuyaoyuan 697d3773c8 update v3.10.1
Co-authored-by: Copilot <copilot@github.com>
2026-05-06 19:14:45 +08:00
Chuyaoyuan c44855e573 update 2026-04-30 18:52:44 +08:00
Chuyaoyuan da65b3e73d update 2026-04-29 19:03:25 +08:00
39 changed files with 20123 additions and 24225 deletions
View File
+57
View File
@@ -0,0 +1,57 @@
name: Deploy to Production
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
env:
ALGOLIA_APP_ID: ${{ secrets.ALGOLIA_APP_ID }}
ALGOLIA_API_KEY: ${{ secrets.ALGOLIA_API_KEY }}
- name: Upload build artifact
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
uses: actions/upload-artifact@v4
with:
name: build
path: build/
retention-days: 1
deploy:
name: Deploy
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
steps:
- name: Download build artifact
uses: actions/download-artifact@v4
with:
name: build
path: build/
- name: Deploy via FTP
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
with:
server: ${{ secrets.FTP_SERVER }}
username: ${{ secrets.FTP_USER }}
password: ${{ secrets.FTP_PWD }}
local-dir: ./build/
server-dir: code-docs/www/
-28
View File
@@ -1,28 +0,0 @@
on: push
name: 🚀 Deploy website on push
jobs:
web-deploy:
name: 🎉 Deploy
runs-on: ubuntu-latest
steps:
- name: 🚚 Get latest code
uses: actions/checkout@v2.3.2
- name: Use Node.js 12
uses: actions/setup-node@v2-beta
with:
node-version: '12'
- name: 🔨 Build Project
run: |
npm install
npm run build
- name: 📂 Sync files
uses: SamKirkland/FTP-Deploy-Action@4.0.0
with:
server: ${{ secrets.ftp_server }}
username: ${{ secrets.ftp_user }}
password: ${{ secrets.ftp_pwd }}
local-dir: ./build/
server-dir: code-docs/www/
+7
View File
@@ -108,3 +108,10 @@ dist
build
.idea
# macOS
.DS_Store
# Environment variables (never commit secrets)
.env.local
.env.*.local
+252
View File
@@ -0,0 +1,252 @@
# CodeDocs 内容架构规划
## 愿景
为全栈、全端工程师打造一个**可查、可参考、可速查**的技术文档与知识库,覆盖从底层原理、框架实战、到面试突破的全链路。
## 一级分类(顶部菜单)
### 1. 📚 技术文档
主要技术栈与框架学习
#### 1.1 ⚙️ 后端技术
**目标用户**: 后端工程师、全栈开发者
- **Java 生态**
- Spring Framework / Spring Boot / Spring Cloud
- 核心概念 (IoC, AOP, Bean 生命周期)
- 常用注解与配置方式
- 微服务架构与分布式方案
- 性能优化与监控
- JVM 优化与性能调试
- 并发编程 (ThreadPool, Lock, Concurrent 工具)
- **数据库与缓存**
- SQL 优化与查询计划
- MySQL 索引设计与事务管理
- NoSQL (Redis, MongoDB)
- 分布式缓存方案
- **消息队列与异步**
- RabbitMQ / Kafka / RocketMQ
- 事件驱动架构
- **分布式系统**
- 一致性 (Raft, Consensus)
- 服务治理 (Nacos, Consul)
- 链路追踪 (Jaeger, SkyWalking)
#### 1.2 ⚛️ 前端开发
**目标用户**: 前端工程师、全栈开发者
- **核心框架**
- React
- Hooks 深度解析
- 状态管理 (Redux, Zustand, Jotai)
- 性能优化 (Code Splitting, Memo, Lazy)
- SSR / SSG 方案
- Vue 3
- Composition API 最佳实践
- 响应性原理
- Pinia 状态管理
- **工程化**
- 构建工具 (Webpack, Vite, Turbopack)
- 包管理 (npm, pnpm, yarn)
- CI/CD 流程
- **性能与体验**
- Web 性能指标 (LCP, FID, CLS)
- 渲染优化
- 网络优化 (CDN, 压缩)
- **跨端开发**
- React Native
- Electron
- 小程序 (微信、支付宝)
#### 1.3 🧠 算法与面试
**目标用户**: 求职者、算法爱好者
- **数据结构**
- 数组、链表、栈、队列
- 树 (二叉树、AVL、红黑树、B 树)
-
- 堆、优先队列
- **经典算法**
- 排序与查找
- 动态规划
- 贪心算法
- 回溯与递归
- **编程面试题**
- 按类型分类 (String, Array, Tree, Graph, DP)
- 按难度分级
- 按公司出现频率分类
- **系统设计**
- 高并发架构设计
- 分布式系统设计
- 大数据处理
---
## 二级分类 - 导航示例
### 技术文档 > 后端技术
```
├── Spring 全家桶
│ ├── Spring Core (IoC, AOP)
│ ├── Spring MVC
│ ├── Spring Boot 实战
│ ├── Spring Cloud 微服务
│ └── Spring Data
├── JVM 与性能
│ ├── JVM 内存模型
│ ├── GC 调优
│ └── 性能分析工具
├── 并发编程
│ ├── 线程基础
│ ├── 锁与同步
│ ├── Concurrent 工具类
│ └── 实战案例
└── 数据库
├── MySQL 核心
├── 索引优化
├── 事务与隔离
└── 分布式事务
```
### 技术文档 > 前端开发
```
├── React 进阶
│ ├── Hooks 深入
│ ├── 状态管理对比
│ ├── 性能优化
│ └── Next.js / Remix
├── 工程化实践
│ ├── 构建系统选型
│ ├── 测试体系
│ ├── 发布流程
│ └── 监控与错误追踪
└── 跨端方案
├── React Native
├── Electron
└── 小程序开发
```
---
## 三级结构示例
每个主题采用标准化格式:
```
## 主题名称
### 📌 核心概念
- 定义与原理
- 为什么需要它
### 🔧 实践指南
- 快速开始
- 常见用法
- 最佳实践
### ⚡ 性能优化
- 性能指标
- 瓶颈分析
- 优化方案
### 🎯 面试必考
- 高频问题
- 答题思路
- 深度扩展
### 📚 参考资源
- 官方文档
- 推荐阅读
- 代码示例
```
---
## 2️⃣ 🛠️ 工具与资源(待扩展)
- **最佳实践**: 设计模式、代码规范、安全实践
- **常用链接**: 文档汇总、在线工具、社区论坛
- **推荐阅读**: 经典书籍、论文、博客精选
---
## 3️⃣ 📝 Blog
- 技术分享
- 学习笔记
- 行业资讯
---
## 内容组织策略
### 按学习路径分级
1. **快速入门** (⏱️ 5-10分钟)
- 适合初学者快速上手
2. **深度学习** (⏱️ 30分钟-1小时)
- 详细讲解原理与实践
3. **性能与优化** (⏱️ 1-2小时)
- 高级技巧与优化方案
4. **面试突破** (⏱️ 灵活)
- 高频问题与答题框架
### 搜索与过滤支持
- 按难度筛选
- 按学习时间筛选
- 按使用频率筛选
- 按技术栈筛选
---
## 实施优先级
### Phase 1 (当前)
- ✅ 首页设计升级(蓝色悬停动效)
- ✅ 多级菜单配置
- ✅ 内容分类框架
### Phase 2
- 迁移现有内容到新分类
- 补充 Spring 系列完整文档
- 补充 React 进阶指南
### Phase 3
- 补充算法与面试题库
- 添加交互式代码编辑器
- 性能与搜索优化
### Phase 4
- 用户反馈收集与迭代
- 内容深化与补充
- 社区建设
---
## 目标数据
| 指标 | 当前 | 目标 |
|-----|------|------|
| 文档页面数 | ~30 | 200+ |
| 一级分类 | 3 | 4+ |
| 二级分类 | ~6 | 15+ |
| 代码示例数 | ~10 | 100+ |
| 日均访问 | N/A | 1000+ |
---
## 参考标准
- 参考 Dyte Docs 的多级菜单、强大的搜索
- 参考 MDN 的结构化学习路径
- 参考 阿里技术文档 的工程最佳实践
+167 -24
View File
@@ -1,56 +1,199 @@
中文 &nbsp; | &nbsp; [English](./README.md)
<h1 align="center"> Code-Docs </h1>
<h3 align="center">这里是一些技术人的编程文档</h3>
<h1 align="center">CodeDocs 编程文档</h1>
<h3 align="center">一些技术人的编程文档网站 —— 涵盖后端、前端、算法</h3>
---
<p align="center">
<a href="./LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue" alt="License MIT"></a>
<img src="https://img.shields.io/badge/Docusaurus-3.7-green" alt="Docusaurus 3.7">
<img src="https://img.shields.io/badge/React-18-blue" alt="React 18">
<img src="https://img.shields.io/badge/TypeScript-5-blue" alt="TypeScript 5">
<img src="https://img.shields.io/badge/Node-%3E%3D20-brightgreen" alt="Node >= 20">
</p>
# 预览
[![sykhy4.md.png](https://z3.ax1x.com/2021/04/27/gpXhWR.png)](https://z3.ax1x.com/2021/04/27/gpXhWR.png)
## 简介
CodeDocs 是一个基于 [Docusaurus 3](https://docusaurus.io/) 构建的中文技术文档站,采用 React 18 + TypeScript 技术栈。
# 简介
基于React,使用Docusaurus构建,官网:[[docs.yaoyuan.io]](http://docs.yaoyuan.io/)
**官网**[docs.yaoyuan.io](http://docs.yaoyuan.io/)
# 在线体验
## 功能特性
- [[首页地址]](http://docs.cyy.im/)
- 📚 **系统化文档** — 后端(Spring Boot / Spring Cloud)、前端(React / Vue)、算法(LeetCode)分门别类
-**全文检索** — 集成 [Algolia DocSearch](https://docsearch.algolia.com/),毫秒级搜索
- 🔢 **数学公式** — 通过 KaTeX 渲染 LaTeX 数学公式(`remark-math` + `rehype-katex`
- 🌐 **国际化** — 支持中文 / English 双语切换(`i18n`
- 🌙 **深色模式** — 内置亮色 / 深色主题自动切换
- 🚀 **CI/CD** — GitHub Actions 自动构建 + FTP 部署
# 部署
## [一]、开发环境配置
## 技术栈
| 类别 | 技术 |
|------|------|
| 框架 | [Docusaurus 3.7](https://docusaurus.io/) |
| 前端 | React 18, TypeScript 5, MDX 3 |
| 样式 | CSS Modules, Infima |
| 数学渲染 | KaTeX (remark-math 6 + rehype-katex 7) |
| 搜索 | Algolia DocSearch |
| 构建 | Node.js 20, npm |
| CI/CD | GitHub Actions → FTP Deploy |
| 代码规范 | TypeScript 严格模式, ESLint (可扩展) |
## 目录结构
```
// 需Node 12以上,Git。
code-docs/
├── docs/ # 文档内容
│ ├── intro-docs.mdx # 文档首页介绍
│ ├── backend-doc/ # 后端文档
│ │ ├── SpringBoot/ # Spring Boot 系列
│ │ └── SpringCloud/ # Spring Cloud 系列
│ ├── frontend-doc/ # 前端文档
│ │ ├── React/ # React 系列
│ │ └── Vue/ # Vue 系列
│ └── LeetCode/ # 算法题解
│ ├── 1 - 100/ # 第 1 ~ 100 题
│ ├── 100 - 200/ # 第 100 ~ 200 题
│ └── CodingInterviews/ # 剑指 Offer 系列
├── blog/ # 博客文章
├── src/
│ ├── components/ # React 组件 (TSX)
│ ├── css/ # 全局样式
│ └── pages/ # 自定义页面 (TSX)
├── static/ # 静态资源 (图片等)
├── docusaurus.config.ts # Docusaurus 配置 (TypeScript)
├── sidebars.ts # 侧边栏配置
├── tsconfig.json # TypeScript 配置
├── babel.config.js # Babel 配置
├── package.json # 依赖管理
└── .github/workflows/deploy.yml # CI/CD 工作流
```
## [二]、下载代码
## 快速开始
```
// Github - https://gitee.com/chuyaoyuan/code-docs.git
### 环境要求
- **Node.js** >= 20 (推荐 LTS 版本)
- **npm** >= 10
- **Git**
### 安装 & 启动
```bash
# 1. 克隆仓库
git clone https://github.com/chuyaoyuan/code-docs.git
cd code-docs
# 2. 安装依赖
npm install
# 3. 本地开发 (热更新)
npm run start
# 4. 访问
# http://localhost:3000
```
### 常用命令
## [三]、运行启动
| 命令 | 说明 |
|------|------|
| `npm run start` | 启动本地开发服务器(热更新) |
| `npm run build` | 生产环境构建 |
| `npm run serve` | 预览生产构建产物 |
| `npm run typecheck` | TypeScript 类型检查 |
| `npm run write-translations` | 生成 i18n 翻译模板 |
| `npm run clear` | 清除 Docusaurus 缓存 |
```
// 1、代码导入IDE
npm install or cnpm install
## 环境变量
// 2、启动服务
npm run serve
本项目使用 Algolia DocSearch 进行全文检索,需要配置以下环境变量:
// 4、访问地址
http://localhost:3000
```bash
# 创建 .env.local 文件 (已在 .gitignore 中排除)
ALGOLIA_APP_ID=your_app_id
ALGOLIA_API_KEY=your_search_only_api_key
```
> 本地开发时通过 `dotenv` 自动加载 `.env.local`。CI 环境中通过 GitHub Secrets 注入。
## [四]、开源协议
## 部署
[MIT](https://opensource.org/licenses/MIT)
### GitHub Actions 自动部署
项目配置了 GitHub Actions 工作流(`.github/workflows/deploy.yml`):
- **PR → `main`**:仅执行构建校验,不部署
- **Push → `main`**:构建 + FTP 部署到生产服务器
需要在 GitHub 仓库 **Settings → Secrets** 中配置:
| Secret | 说明 |
|--------|------|
| `ALGOLIA_APP_ID` | Algolia Application ID |
| `ALGOLIA_API_KEY` | Algolia Search-Only API Key |
| `FTP_SERVER` | FTP 服务器地址 |
| `FTP_USER` | FTP 用户名 |
| `FTP_PWD` | FTP 密码 |
### 手动部署
```bash
npm run build
# 产物输出到 ./build/ 目录,部署到任意静态服务器即可
```
## 撰写文档
### 新增文档页
`docs/` 对应目录下创建 `.md``.mdx` 文件:
```md
---
sidebar_position: 1
---
# 文档标题
这里是文档内容。
```
- 纯 Markdown 内容使用 `.md` 扩展名
- 包含 JSX 组件(如 `<Tabs>``<span style={{}}>` 等)的文件须使用 `.mdx` 扩展名
### 数学公式
支持 LaTeX 语法,通过 KaTeX 渲染:
```md
行内公式:$E = mc^2$
独立公式块:
$$
\int_0^\infty f(x)\,dx
$$
```
### 新增博客
`blog/` 目录下创建 Markdown 文件:
```md
---
slug: my-post
title: 文章标题
author: 作者名
tags: [标签1, 标签2]
---
摘要内容。
<!--truncate-->
正文内容。
```
## 开源协议
[MIT](https://opensource.org/licenses/MIT) © Yaoyuan Chu
+310
View File
@@ -0,0 +1,310 @@
# CodeDocs 升级总结与实施指南
## 📋 已完成的升级
### 1️⃣ 首页样式升级 ✅
#### 变更清单
- **HomepageFeatures.tsx**:
- 从 3 个简单文本卡片 → 交互式卡片组件
- 支持图标、颜色、渐变背景
- 完整的 hover 动效和动画
- **HomepageFeatures.module.css**:
- 新增蓝色悬停动效 (`hover:text-primary`)
- 新增图标背景色变化
- 新增箭头滑出动画
- 新增卡片缩放 + 投影效果
- 新增分层渐变背景
- 响应式网格布局(3列→1列)
- **index.tsx**:
- 新增 3 个主要导航按钮
- 优化首页文案
- 增强视觉层级
#### 设计理念(参考 dyte-io/docs
```
卡片组成 = icon + title + description + hover-effect
├── Icon: 根据分类变色(蓝色/青色/粉色)
├── Title: hover 时变为主色 (#2160fd)
├── Border: hover 时从半透明→主色
└── Arrow: hover 时从隐藏→显示并滑入
```
---
### 2️⃣ 多级菜单配置 ✅
#### 变更清单
- **docusaurus.config.ts - navbar.items**:
```typescript
items: [
// 技术文档 - 3 级分类
{
type: 'dropdown',
label: '📚 技术文档',
items: [
'⚙️ 后端技术',
'⚛️ 前端开发',
'🧠 算法与面试'
]
},
// 工具与资源 - 预留扩展
{
type: 'dropdown',
label: '🛠️ 工具与资源',
items: [
'📖 最佳实践',
'🔗 常用链接',
'📚 推荐阅读'
]
},
// 其他链接
'📝 Blog',
'GitHub'
]
```
#### 菜单截图预期
```
顶部导航:
[📚 技术文档 ▼] [🛠️ 工具与资源 ▼] [📝 Blog] [GitHub]
下拉展开:
📚 技术文档 ▼
├─ ⚙️ 后端技术
├─ ⚛️ 前端开发
└─ 🧠 算法与面试
```
---
### 3️⃣ 样式系统升级 ✅
#### 变更清单
- **tailwind.config.js**: 新建
- 蓝色色系定义 (#2160fd)
- 青色色系支持
- 粉色色系支持
- 响应式断点优化
- **postcss.config.js**: 新建
- PostCSS 处理管道配置
- **custom.css**: 重写
- 原有 Infima 主色替换为蓝色 (#2160fd)
- 增加 Tailwind 导入(@import
- 新增 CSS 变量系统(支持深色模式)
- 新增 hero 背景渐变
#### 颜色对照表
| 用途 | 颜色 | 十六进制 | RGB |
|------|------|---------|-----|
| 主色 (Primary) | 蓝色 | #2160fd | rgb(33 96 253) |
| 悬停强调 | 深蓝 | #1850d8 | - |
| 次色 (Secondary) | 青色 | #06b6d4 | - |
| 三色 (Tertiary) | 粉色 | #ec4899 | - |
---
### 4️⃣ 内容架构规划 ✅
#### 文档位置
- `ARCHITECTURE_PLAN.md` - 完整规划书
#### 结构概览
```
一级菜单 (4 类)
├─ 📚 技术文档
│ ├─ ⚙️ 后端技术 (Java/Spring/Database/MQ/分布式)
│ ├─ ⚛️ 前端开发 (React/Vue/工程化/跨端)
│ └─ 🧠 算法与面试 (数据结构/算法/系统设计)
├─ 🛠️ 工具与资源 (best practices/links/reading)
├─ 📝 Blog (分享与资讯)
└─ GitHub (开源)
```
#### 内容分级(学习路径)
1. **快速入门** (⏱️ 5-10 分钟) - 适合初学
2. **深度学习** (⏱️ 30 分钟-1 小时) - 详解原理
3. **性能优化** (⏱️ 1-2 小时) - 高级技巧
4. **面试突破** (⏱️ 灵活) - 频考题
---
## 🚀 下一步操作
### 步骤 1: 本地验证 (NOW)
```bash
cd /opt/cyy/code-docs
# 若未完成 npm install,先安装依赖
npm install
# 启动开发服务器
npm start
# 验证内容:
# ✅ 首页 3 个卡片是否显示
# ✅ 卡片 hover 是否有蓝色效果
# ✅ 菜单是否显示下拉箭头
# ✅ 深色模式是否正常
```
### 步骤 2: 迁移现有内容 (Week 1)
```
当前文件:
docs/
├─ intro-docs.mdx ✅ 保留
├─ backend-doc/ ✅ 已有结构
├─ frontend-doc/ ✅ 已有结构
├─ LeetCode/ ✅ 已有结构
└─ ...
需要处理:
1. 更新 sidebars.ts 以支持新菜单
2. 验证所有链接有效性
3. 补充缺失的 intro-docs.md 文件
```
### 步骤 3: 菜单链接修复 (Week 1)
在 navbar 中验证以下路由存在:
- `/docs/backend-doc/intro-docs`
- `/docs/frontend-doc/intro-docs`
- `/docs/LeetCode/intro-docs`
### 步骤 4: 内容扩充计划 (Phase 2)
根据 ARCHITECTURE_PLAN.md 逐步添加:
**高优先级**:
- [ ] Spring Framework 核心(5-8 篇)
- [ ] React Hooks 深入(3-5 篇)
- [ ] LeetCode 精选题库(10-15 题)
**中优先级**:
- [ ] JVM 调优系列
- [ ] Vue 3 完整指南
- [ ] 系统设计案例
**低优先级**:
- [ ] 最佳实践合集
- [ ] 工具对比
- [ ] 推荐书籍
---
## 🎨 设计效果预览
### 首页卡片效果
```
┌─────────────────────────────────┐
│ [⚙️] 后端技术 │ → hover: border-blue, text-blue, arrow-in
│ │
│ 深度讲解 Spring Boot / Spring │
│ Cloud 核心概念、最佳实践... │
│ │
│ → │ (animated)
└─────────────────────────────────┘
动效细节:
- 渐变背景从灰→蓝色渐变
- 图标放大 10%,背景变蓝
- 标题变成蓝色 (#2160fd)
- 箭头从右侧滑入
- 整体卡片上移 4px
- 投影增强,显示深度感
```
### 顶部菜单效果
```
┌─ CodeDocs ─────┐ [📚 技术文档 ▼] [🛠️ 工具 ▼] [📝 Blog] [GitHub]
┌─────────────┐
│ ⚙️ 后端 │
│ ⚛️ 前端 │
│ 🧠 算法 │
└─────────────┘
```
---
## 📊 检查清单
- [ ] npm install 完成
- [ ] npm start 本地验证通过
- [ ] 首页卡片显示正常
- [ ] 卡片 hover 效果生效
- [ ] 菜单下拉正常
- [ ] 所有链接有效
- [ ] 深色模式测试
- [ ] 响应式(手机端)测试
---
## 📁 文件变更总结
| 文件 | 操作 | 说明 |
|-----|------|------|
| `src/components/HomepageFeatures.tsx` | ✏️ 修改 | 新组件结构 + 3 色卡片 |
| `src/components/HomepageFeatures.module.css` | ✏️ 重写 | 完整的悬停动效 |
| `src/pages/index.tsx` | ✏️ 修改 | 新的 CTA 按钮 |
| `src/css/custom.css` | ✏️ 重写 | 主色改蓝 + Tailwind 导入 |
| `docusaurus.config.ts` | ✏️ 修改 | 多级菜单配置 |
| `tailwind.config.js` | ✨ 新建 | Tailwind 配置 |
| `postcss.config.js` | ✨ 新建 | PostCSS 管道 |
| `package.json` | ✏️ 修改 | 已升级依赖版本 |
| `ARCHITECTURE_PLAN.md` | ✨ 新建 | 内容架构规划 |
---
## 🆘 常见问题
### Q1: npm install 很慢?
**A**: 使用 pnpm 或 npm 阿里镜像加速
```bash
npm install -g pnpm
pnpm install
```
### Q2: Tailwind 样式未生效?
**A**: 需要先完成 `npm install`,再运行 `npm start`
### Q3: 首页链接 404
**A**: 检查 `/docs` 下是否存在对应的文件夹:
```bash
ls -la docs/
# 应该看到:backend-doc/ frontend-doc/ LeetCode/
```
### Q4: 深色模式图标不清晰?
**A**: 在 custom.css 中针对 `[data-theme='dark']` 添加 color 覆盖
---
## 📞 后续支持
需要进一步升级:
1. **搜索优化** - 集成 Algolia 优化查询
2. **版本管理** - 为 SDK 文档添加版本切换(参考 dyte-io/docs
3. **API 文档** - 集成 OpenAPI / Swagger
4. **交互示例** - 嵌入 CodeSandbox / RunKit
5. **反馈系统** - 页面评分与问题报告
---
## 参考资源
- 📖 [Docusaurus 官方文档](https://docusaurus.io/)
- 🎨 [Tailwind CSS](https://tailwindcss.com/)
- 🔗 [dyte-io/docs 源代码](https://github.com/dyte-io/docs)
- 📚 [MDN 文档结构参考](https://developer.mozilla.org/)
---
**最后更新**: 2026-05-06
**更新者**: CodeDocs 升级系统
**版本**: v2.0
-18
View File
@@ -1,18 +0,0 @@
---
slug: hello-world
title: Hello Welcome
author: Endilie Yacop Sucipto
author_title: Maintainer of Docusaurus
author_url: https://github.com/endiliey
author_image_url: https://s3.ax1x.com/2021/02/26/6SEr4g.jpg
tags: [hello, chuyaoyuan]
---
Welcome to this blog. This blog is created .
欢迎来到这个博客。此博客已创建
<!--truncate-->
This is a test post.
A whole bunch of other information.
-11
View File
@@ -1,11 +0,0 @@
---
slug: join in
title: 加入到这里
author: yaoyuan chu
author_title: chuyaoyuan
author_url: https://github.com/chuyaoyuan
author_image_url: https://s3.ax1x.com/2021/02/26/6SEr4g.jpg
tags: [hola, code-docs]
---
这里是个公开的技术文档聚集之地,可以随时随地的发表新文档,GitHub:[**code-docs**](https://github.com/chuyaoyuan/code-docs).
+3 -3
View File
@@ -4,12 +4,11 @@ title: 使用VS Code写一篇文档
author: chuyaoyuan
author_title: cyy
author_url: https://github.com/chuyaoyuan
author_image_url: https://s3.ax1x.com/2021/02/26/6SEr4g.jpg
tags: [hello, chuyaoyuan]
---
Welcome to this site.
这是一篇关于如何创建文档的博客。[开始阅读](http://docs.yaoyuan.io/blog/use-code-docs)
这是一篇关于如何创建文档的博客。[开始阅读](/blog/use-code-docs)
<!--truncate-->
### 使用
@@ -27,5 +26,6 @@ npm run serve
### VS Code编辑
1. `file-open` 打开编辑器,开始编写之旅.
[![gp1R61.png](https://z3.ax1x.com/2021/04/26/gp1R61.png)](http://docs.yaoyuan.io)
> 截图已移除(原图床 CDN 已失效)
1. `done` 结束.
+10 -14
View File
@@ -14,20 +14,16 @@ Or **try Docusaurus immediately** with **[new.docusaurus.io](https://new.docusau
## 代码块
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs
defaultValue="js"
values={[
{ label: 'JavaScript', value: 'js', },
{ label: 'Python', value: 'py', },
{ label: 'Java', value: 'java', },
]
}>
defaultValue="js"
values={[
{ label: 'JavaScript', value: 'js' },
{ label: 'Python', value: 'py' },
{ label: 'Java', value: 'java' },
]}>
<TabItem value="js">
```js
@@ -95,18 +91,18 @@ https://katex.org/ .
**Fundamental Theorem of Calculus**
Let $f:[a,b] \to \R$ be Riemann integrable. Let $F:[a,b]\to\R$ be $F(x)=
Let $f:[a,b] \to \mathbb{R}$ be Riemann integrable. Let $F:[a,b]\to\mathbb{R}$ be $F(x)=
\int_{a}^{x}f(t)dt$.
Then $$F$$ is continuous, and at all $x$ such that $f$ is continuous at $x$,
Then $F$ is continuous, and at all $x$ such that $f$ is continuous at $x$,
$F$ is differentiable at $x$ with $F'(x)=f(x)$.
### 科学公式 TeX(KaTeX)
$$E=mc^2$$
行内的公式$$E=mc^2$$行内的公式,行内的$$E=mc^2$$公式。
行内的公式$E=mc^2$行内的公式,行内的$E=mc^2$公式。
$$\(\sqrt{3x-1}+(1+x)^2\)$$
$$\sqrt{3x-1}+(1+x)^2$$
$$\sin(\alpha)^{\theta}=\sum_{i=0}^{n}(x^i + \cos(f))$$
-4
View File
@@ -1,4 +0,0 @@
{
"label": "文档教程 - 基础",
"position": 14
}
-21
View File
@@ -1,21 +0,0 @@
---
sidebar_position: 6
---
# Congratulations!
You have just learned the **basics of Docusaurus** and made some changes to the **initial template**.
Docusaurus has **much more to offer**!
Have **5 more minutes**? Take a look at **[versioning](../tutorial-extras/manage-docs-versions.md)** and **[i18n](../tutorial-extras/translate-your-site.md)**.
Anything **unclear** or **buggy** in this tutorial? [Please report it!](https://github.com/facebook/docusaurus/discussions/4610)
## What's next?
- Read the [official documentation](https://docusaurus.io/).
- Add a custom [Design and Layout](https://docusaurus.io/docs/styling-layout)
- Add a [search bar](https://docusaurus.io/docs/search)
- Find inspirations in the [Docusaurus showcase](https://docusaurus.io/showcase)
- Get involved in the [Docusaurus Community](https://docusaurus.io/community/support)
@@ -1,29 +0,0 @@
---
sidebar_position: 3
---
# Create a Blog Post
Docusaurus creates a **page for each blog post**, but also a **blog index page**, a **tag system**, an **RSS** feed...
## Create your first Post
Create a file at `blog/2021-02-28-greetings.md`:
```md title="blog/2021-02-28-greetings.md"
---
slug: greetings
title: Greetings!
author: Steven Hansel
author_title: Docusaurus Contributor
author_url: https://github.com/ShinteiMai
author_image_url: https://github.com/ShinteiMai.png
tags: [greetings]
---
Congratulations, you have made your first post!
Feel free to play around and edit this post as much you like.
```
A new blog post is now available at `http://localhost:3000/blog/greetings`.
-56
View File
@@ -1,56 +0,0 @@
---
sidebar_position: 2
---
# Create a Document
Documents are **groups of pages** connected through:
- a **sidebar**
- **previous/next navigation**
- **versioning**
## Create your first Doc
Create a markdown file at `docs/hello.md`:
```md title="docs/hello.md"
# Hello
This is my **first Docusaurus document**!
```
A new document is now available at `http://localhost:3000/docs/hello`.
## Configure the Sidebar
Docusaurus automatically **creates a sidebar** from the `docs` folder.
Add metadatas to customize the sidebar label and position:
```diff title="docs/hello.md"
+ ---
+ sidebar_label: "Hi!"
+ sidebar_position: 3
+ ---
# Hello
This is my **first Docusaurus document**!
```
It is also possible to create your sidebar explicitly in `sidebars.js`:
```diff title="sidebars.js"
module.exports = {
tutorialSidebar: [
{
type: 'category',
label: 'Tutorial',
- items: [...],
+ items: ['hello'],
},
],
};
```
-43
View File
@@ -1,43 +0,0 @@
---
sidebar_position: 1
---
# Create a Page
Add **Markdown or React** files to `src/pages` to create a **standalone page**:
- `src/pages/index.js` -> `localhost:3000/`
- `src/pages/foo.md` -> `localhost:3000/foo`
- `src/pages/foo/bar.js` -> `localhost:3000/foo/bar`
## Create your first React Page
Create a file at `src/pages/my-react-page.js`:
```jsx title="src/pages/my-react-page.js"
import React from 'react';
import Layout from '@theme/Layout';
export default function MyReactPage() {
return (
<Layout>
<h1>My React page</h1>
<p>This is a React page</p>
</Layout>
);
}
```
A new page is now available at `http://localhost:3000/my-react-page`.
## Create your first Markdown Page
Create a file at `src/pages/my-markdown-page.md`:
```mdx title="src/pages/my-markdown-page.md"
# My Markdown page
This is a Markdown page
```
A new page is now available at `http://localhost:3000/my-markdown-page`.
-31
View File
@@ -1,31 +0,0 @@
---
sidebar_position: 5
---
# Deploy your site
Docusaurus is a **static-site-generator** (also called **[Jamstack](https://jamstack.org/)**).
It builds your site as simple **static HTML, JavaScript and CSS files**.
## Build your site
Build your site **for production**:
```bash
npm run build
```
The static files are generated in the `build` folder.
## Deploy your site
Test your production build locally:
```bash
npm run serve
```
The `build` folder is now served at `http://localhost:3000/`.
You can now deploy the `build` folder **almost anywhere** easily, **for free** or very small cost (read the **[Deployment Guide](https://docusaurus.io/docs/deployment)**).
-144
View File
@@ -1,144 +0,0 @@
---
sidebar_position: 4
---
# Markdown Features
Docusaurus supports **[Markdown](https://daringfireball.net/projects/markdown/syntax)** and a few **additional features**.
## Front Matter
Markdown documents have metadata at the top called [Front Matter](https://jekyllrb.com/docs/front-matter/):
```text title="my-doc.md"
// highlight-start
---
id: my-doc-id
title: My document title
description: My document description
slug: /my-custom-url
---
// highlight-end
## Markdown heading
Markdown text with [links](./hello.md)
```
## Links
Regular Markdown links are supported, using url paths or relative file paths.
```md
Let's see how to [Create a page](/create-a-page).
```
```md
Let's see how to [Create a page](./create-a-page.md).
```
**Result:** Let's see how to [Create a page](./create-a-page.md).
## Images
Regular Markdown images are supported.
Add an image at `static/img/docusaurus.png` and display it in Markdown:
```md
![Docusaurus logo](/img/docusaurus.png)
```
![Docusaurus logo](/img/docusaurus.png)
## Code Blocks
Markdown code blocks are supported with Syntax highlighting.
```jsx title="src/components/HelloDocusaurus.js"
function HelloDocusaurus() {
return (
<h1>Hello, Docusaurus!</h1>
)
}
```
```jsx title="src/components/HelloDocusaurus.js"
function HelloDocusaurus() {
return <h1>Hello, Docusaurus!</h1>;
}
```
## Admonitions
Docusaurus has a special syntax to create admonitions and callouts:
:::tip My tip
Use this awesome feature option
:::
:::danger Take care
This action is dangerous
:::
:::tip My tip
Use this awesome feature option
:::
:::danger Take care
This action is dangerous
:::
## MDX and React Components
[MDX](https://mdxjs.com/) can make your documentation more **interactive** and allows using any **React components inside Markdown**:
```jsx
export const Highlight = ({children, color}) => (
<span
style={{
backgroundColor: color,
borderRadius: '20px',
color: '#fff',
padding: '10px',
cursor: 'pointer',
}}
onClick={() => {
alert(`You clicked the color ${color} with label ${children}`)
}}>
{children}
</span>
);
This is <Highlight color="#25c2a0">Docusaurus green</Highlight> !
This is <Highlight color="#1877F2">Facebook blue</Highlight> !
```
export const Highlight = ({children, color}) => (
<span
style={{
backgroundColor: color,
borderRadius: '20px',
color: '#fff',
padding: '10px',
cursor: 'pointer',
}}
onClick={() => {
alert(`You clicked the color ${color} with label ${children}`);
}}>
{children}
</span>
);
This is <Highlight color="#25c2a0">Docusaurus green</Highlight> !
This is <Highlight color="#1877F2">Facebook blue</Highlight> !
-4
View File
@@ -1,4 +0,0 @@
{
"label": "文档教程 - 高级",
"position": 15
}
@@ -1,55 +0,0 @@
---
sidebar_position: 1
---
# Manage Docs Versions
Docusaurus can manage multiple versions of your docs.
## Create a docs version
Release a version 1.0 of your project:
```bash
npm run docusaurus docs:version 1.0
```
The `docs` folder is copied into `versioned_docs/version-1.0` and `versions.json` is created.
Your docs now have 2 versions:
- `1.0` at `http://localhost:3000/docs/` for the version 1.0 docs
- `current` at `http://localhost:3000/docs/next/` for the **upcoming, unreleased docs**
## Add a Version Dropdown
To navigate seamlessly across versions, add a version dropdown.
Modify the `docusaurus.config.js` file:
```js title="docusaurus.config.js"
module.exports = {
themeConfig: {
navbar: {
items: [
// highlight-start
{
type: 'docsVersionDropdown',
},
// highlight-end
],
},
},
};
```
The docs version dropdown appears in your navbar:
![Docs Version Dropdown](/img/tutorial/docsVersionDropdown.png)
## Update an existing version
It is possible to edit versioned docs in their respective folder:
- `versioned_docs/version-1.0/hello.md` updates `http://localhost:3000/docs/hello`
- `docs/hello.md` updates `http://localhost:3000/docs/next/hello`
@@ -1,88 +0,0 @@
---
sidebar_position: 2
---
# Translate your site
Let's translate `docs/getting-started.md` to French.
## Configure i18n
Modify `docusaurus.config.js` to add support for the `fr` locale:
```js title="docusaurus.config.js"
module.exports = {
i18n: {
defaultLocale: 'en',
locales: ['en', 'fr'],
},
};
```
## Translate a doc
Copy the `docs/getting-started.md` file to the `i18n/fr` folder:
```bash
mkdir -p i18n/fr/docusaurus-plugin-content-docs/current/
cp docs/getting-started.md i18n/fr/docusaurus-plugin-content-docs/current/getting-started.md
```
Translate `i18n/fr/docusaurus-plugin-content-docs/current/getting-started.md` in French.
## Start your localized site
Start your site on the French locale:
```bash
npm run start -- --locale fr
```
Your localized site is accessible at `http://localhost:3000/fr/` and the `Getting Started` page is translated.
:::caution
In development, you can only use one locale at a same time.
:::
## Add a Locale Dropdown
To navigate seamlessly across languages, add a locale dropdown.
Modify the `docusaurus.config.js` file:
```js title="docusaurus.config.js"
module.exports = {
themeConfig: {
navbar: {
items: [
// highlight-start
{
type: 'localeDropdown',
},
// highlight-end
],
},
},
};
```
The locale dropdown now appears in your navbar:
![Locale Dropdown](/img/tutorial/localeDropdown.png)
## Build your localized site
Build your site for a specific locale:
```bash
npm run build -- --locale fr
```
Or build your site to include all the locales at once:
```bash
npm run build
```
+77 -40
View File
@@ -1,8 +1,19 @@
/** @type {import('@docusaurus/types').DocusaurusConfig} */
const math = require('remark-math');
const katex = require('rehype-katex');
import type { Config } from '@docusaurus/types';
import type * as Preset from '@docusaurus/preset-classic';
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
import { config as loadEnv } from 'dotenv';
import fs from 'fs';
import path from 'path';
module.exports = {
loadEnv({ path: '.env.local' });
const techDocsHTML = fs.readFileSync(
path.join(__dirname, 'src/snippets/tech-docs.html'),
'utf-8',
);
const config: Config = {
title: 'CodeDocs 编程文档',
tagline: 'CodeDocs 编程文档 -- 这里是一些技术人的编程文档',
url: 'http://docs.yaoyuan.io/',
@@ -10,23 +21,42 @@ module.exports = {
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
favicon: 'img/favicon.ico',
organizationName: 'chuyaoyuan', // Usually your GitHub org/user name.
projectName: 'code-docs', // Usually your repo name.
organizationName: 'chuyaoyuan',
projectName: 'code-docs',
i18n: {
defaultLocale: 'zh-cn',
locales: ['zh-cn','en'],
locales: ['zh-cn', 'en'],
localeConfigs: {
'zh-cn': {
label: '中文',
direction: 'ltr',
htmlLang: 'zh-CN',
},
en: {
label: 'English',
direction: 'ltr',
htmlLang: 'en-US',
},
},
},
themeConfig: {
// Only enable Algolia when API keys are provided
...(process.env.ALGOLIA_API_KEY && process.env.ALGOLIA_APP_ID ? {
algolia: {
apiKey: '204335ce5ba2700fd04046b290498627',
apiKey: process.env.ALGOLIA_API_KEY,
appId: process.env.ALGOLIA_APP_ID,
indexName: 'code-docs',
// Optional: see doc section below
contextualSearch: true,
// Optional: see doc section below
appId: 'D8PEAPGLZ3',
// Optional: Algolia search parameters
searchParameters: {},
//... other Algolia params
},
} : {}),
// Enable sidebar collapse/expand button (dyte-style)
docs: {
sidebar: {
hideable: true,
},
},
navbar: {
title: 'CodeDocs 编程文档',
@@ -35,22 +65,37 @@ module.exports = {
src: 'img/logo.svg',
},
items: [
// ── Mega Dropdown: 技术文档 (left-right panel, mirrors dyte SDK dropdown)
{
type: 'doc',
docId: 'intro-docs',
label: '技术文档',
type: 'dropdown',
className: 'tech-docs-dropdown',
position: 'left',
label: 'Docs',
},
{to: '/blog', label: 'Blog', position: 'left'},
items: [
{
type: 'localeDropdown',
position: 'right',
type: 'html',
value: techDocsHTML,
className: 'tech-docs-dropdown',
},
],
},
// ── Blog
{
to: '/blog',
label: 'Blog',
position: 'left',
},
// ── GitHub (right)
{
href: 'https://github.com/chuyaoyuan/code-docs',
label: 'GitHub',
position: 'right',
},
// ── Language toggle (right)
{
type: 'localeDropdown',
position: 'right',
},
],
},
footer: {
@@ -76,10 +121,6 @@ module.exports = {
label: 'Discord',
href: 'https://discordapp.com/',
},
{
label: 'Twitter',
href: 'https://twitter.com/',
},
],
},
{
@@ -111,38 +152,34 @@ module.exports = {
],
copyright: `Copyright © ${new Date().getFullYear()} Code Docs, Inc. 一些技术人的编程文档网站.`,
},
},
} satisfies Preset.ThemeConfig,
stylesheets: [
{
href: 'https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css',
href: 'https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css',
type: 'text/css',
integrity:
'sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X',
crossorigin: 'anonymous',
},
],
presets: [
[
'@docusaurus/preset-classic',
'classic',
{
docs: {
sidebarPath: require.resolve('./sidebars.js'),
// Please change this to your repo.
remarkPlugins: [math],
rehypePlugins: [katex],
editUrl:
'https://github.com/facebook/docusaurus/edit/master/website/',
sidebarPath: './sidebars.ts',
remarkPlugins: [remarkMath],
rehypePlugins: [rehypeKatex],
},
blog: {
showReadingTime: true,
// Please change this to your repo.
editUrl:
'https://github.com/facebook/docusaurus/edit/master/website/blog/',
},
theme: {
customCss: require.resolve('./src/css/custom.css'),
},
customCss: './src/css/custom.css',
},
} satisfies Preset.Options,
],
],
};
export default config;
+279
View File
@@ -0,0 +1,279 @@
Read [](file:///opt/cyy/code-docs)
Read [](file:///opt/cyy/code-docs/package.json)
Read [](file:///opt/cyy/code-docs/docusaurus.config.js#1-1), lines 1 to 120
Read [](file:///opt/cyy/code-docs/sidebars.js)
Read [](file:///opt/cyy/code-docs/src/components/HomepageFeatures.js#1-1), lines 1 to 50
Read [](file:///opt/cyy/code-docs/src/pages/index.js)
Read [](file:///opt/cyy/code-docs/babel.config.js)
Read [](file:///opt/cyy/code-docs/.github)
Read [](file:///opt/cyy/code-docs/docs/intro-docs.md#1-1), lines 1 to 40
Read [](file:///opt/cyy/code-docs/.github/workflows)
Read [](file:///opt/cyy/code-docs/docs/LeetCode/CodingInterviews/StackAndQueue/MaxValueOfQueue.md#1-1), lines 1 to 50
Read [](file:///opt/cyy/code-docs/.github/workflows/nodejs.yml)
Read [](file:///opt/cyy/code-docs/docs/LeetCode/CodingInterviews/StackAndQueue/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E9%81%8D%E5%8E%86.md#1-1), lines 1 to 30
Let me check for the garbled files:
Ran terminal command: find /opt/cyy/code-docs -maxdepth 1 -type f | sort && echo "---" && ls -la /opt/cyy/code-docs/ | head -30
Found them. Both are empty files (size 0) with garbled names. Let me delete them:
Ran terminal command: cd /opt/cyy/code-docs && find . -maxdepth 1 -name "2p" -delete && find . -maxdepth 1 -name $',\xef\xbf\xbd0p>*' -delete 2>/dev/null; find . -maxdepth 1 -type f -size 0 ! -name ".*" | head -20
Ran terminal command: cd /opt/cyy/code-docs && ls -la | grep "^-rw.* 0 " | awk '{print $NF}' && find . -maxdepth 1 -type f -size 0 -exec rm -v {} \;
Ran terminal command: cd /opt/cyy/code-docs && find . -maxdepth 1 -type f -size 0 | wc -l && ls | head -20
Both garbled files removed. Now let me read the remaining docs for the full analysis:
Read [](file:///opt/cyy/code-docs/blog/2021-04-26-use-code-docs.md)
Read [](file:///opt/cyy/code-docs/src/css/custom.css)
Now I have a complete picture. Let me compose the professional analysis and upgrade prompt:
---
## 两个乱码文件处理完毕
已删除根目录下的两个空白乱码文件:
- `2p`(空文件)
- `,°0p>;°8p>...Rich2p>PEd...`(空文件,名称为二进制乱码)
---
## 项目分析报告 + 系统升级提示词
---
## 一、项目现状分析
| 维度 | 当前状态 | 风险等级 |
|------|----------|----------|
| Docusaurus 版本 | `2.0.0-alpha.73` (2021年) | 🔴 极高 |
| React 版本 | `17.0.1` | 🟠 高 |
| Node.js (CI) | `12` (EOL) | 🔴 极高 |
| 部署方式 | FTP 明文传输 | 🔴 安全风险 |
| Algolia Key | 硬编码在公开配置文件 | 🔴 信息泄露 |
| TypeScript | 未使用 | 🟡 中 |
| 包管理器 | yarn.lock + package-lock.json 混用 | 🟠 高 |
---
## 二、问题点清单
**严重问题:**
1. `@docusaurus/core: 2.0.0-alpha.73` — 当前稳定版为 `3.7.x`,跨越近3年迭代,含大量Breaking Changes
2. Node.js 12 已于2022年4月正式 EOLCI/CD 中仍在使用
3. Algolia `apiKey` 明文暴露在 docusaurus.config.js
4. `remark-math@3` + `rehype-katex@4` 与 Docusaurus 3.x 使用的 MDX 3.x 不兼容
5. .DS_Store 文件未被 .gitignore 过滤,已提交到仓库
**架构问题:**
6. 纯 JavaScript 项目,Docusaurus 3.x 全面支持 TypeScript,缺失类型安全
7. FTP 部署方案无加密、无回滚、无原子发布能力
8. GitHub Actions 使用过期版本:`actions/checkout@v2.3.2``actions/setup-node@v2-beta`
9. yarn.lock 和 package-lock.json 同时存在,包管理器冲突
10. CI 无分支过滤,每次 push(包括草稿分支)都会触发生产部署
**内容问题:**
11. HomepageFeatures.js 仍为 Docusaurus 默认英文占位内容
12. 依赖外部图片 CDN`s3.ax1x.com``z3.ax1x.com`)存在链接失效风险
13. i18n 配置了 `en`/`zh-cn` 双语,但无对应翻译文件
14. Blog 文章内含硬编码域名链接 `http://docs.yaoyuan.io/...`
15. Tutorial 目录仍为 Docusaurus 官方示例内容,未替换为项目自有文档
---
## 三、系统升级提示词(可直接用于 AI 对话)
```
你是一名资深全栈工程师,精通 Docusaurus、React、GitHub Actions 和技术文档工程。
我需要你对下述项目进行全面系统升级,请严格按照优先级顺序执行,给出完整可执行的代码和配置。
## 项目背景
- 项目名称:code-docsCodeDocs 编程文档站)
- 当前框架:Docusaurus v2.0.0-alpha.73React 17,纯 JS
- 内容:中文技术文档,包含 LeetCode、Spring Boot、Spring Cloud、React、Vue 专题
- 部署:GitHub Actions → FTP → 自托管服务器(http://docs.yaoyuan.io
---
## 升级任务列表(按优先级排序)
### P0 - 核心框架升级
**1. 升级 Docusaurus 3.x**
- 将 `@docusaurus/core` 和 `@docusaurus/preset-classic` 从 `2.0.0-alpha.73` 升级到最新稳定版 `^3.7.0`
- 同步升级所有 peer dependencies`react@^18.3`、`react-dom@^18.3`
- 迁移 `docusaurus.config.js` 为 `docusaurus.config.ts`TypeScript 配置)
- 替换已废弃 API
- `module.exports` → `export default` (ESM)
- `DocusaurusConfig` 类型导入路径变更
- `themeConfig.algolia` 结构校验更新
- 更新 MDX 依赖以兼容 MDX 3.x
- `remark-math` 升级到 `^6.0``rehype-katex` 升级到 `^7.0`
- 检查所有使用 MDX JSX 语法的 `.md` 文件(如 `docs/intro-docs.md` 中的 `<Tabs>`),确保兼容 MDX 3 严格模式
**2. 升级 TypeScript 支持**
- 初始化 `tsconfig.json`(继承 `@docusaurus/tsconfig`
- 将 `src/` 目录下所有 `.js`/`.jsx` 文件迁移为 `.ts`/`.tsx`
- 为 `HomepageFeatures`、`index` 页面添加完整 Props 类型声明
- 升级 `babel.config.js` → `babel.config.ts`
---
### P1 - 安全修复
**3. 消除 Algolia Key 泄露风险**
- 将 `docusaurus.config` 中硬编码的 Algolia `apiKey`、`appId` 提取到环境变量
- 创建 `.env.local` 文件(加入 `.gitignore`):
```
ALGOLIA_APP_ID=D8PEAPGLZ3
ALGOLIA_API_KEY=<your_search_only_api_key>
```
- 在配置中使用 `process.env.ALGOLIA_APP_ID` 引用
- 在 GitHub Actions 中添加对应 `secrets`
**4. 修复 `.gitignore`**
添加以下条目:
```
.DS_Store
.env.local
.env.*.local
```
---
### P2 - CI/CD 现代化
**5. 重写 GitHub Actions 工作流**
```yaml
# .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches: [main] # 仅 main 分支触发,移除草稿分支误部署
pull_request:
branches: [main] # PR 仅做构建校验,不部署
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4 # 升级到 v4
- uses: actions/setup-node@v4 # 升级到 v4
with:
node-version: '20' # Node 20 LTS
cache: 'npm' # 启用依赖缓存
- name: Install dependencies
run: npm ci # 使用 ci 替代 install,更稳定
- name: Build
run: npm run build
env:
ALGOLIA_APP_ID: ${{ secrets.ALGOLIA_APP_ID }}
ALGOLIA_API_KEY: ${{ secrets.ALGOLIA_API_KEY }}
deploy:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
steps:
# 推荐迁移至 GitHub Pages 或 SSH 部署,若保留 FTP 则升级:
- uses: SamKirkland/FTP-Deploy-Action@v4.3.5
with:
server: ${{ secrets.FTP_SERVER }}
username: ${{ secrets.FTP_USER }}
password: ${{ secrets.FTP_PWD }}
local-dir: ./build/
server-dir: code-docs/www/
```
> **架构建议**:将 FTP 部署迁移至 GitHub Pages(零成本)或 Vercel(自动预览 PR),消除明文传输风险。
---
### P3 - 内容与架构优化
**6. 首页本地化改造**
`src/components/HomepageFeatures.tsx` 的英文占位内容替换为项目实际特性:
```tsx
const FeatureList: FeatureItem[] = [
{
title: '📚 系统化文档',
description: '涵盖后端(Spring Boot/Cloud)、前端(React/Vue)和算法(LeetCode),分门别类,清晰索引。',
},
{
title: '⚡ 快速检索',
description: '集成 Algolia DocSearch,毫秒级全文检索,快速定位任意知识点。',
},
{
title: '🌐 持续更新',
description: '由技术团队持续维护,定期同步最新技术栈实践和面试题解析。',
},
];
```
移除对 `undraw_docusaurus_*.svg` 的依赖(这些文件在 img 中可能不存在)。
**7. 清理默认内容**
- 删除 tutorial-basics 和 tutorial-extras 目录(Docusaurus 默认示例,与项目无关)
- 删除 2021-01-01-hello-world.md 和 2021-01-01-hola.md(官方示例博客)
- 统一 Blog 文章中的链接为相对路径,移除硬编码域名
**8. 图片资源本地化**
将外部 CDN 图片(`s3.ax1x.com``z3.ax1x.com`)下载到 img 目录,
替换为相对路径引用,避免 CDN 失效导致图片断链。
**9. 统一包管理器**
删除 package-lock.json(保留 yarn.lock),或删除 yarn.lock(保留 `npm`),
在 package.json 中声明 `"packageManager": "npm@10.x.x"``"yarn@4.x.x"` 固定版本。
**10. 完善 i18n(可选)**
当前 `docusaurus.config` 配置了 `zh-cn` + `en` 双语,但缺少翻译文件。
执行 `npm run write-translations` 生成翻译模板,或移除 `en` locale 以减少维护成本。
---
## 升级注意事项
1. **Breaking Change 重点**Docusaurus 3.x 使用 MDX 3,对 `{}` 中的 HTML 实体、未闭合标签更严格,升级后需逐一检测现有 `.md`/`.mdx` 文件:
```bash
npx docusaurus-mdx-checker
```
2. **KaTeX 配置变更**`remark-math` v6+ 和 `rehype-katex` v7+ 的引入方式从 `require()` 改为 ES Module `import``docusaurus.config.ts` 需同步调整
3. **React 18 并发模式**`ReactDOM.render` 已废弃,检查是否有自定义入口文件使用旧 API
4. **升级顺序建议**
```
Step 1: 先在新分支 feat/upgrade-v3 上操作
Step 2: 升级依赖 → Step 3: 修复 MDX 兼容性 → Step 4: 本地构建验证
Step 5: 修复 CI/CD → Step 6: 合并到 main 触发部署
```
---
## 升级后验证清单
- [ ] `npm run build` 零报错、零警告
- [ ] `npm run start` 本地预览正常
- [ ] 中文搜索正常(Algolia
- [ ] KaTeX 数学公式正常渲染
- [ ] 深色模式外观正常
- [ ] GitHub Actions 仅 `main` 分支触发部署
- [ ] 无硬编码密钥在代码仓库中
+17646 -13786
View File
File diff suppressed because it is too large Load Diff
+19 -9
View File
@@ -2,6 +2,7 @@
"name": "code-docs",
"version": "0.0.0",
"private": true,
"packageManager": "npm@10.9.2",
"scripts": {
"docusaurus": "docusaurus",
"start": "docusaurus start",
@@ -11,17 +12,26 @@
"clear": "docusaurus clear",
"serve": "docusaurus serve",
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids"
"write-heading-ids": "docusaurus write-heading-ids",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@docusaurus/core": "2.0.0-alpha.73",
"@docusaurus/preset-classic": "2.0.0-alpha.73",
"@mdx-js/react": "^1.6.21",
"clsx": "^1.1.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"rehype-katex": "^4.0.0",
"remark-math": "^3.0.1"
"@docusaurus/core": "^3.10.1",
"@docusaurus/preset-classic": "^3.10.1",
"@mdx-js/react": "^3.0.0",
"clsx": "^2.1.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"rehype-katex": "^7.0.0",
"remark-math": "^6.0.0"
},
"devDependencies": {
"@docusaurus/tsconfig": "^3.10.1",
"dotenv": "^16.4.7",
"typescript": "^5.4.5"
},
"overrides": {
"serialize-javascript": "7.0.5"
},
"browserslist": {
"production": [
-26
View File
@@ -1,26 +0,0 @@
/**
* Creating a sidebar enables you to:
- create an ordered group of docs
- render a sidebar for each doc of that group
- provide next/previous navigation
The sidebars can be generated from the filesystem, or explicitly defined here.
Create as many sidebars as you want.
*/
module.exports = {
// By default, Docusaurus generates a sidebar from the docs folder structure
tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
// But you can create a sidebar manually
/*
tutorialSidebar: [
{
type: 'category',
label: 'Tutorial',
items: ['hello'],
},
],
*/
};
+8
View File
@@ -0,0 +1,8 @@
import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
const sidebars: SidebarsConfig = {
// Docusaurus auto-generates a sidebar from the docs folder structure
tutorialSidebar: [{ type: 'autogenerated', dirName: '.' }],
};
export default sidebars;
-64
View File
@@ -1,64 +0,0 @@
import React from 'react';
import clsx from 'clsx';
import styles from './HomepageFeatures.module.css';
const FeatureList = [
{
title: 'Easy to Use',
Svg: require('../../static/img/undraw_docusaurus_mountain.svg').default,
description: (
<>
Docusaurus was designed from the ground up to be easily installed and
used to get your website up and running quickly.
</>
),
},
{
title: 'Focus on What Matters',
Svg: require('../../static/img/undraw_docusaurus_tree.svg').default,
description: (
<>
Docusaurus lets you focus on your docs, and we&apos;ll do the chores. Go
ahead and move your docs into the <code>docs</code> directory.
</>
),
},
{
title: 'Powered by React',
Svg: require('../../static/img/undraw_docusaurus_react.svg').default,
description: (
<>
Extend or customize your website layout by reusing React. Docusaurus can
be extended while reusing the same header and footer.
</>
),
},
];
function Feature({Svg, title, description}) {
return (
<div className={clsx('col col--4')}>
<div className="text--center">
<Svg className={styles.featureSvg} alt={title} />
</div>
<div className="text--center padding-horiz--md">
<h3>{title}</h3>
<p>{description}</p>
</div>
</div>
);
}
export default function HomepageFeatures() {
return (
<section className={styles.features}>
<div className="container">
<div className="row">
{FeatureList.map((props, idx) => (
<Feature key={idx} {...props} />
))}
</div>
</div>
</section>
);
}
+161 -4
View File
@@ -3,11 +3,168 @@
.features {
display: flex;
align-items: center;
padding: 2rem 0;
padding: 3rem 0;
width: 100%;
background: linear-gradient(135deg, rgba(33, 96, 253, 0.05) 0%, rgba(6, 182, 212, 0.05) 100%);
}
.featureGrid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
width: 100%;
}
.featureSvg {
height: 200px;
width: 200px;
@media (max-width: 768px) {
.featureGrid {
grid-template-columns: 1fr;
gap: 1rem;
}
}
/* Feature Card Styling */
.featureCard {
position: relative;
text-decoration: none;
color: inherit;
display: block;
height: 100%;
}
.cardInner {
position: relative;
overflow: hidden;
border-radius: 1.5rem;
border: 1px solid rgba(33, 96, 253, 0.1);
background: linear-gradient(135deg, rgba(33, 96, 253, 0.02), rgba(6, 182, 212, 0.02));
padding: 1.5rem;
height: 100%;
display: flex;
flex-direction: column;
gap: 1rem;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.featureCard:hover .cardInner {
border-color: var(--card-color, #2160fd);
background: linear-gradient(135deg, rgba(33, 96, 253, 0.08), rgba(6, 182, 212, 0.08));
box-shadow: 0 10px 30px rgba(33, 96, 253, 0.1),
0 0 1px rgba(33, 96, 253, 0.3);
transform: translateY(-4px);
}
.cardIcon {
font-size: 2.5rem;
line-height: 1;
width: 3rem;
height: 3rem;
display: flex;
align-items: center;
justify-content: center;
background: rgba(33, 96, 253, 0.1);
border-radius: 1rem;
transition: all 0.3s ease;
}
.featureCard:hover .cardIcon {
background: var(--card-color, #2160fd);
color: white;
transform: scale(1.1);
}
.cardContent {
flex: 1;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.cardTitle {
font-size: 1.25rem;
font-weight: 600;
margin: 0;
color: var(--docs-color-text, #1f2937);
transition: color 0.3s ease;
}
[data-theme='dark'] .cardTitle {
color: #f3f4f6;
}
.featureCard:hover .cardTitle {
color: var(--card-color, #2160fd);
}
.cardDescription {
font-size: 0.95rem;
line-height: 1.6;
margin: 0;
color: var(--docs-color-text-secondary, #6b7280);
transition: color 0.3s ease;
}
[data-theme='dark'] .cardDescription {
color: #d1d5db;
}
.cardGradient {
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
pointer-events: none;
opacity: 0;
transition: opacity 0.3s ease;
background: radial-gradient(circle at top right, rgba(33, 96, 253, 0.15), transparent 70%);
z-index: 0;
}
.featureCard:hover .cardGradient {
opacity: 1;
}
.cardArrow {
position: absolute;
top: 1rem;
right: 1rem;
font-size: 1.5rem;
opacity: 0;
transform: translate(8px, -8px);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
color: var(--card-color, #2160fd);
}
.featureCard:hover .cardArrow {
opacity: 1;
transform: translate(0, 0);
}
/* Animation */
@keyframes slideInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.cardInner {
animation: slideInUp 0.5s ease-out;
}
/* Stagger animation for cards */
:nth-child(1) .cardInner {
animation-delay: 0.1s;
}
:nth-child(2) .cardInner {
animation-delay: 0.2s;
}
:nth-child(3) .cardInner {
animation-delay: 0.3s;
}
+100
View File
@@ -0,0 +1,100 @@
import React from 'react';
import Link from '@docusaurus/Link';
import styles from './HomepageFeatures.module.css';
interface FeatureItem {
id: string;
title: string;
description: string;
icon: React.ReactNode;
link: string;
color: string;
gradient: string;
}
const FeatureList: FeatureItem[] = [
{
id: 'backend',
title: '后端技术',
description:
'深度讲解 Spring Boot / Spring Cloud 核心概念、最佳实践与微服务架构,含真实项目案例。',
icon: '⚙️',
link: '/docs/backend-doc/intro-docs',
color: '#2160fd',
gradient: 'from-blue-500/20 to-transparent',
},
{
id: 'frontend',
title: '前端开发',
description:
'系统化学习 React / Vue 现代框架、状态管理、组件设计与性能优化,打造高质量前端应用。',
icon: '⚛️',
link: '/docs/frontend-doc/intro-docs',
color: '#06b6d4',
gradient: 'from-cyan-500/20 to-transparent',
},
{
id: 'algorithms',
title: '算法与面试',
description:
'精选 LeetCode 题目分类讲解、编程面试题库与数据结构深度分析,快速突破算法关卡。',
icon: '🧠',
link: '/docs/LeetCode/intro-docs',
color: '#ec4899',
gradient: 'from-pink-500/20 to-transparent',
},
];
interface FeatureCardProps extends FeatureItem {}
function FeatureCard({
title,
description,
icon,
link,
color,
gradient,
}: FeatureCardProps): JSX.Element {
return (
<Link
to={link}
className={`${styles.featureCard} group`}
style={
{
'--card-color': color,
} as React.CSSProperties & { '--card-color': string }
}
>
<div className={styles.cardInner}>
{/* Icon */}
<div className={styles.cardIcon}>{icon}</div>
{/* Content */}
<div className={styles.cardContent}>
<h3 className={styles.cardTitle}>{title}</h3>
<p className={styles.cardDescription}>{description}</p>
</div>
{/* Gradient Background */}
<div className={`${styles.cardGradient} ${gradient}`}></div>
{/* Arrow Icon */}
<div className={styles.cardArrow}></div>
</div>
</Link>
);
}
export default function HomepageFeatures(): JSX.Element {
return (
<section className={styles.features}>
<div className="container">
<div className={styles.featureGrid}>
{FeatureList.map((props) => (
<FeatureCard key={props.id} {...props} />
))}
</div>
</div>
</section>
);
}
+450 -14
View File
@@ -1,20 +1,86 @@
/* stylelint-disable docusaurus/copyright-header */
/**
* Any CSS included here will be global. The classic template
* bundles Infima by default. Infima is a CSS framework designed to
* work well for content-centric websites.
*/
/* You can override the default Infima variables here. */
/* ══════════════════════════════════════════════════
Base CSS variables (mirrors dyte-io/docs token system)
══════════════════════════════════════════════════ */
:root {
--ifm-color-primary: #25c2a0;
--ifm-color-primary-dark: rgb(33, 175, 144);
--ifm-color-primary-darker: rgb(31, 165, 136);
--ifm-color-primary-darkest: rgb(26, 136, 112);
--ifm-color-primary-light: rgb(70, 203, 174);
--ifm-color-primary-lighter: rgb(102, 212, 189);
--ifm-color-primary-lightest: rgb(146, 224, 208);
--ifm-code-font-size: 95%;
/* Infima primary (matches dyte blue) */
--ifm-color-primary: #2160fd;
--ifm-color-primary-dark: #1959fc;
--ifm-color-primary-darker: #0f51f8;
--ifm-color-primary-darkest: #0042e7;
--ifm-color-primary-light: #3d72f8;
--ifm-color-primary-lighter: #477af8;
--ifm-color-primary-lightest: #6791fc;
/* Docs color tokens */
--docs-color-primary: #2160fd;
--docs-color-primary-tint: rgba(33, 96, 253, 0.16);
--docs-color-primary-tint-light: rgba(33, 96, 253, 0.24);
/* Background */
--docs-color-background: #ffffff;
--docs-color-background-100: #f8f8f8;
--docs-color-background-200: #efefef;
--docs-color-background-300: #dcdcdc;
/* Text */
--docs-color-text: #000000;
--docs-color-text-100: #646464;
--docs-color-text-400: #474747;
/* Border */
--docs-color-border: #dadde1;
/* Secondary scale (light mode = lighter greys) */
--docs-color-secondary-700: 232 232 236;
--docs-color-secondary-800: 245 245 247;
--docs-color-secondary-900: 251 251 251;
--docs-color-secondary-1000: 255 255 255;
/* Navbar */
--ifm-navbar-shadow: none;
--ifm-navbar-padding-horizontal: 0.75rem;
/* Misc */
--ifm-code-font-size: 92%;
--ifm-toc-border-color: #dedede;
--docusaurus-highlighted-code-line-bg: rgba(147, 178, 244, 0.38);
}
html[data-theme='dark'] {
--ifm-color-primary: #1a90ff;
--docs-color-primary: #1a90ff;
--docs-color-background: #161616;
--docs-color-background-100: #1c1c1c;
--docs-color-background-200: #2a2a2a;
--docs-color-background-300: #2e2e2e;
--docs-color-text: #ffffff;
--docs-color-text-100: #b4b4b4;
--docs-color-text-400: #999999;
--docs-color-border: #2e2e2e;
--docs-color-secondary-700: 71 71 71;
--docs-color-secondary-800: 38 38 38;
--docs-color-secondary-900: 25 25 25;
--docs-color-secondary-1000: 0 0 0;
--ifm-background-color: #161616;
--ifm-background-surface-color: #161616;
--ifm-footer-background-color: #1c1c1c;
--ifm-toc-border-color: #2e2e2e;
--ifm-color-content: #e7e7e7;
--docusaurus-highlighted-code-line-bg: rgba(105, 105, 105, 0.3);
}
/* ══════════════════════════════════════════════════
Base element styles
══════════════════════════════════════════════════ */
nav.navbar {
border-bottom: 1px solid var(--ifm-toc-border-color);
}
.docusaurus-highlight-code-line {
@@ -23,3 +89,373 @@
margin: 0 calc(-1 * var(--ifm-pre-padding));
padding: 0 var(--ifm-pre-padding);
}
/* Disable underline-on-hover in nav/sidebar */
.navbar__link,
.menu__link,
.table-of-contents__link,
.pagination-nav,
.footer {
--ifm-link-hover-decoration: none;
}
.menu__link {
--ifm-menu-color-background-active: var(--docs-color-primary-tint);
}
/* Dropdown chevron (matches dyte) */
.dropdown > .navbar__link {
display: flex;
align-items: center;
}
.dropdown > .navbar__link:after {
content: '';
border: none;
position: static;
top: auto;
transform: none;
width: 12px;
height: 12px;
margin-left: 4px;
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' fill='none' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.293 8.293a1 1 0 0 1 1.414 0L12 14.586l6.293-6.293a1 1 0 1 1 1.414 1.414l-7 7a1 1 0 0 1-1.414 0l-7-7a1 1 0 0 1 0-1.414Z' fill='%23888888'/%3E%3C/svg%3E");
background-size: 12px;
background-repeat: no-repeat;
}
html[data-theme='dark'] .dropdown > .navbar__link:after {
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' fill='none' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.293 8.293a1 1 0 0 1 1.414 0L12 14.586l6.293-6.293a1 1 0 1 1 1.414 1.414l-7 7a1 1 0 0 1-1.414 0l-7-7a1 1 0 0 1 0-1.414Z' fill='%23cccccc'/%3E%3C/svg%3E");
}
.dropdown:hover > .navbar__link:after {
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' fill='none' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.293 8.293a1 1 0 0 1 1.414 0L12 14.586l6.293-6.293a1 1 0 1 1 1.414 1.414l-7 7a1 1 0 0 1-1.414 0l-7-7a1 1 0 0 1 0-1.414Z' fill='%232160fd'/%3E%3C/svg%3E") !important;
}
/* ══════════════════════════════════════════════════
Tech Dropdown: Mega Menu (left panel + right panel)
Mirrors dyte's SDK dropdown pattern exactly
══════════════════════════════════════════════════ */
/* Docusaurus wraps the html item in a ul.dropdown__menu */
.tech-docs-dropdown + ul.dropdown__menu {
padding: 0;
border-radius: 16px;
overflow: hidden;
border: 1px solid var(--docs-color-border);
background: transparent;
min-width: 750px;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
}
.tech-dropdown {
display: flex;
min-height: 280px;
}
/* Left Category Panel */
.tech-dropdown-left {
display: flex;
flex-direction: column;
gap: 0;
background: rgb(var(--docs-color-secondary-1000));
min-width: 200px;
padding: 0.75rem;
border-right: 1px solid var(--docs-color-border);
}
.tech-menu-item {
display: flex;
align-items: flex-start;
gap: 0.6rem;
padding: 0.65rem 0.75rem;
border-radius: 8px;
cursor: pointer;
text-decoration: none !important;
color: var(--docs-color-text) !important;
border: 2px solid transparent;
transition: background 0.15s, border-color 0.15s;
}
.tech-menu-item:hover {
background: rgb(var(--docs-color-secondary-800) / 0.6);
border-color: transparent;
color: var(--docs-color-text) !important;
}
/* Active category item (matches dyte's left border style) */
body[data-tech-menu='backend'] [data-dropdown-tech-menu='backend'],
body[data-tech-menu='frontend'] [data-dropdown-tech-menu='frontend'],
body[data-tech-menu='algorithms'] [data-dropdown-tech-menu='algorithms'] {
border-left-color: #2160fd;
background: rgb(var(--docs-color-secondary-800) / 0.5);
}
.tech-menu-icon {
font-size: 1.2rem;
flex-shrink: 0;
margin-top: 0.1rem;
}
.tech-menu-item-title {
font-size: 0.875rem;
font-weight: 600;
line-height: 1.3;
color: var(--docs-color-text);
}
.tech-menu-item-desc {
font-size: 0.75rem;
color: var(--docs-color-text-100);
margin: 0;
line-height: 1.4;
}
/* Right Content Panel */
.tech-dropdown-right {
flex: 1;
padding: 1rem 1.25rem;
background: rgb(var(--docs-color-secondary-900));
}
/* Panel visibility: dyte's body data-attribute pattern */
[data-dropdown-tech] {
display: none;
}
.tech-panel-group {
min-width: 150px;
}
.tech-panel-heading {
font-size: 0.78rem !important;
font-weight: 700 !important;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--docs-color-text-100) !important;
margin-bottom: 0.5rem !important;
margin-top: 0 !important;
}
.tech-panel-links {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 0.2rem 0.4rem;
}
.tech-link {
display: flex;
align-items: center;
gap: 0.4rem;
padding: 0.35rem 0.5rem;
border-radius: 6px;
font-size: 0.84rem;
text-decoration: none !important;
color: var(--docs-color-text) !important;
transition: background 0.15s, color 0.15s;
}
.tech-link:hover {
background: rgba(33, 96, 253, 0.08);
color: #2160fd !important;
}
[data-theme='dark'] .tech-link:hover {
background: rgba(26, 144, 255, 0.1);
color: #1a90ff !important;
}
/* ══════════════════════════════════════════════════
Right panel: groups stack vertically, links flow horizontally
══════════════════════════════════════════════════ */
body:not([data-tech-menu]) [data-dropdown-tech='backend'],
body[data-tech-menu='backend'] [data-dropdown-tech='backend'],
body[data-tech-menu='frontend'] [data-dropdown-tech='frontend'],
body[data-tech-menu='algorithms'] [data-dropdown-tech='algorithms'] {
display: flex !important;
flex-direction: column;
gap: 1.25rem;
width: 100%;
}
/* ══════════════════════════════════════════════════
Sidebar: dyte-style collapse/expand button
══════════════════════════════════════════════════ */
aside.theme-doc-sidebar-container {
position: relative;
z-index: 2; /* ensure sidebar renders above main content */
clip-path: inset(0px -140px);
}
/* ── Collapse button (visible when sidebar is expanded) ── */
/* Title is translated to Chinese in zh-cn locale, so target both */
.theme-doc-sidebar-container button[title='Collapse sidebar'],
.theme-doc-sidebar-container button[title='收起侧边栏'] {
position: absolute;
top: 95vh;
right: -14px;
width: 28px;
height: 28px;
padding: 0;
border-radius: 4px;
z-index: 10;
background-size: 16px;
background-position: center;
background-repeat: no-repeat;
background-color: var(--docs-color-border);
border: none;
cursor: pointer;
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' fill='none' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M15.707 4.293a1 1 0 0 1 0 1.414L9.414 12l6.293 6.293a1 1 0 0 1-1.414 1.414l-7-7a1 1 0 0 1 0-1.414l7-7a1 1 0 0 1 1.414 0Z' fill='%23181818'/%3E%3C/svg%3E");
}
html[data-theme='dark'] .theme-doc-sidebar-container button[title='Collapse sidebar'],
html[data-theme='dark'] .theme-doc-sidebar-container button[title='收起侧边栏'] {
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' fill='none' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M15.707 4.293a1 1 0 0 1 0 1.414L9.414 12l6.293 6.293a1 1 0 0 1-1.414 1.414l-7-7a1 1 0 0 1 0-1.414l7-7a1 1 0 0 1 1.414 0Z' fill='%23ffffff'/%3E%3C/svg%3E");
}
/* ── Collapse button: hide Docusaurus default SVG (we use bg-image) ── */
.theme-doc-sidebar-container button[title='Collapse sidebar'] svg,
.theme-doc-sidebar-container button[title='收起侧边栏'] svg {
display: none;
}
/* ── Expand button (visible when sidebar is collapsed to 30px strip) ── */
/* Strategy: keep the div as full-area click target, use ::after for the visible icon */
.theme-doc-sidebar-container div[title='Expand sidebar'],
.theme-doc-sidebar-container div[title='展开侧边栏'] {
position: absolute !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
width: 100% !important;
height: 100% !important;
background-image: none !important;
background-color: transparent !important;
display: flex !important;
align-items: flex-end !important;
justify-content: center !important;
padding-bottom: 5vh !important;
}
/* Visible icon at bottom of the strip */
.theme-doc-sidebar-container div[title='Expand sidebar']::after,
.theme-doc-sidebar-container div[title='展开侧边栏']::after {
content: '';
display: block;
width: 28px;
height: 28px;
flex-shrink: 0;
border-radius: 4px;
background-color: var(--docs-color-border);
background-size: 16px;
background-position: center;
background-repeat: no-repeat;
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' fill='none' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8.293 4.293a1 1 0 0 0 0 1.414L14.586 12l-6.293 6.293a1 1 0 1 0 1.414 1.414l7-7a1 1 0 0 0 0-1.414l-7-7a1 1 0 0 0-1.414 0Z' fill='%23181818'/%3E%3C/svg%3E");
}
html[data-theme='dark'] .theme-doc-sidebar-container div[title='Expand sidebar']::after,
html[data-theme='dark'] .theme-doc-sidebar-container div[title='展开侧边栏']::after {
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' fill='none' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8.293 4.293a1 1 0 0 0 0 1.414L14.586 12l-6.293 6.293a1 1 0 1 0 1.414 1.414l7-7a1 1 0 0 0 0-1.414l-7-7a1 1 0 0 0-1.414 0Z' fill='%23ffffff'/%3E%3C/svg%3E");
}
/* Hide the default SVG inside the expand div */
.theme-doc-sidebar-container div[title='Expand sidebar'] svg,
.theme-doc-sidebar-container div[title='展开侧边栏'] svg {
display: none;
}
/* ══════════════════════════════════════════════════
Sidebar enhancements
══════════════════════════════════════════════════ */
.menu__link {
border-radius: 4px 0 0 4px;
font-size: 14px;
}
ul.menu__list > li > a.menu__link--active {
border-right: 1px solid var(--ifm-color-primary);
}
/* ══════════════════════════════════════════════════
Footer tweaks — dyte-style dark palette
══════════════════════════════════════════════════ */
.footer,
.footer--dark {
background-color: #1c1c1c !important;
border-top: 1px solid #2e2e2e !important;
padding: 3rem 0 2rem;
color: #b4b4b4;
}
.footer__title {
font-size: 14px;
font-weight: normal;
color: #b4b4b4;
margin-bottom: 0.5rem;
}
.footer__item {
font-size: 14px;
font-weight: normal;
}
.footer__link-item {
color: #b4b4b4;
transition: color 0.15s;
}
.footer__link-item:hover {
text-decoration: none;
color: #ffffff;
}
.footer__copyright {
margin-top: 32px;
font-size: 14px;
color: #b4b4b4;
}
/* ══════════════════════════════════════════════════
Code block tweaks — dyte-style
══════════════════════════════════════════════════ */
/* Reference variable (used by details/admonitions) — do NOT use as pre background */
:root {
--docs-color-code-background: #f6f8fa;
--code-border-color: var(--docs-color-border);
}
html[data-theme='dark'] {
--docs-color-code-background: #1e1e1e;
}
/* Only add a border — let Prism theme control the background/colors */
pre.prism-code {
border: 1px solid var(--code-border-color);
}
/* Inline code */
code:not(pre code) {
background-color: var(--docs-color-background-200);
border: 1px solid var(--docs-color-border);
border-radius: 4px;
font-size: 0.88em;
padding: 0.1em 0.35em;
}
/* Code block title bar */
.codeBlockTitle_node_modules-\@docusaurus-theme-classic-lib-theme-CodeBlock-Content-styles-module {
background-color: var(--docs-color-background-100) !important;
border-bottom: 1px solid var(--code-border-color) !important;
font-size: 13px;
}
/* Details/Admonition code blocks */
details code {
background-color: var(--docs-color-background);
}
-40
View File
@@ -1,40 +0,0 @@
import React from 'react';
import clsx from 'clsx';
import Layout from '@theme/Layout';
import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import styles from './index.module.css';
import HomepageFeatures from '../components/HomepageFeatures';
function HomepageHeader() {
const {siteConfig} = useDocusaurusContext();
return (
<header className={clsx('hero hero--primary', styles.heroBanner)}>
<div className="container">
<h1 className="hero__title">{siteConfig.title}</h1>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<div className={styles.buttons}>
<Link
className="button button--secondary button--lg"
to="/docs/intro-docs">
Code Docs 介绍 - 1min
</Link>
</div>
</div>
</header>
);
}
export default function Home() {
const {siteConfig} = useDocusaurusContext();
return (
<Layout
title={`Hello from ${siteConfig.title}`}
description="Description will go into a meta tag in <head />">
<HomepageHeader />
<main>
<HomepageFeatures />
</main>
</Layout>
);
}
+408 -10
View File
@@ -1,10 +1,414 @@
/* stylelint-disable docusaurus/copyright-header */
/**
* CSS files with the .module.css suffix will be treated as CSS modules
* and scoped locally.
*/
/* ══════════════════════════════════════════════════════════
Homepage Wrapper
══════════════════════════════════════════════════════════ */
.homepageWrapper {
display: flex;
flex-direction: column;
}
/* ══════════════════════════════════════════════════════════
Hero Background — dyte's noise-bg with grid pattern
══════════════════════════════════════════════════════════ */
.heroBg {
padding-bottom: 4rem;
background-color: #fafafa;
background-image:
linear-gradient(rgba(33, 96, 253, 0.03) 1px, transparent 1px),
linear-gradient(90deg, rgba(33, 96, 253, 0.03) 1px, transparent 1px);
background-size: 40px 40px;
border-bottom: 1px solid var(--ifm-toc-border-color);
}
[data-theme='dark'] .heroBg {
background-color: #111;
background-image:
linear-gradient(rgba(33, 96, 253, 0.06) 1px, transparent 1px),
linear-gradient(90deg, rgba(33, 96, 253, 0.06) 1px, transparent 1px);
background-size: 40px 40px;
}
/* ══════════════════════════════════════════════════════════
Hero Top Section (title + subtitle)
══════════════════════════════════════════════════════════ */
.heroTop {
padding: 5rem 1.5rem 3rem;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
gap: 1rem;
}
.heroBadge {
display: inline-block;
padding: 0.3rem 0.9rem;
border-radius: 9999px;
border: 1px solid rgba(33, 96, 253, 0.35);
background: rgba(33, 96, 253, 0.08);
color: #2160fd;
font-size: 0.8rem;
font-weight: 600;
letter-spacing: 0.04em;
text-transform: uppercase;
}
[data-theme='dark'] .heroBadge {
background: rgba(33, 96, 253, 0.15);
color: #7a9eff;
border-color: rgba(33, 96, 253, 0.4);
}
.heroTitle {
font-size: 3.5rem;
font-weight: 800;
line-height: 1.1;
letter-spacing: -0.03em;
color: #0f172a;
margin: 0;
}
[data-theme='dark'] .heroTitle {
color: #f1f5f9;
}
.heroTitleAccent {
color: #2160fd;
}
[data-theme='dark'] .heroTitleAccent {
color: #7a9eff;
}
.heroSubtitle {
max-width: 560px;
font-size: 1.1rem;
line-height: 1.7;
color: #475569;
margin: 0;
}
[data-theme='dark'] .heroSubtitle {
color: #94a3b8;
}
.heroButtons {
display: flex;
gap: 0.75rem;
flex-wrap: wrap;
justify-content: center;
margin-top: 0.5rem;
}
.btnPrimary {
display: inline-flex;
align-items: center;
padding: 0.65rem 1.5rem;
border-radius: 8px;
background: #2160fd;
color: #fff !important;
font-weight: 600;
font-size: 0.95rem;
text-decoration: none !important;
transition: background 0.2s, transform 0.15s, box-shadow 0.2s;
box-shadow: 0 2px 12px rgba(33, 96, 253, 0.35);
}
.btnPrimary:hover {
background: #1442c4;
transform: translateY(-1px);
box-shadow: 0 4px 20px rgba(33, 96, 253, 0.45);
color: #fff !important;
}
.btnOutline {
display: inline-flex;
align-items: center;
padding: 0.65rem 1.5rem;
border-radius: 8px;
border: 1.5px solid #cbd5e1;
background: transparent;
color: #334155 !important;
font-weight: 600;
font-size: 0.95rem;
text-decoration: none !important;
transition: border-color 0.2s, color 0.2s, background 0.2s;
}
.btnOutline:hover {
border-color: #2160fd;
color: #2160fd !important;
background: rgba(33, 96, 253, 0.04);
}
[data-theme='dark'] .btnOutline {
border-color: #334155;
color: #cbd5e1 !important;
}
[data-theme='dark'] .btnOutline:hover {
border-color: #7a9eff;
color: #7a9eff !important;
}
/* ══════════════════════════════════════════════════════════
Hero Cards (dyte-style: dark bg + blue hover gradient)
══════════════════════════════════════════════════════════ */
.heroCards {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 1.25rem;
max-width: 1200px;
margin: 0 auto;
padding: 0 1.5rem;
}
/* The card itself is the <Link> */
.heroCard {
position: relative;
display: flex;
flex-direction: column;
justify-content: space-between;
width: 360px;
border-radius: 1.5rem; /* rounded-3xl */
border: 1px solid #e2e8f0; /* secondary-700 light */
background: #f8fafc; /* secondary-900 light */
overflow: hidden;
cursor: pointer;
text-decoration: none !important;
color: #0f172a !important;
transition: border-color 0.25s ease,
background 0.25s ease,
box-shadow 0.25s ease,
color 0.25s ease,
transform 0.2s ease;
}
[data-theme='dark'] .heroCard {
border-color: #1e293b; /* secondary-700 dark */
background: #0f172a; /* secondary-900 dark */
color: #f1f5f9 !important;
}
/* ── Hover State ───────────────────────────────────── */
.heroCard:hover {
border-color: #2160fd;
background: linear-gradient(
135deg,
rgba(33, 96, 253, 0.15) 0%,
transparent 60%
);
box-shadow: 0 0 0 1px rgba(33, 96, 253, 0.25),
0 8px 30px rgba(33, 96, 253, 0.12);
color: #2160fd !important;
transform: translateY(-3px);
}
[data-theme='dark'] .heroCard:hover {
background: linear-gradient(
135deg,
rgba(33, 96, 253, 0.25) 0%,
transparent 60%
);
}
.heroCardContent {
padding: 1.5rem;
display: flex;
flex-direction: column;
gap: 0.75rem;
flex: 1;
}
.heroCardHeader {
display: flex;
align-items: center;
gap: 0.75rem;
}
.heroCardEmoji {
font-size: 1.75rem;
line-height: 1;
width: 2.5rem;
height: 2.5rem;
display: flex;
align-items: center;
justify-content: center;
border-radius: 0.75rem;
background: rgba(33, 96, 253, 0.08);
flex-shrink: 0;
transition: background 0.25s, transform 0.2s;
}
.heroCard:hover .heroCardEmoji {
background: rgba(33, 96, 253, 0.18);
transform: scale(1.1);
}
.heroCardTitle {
font-size: 1.2rem;
font-weight: 700;
margin: 0;
color: #0f172a;
transition: color 0.25s;
}
[data-theme='dark'] .heroCardTitle {
color: #f1f5f9;
}
.heroCard:hover .heroCardTitle {
color: #2160fd;
}
[data-theme='dark'] .heroCard:hover .heroCardTitle {
color: #7a9eff;
}
.heroCardText {
font-size: 0.9rem;
line-height: 1.65;
color: #64748b;
margin: 0;
transition: color 0.25s;
}
[data-theme='dark'] .heroCardText {
color: #94a3b8;
}
.heroCard:hover .heroCardText {
color: #1e40af;
}
[data-theme='dark'] .heroCard:hover .heroCardText {
color: #93c5fd;
}
.heroCardTags {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
margin-top: 0.25rem;
}
.heroCardTag {
display: inline-block;
padding: 0.15rem 0.55rem;
border-radius: 4px;
background: rgba(33, 96, 253, 0.07);
color: #2160fd;
font-size: 0.72rem;
font-weight: 600;
transition: background 0.2s;
}
.heroCard:hover .heroCardTag {
background: rgba(33, 96, 253, 0.15);
}
[data-theme='dark'] .heroCardTag {
background: rgba(33, 96, 253, 0.12);
color: #7a9eff;
}
/* Arrow in top-right */
.heroCardArrow {
position: absolute;
top: 1.1rem;
right: 1.2rem;
font-size: 1.25rem;
opacity: 0;
transform: translate(6px, -6px);
color: #2160fd;
transition: opacity 0.25s, transform 0.25s;
}
.heroCard:hover .heroCardArrow {
opacity: 1;
transform: translate(0, 0);
}
/* ══════════════════════════════════════════════════════════
Feature Strip
══════════════════════════════════════════════════════════ */
.featuresStrip {
background: #fff;
border-bottom: 1px solid var(--ifm-toc-border-color);
padding: 2.5rem 1.5rem;
}
[data-theme='dark'] .featuresStrip {
background: #161616;
}
.featuresInner {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 1.5rem;
max-width: 1100px;
margin: 0 auto;
}
@media (max-width: 900px) {
.featuresInner {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 480px) {
.featuresInner {
grid-template-columns: 1fr;
}
.heroCards {
flex-direction: column;
align-items: center;
}
.heroCard {
width: 100%;
max-width: 380px;
}
.heroTitle {
font-size: 2.2rem;
}
}
.featureItem {
display: flex;
align-items: flex-start;
gap: 0.8rem;
}
.featureIcon {
font-size: 1.6rem;
flex-shrink: 0;
margin-top: 0.1rem;
}
.featureTitle {
font-size: 0.9rem;
font-weight: 600;
color: #0f172a;
margin-bottom: 0.25rem;
}
[data-theme='dark'] .featureTitle {
color: #f1f5f9;
}
.featureDesc {
font-size: 0.8rem;
line-height: 1.5;
color: #64748b;
}
[data-theme='dark'] .featureDesc {
color: #94a3b8;
}
/* Legacy - kept for compatibility */
.heroBanner {
padding: 4rem 0;
text-align: center;
@@ -12,12 +416,6 @@
overflow: hidden;
}
@media screen and (max-width: 966px) {
.heroBanner {
padding: 2rem;
}
}
.buttons {
display: flex;
align-items: center;
+119
View File
@@ -0,0 +1,119 @@
import React from 'react';
import Layout from '@theme/Layout';
import Link from '@docusaurus/Link';
import styles from './index.module.css';
/* ── Hero Cards ────────────────────────────────────────────── */
const HERO_CARDS = [
{
id: 'backend',
emoji: '⚙️',
title: '后端技术',
link: '/docs/backend-doc/intro-docs',
text: '深入讲解 Spring Boot / Spring Cloud 核心概念,微服务架构、分布式缓存与性能调优,含真实项目案例',
tags: ['Spring Boot', 'Spring Cloud', 'MySQL', 'Redis'],
},
{
id: 'frontend',
emoji: '⚛️',
title: '前端开发',
link: '/docs/frontend-doc/intro-docs',
text: '系统化学习 React / Vue 现代框架,工程化实践、状态管理与跨端开发,构建高质量前端应用',
tags: ['React', 'Vue 3', 'Vite', 'TypeScript'],
},
{
id: 'algorithms',
emoji: '🧠',
title: '算法与面试',
link: '/docs/LeetCode/intro-docs',
text: '精选 LeetCode 题解与数据结构深析,系统设计面试指南,快速突破大厂技术面试关卡',
tags: ['LeetCode', '数据结构', '系统设计', '剑指Offer'],
},
];
/* ── Feature List ───────────────────────────────────────────── */
const FEATURES = [
{ icon: '🔍', title: '全文搜索', desc: '集成 Algolia DocSearch,毫秒级检索,快速定位任意知识点' },
{ icon: '🌙', title: '深色模式', desc: '完整支持深色/浅色主题切换,护眼阅读体验' },
{ icon: '📱', title: '响应式设计', desc: '适配桌面、平板、手机,随时随地查阅技术文档' },
{ icon: '⚡', title: '持续更新', desc: '技术团队持续维护,同步最新技术栈与面试题解' },
];
function HeroCard({ emoji, title, link, text, tags }) {
return (
<Link to={link} className={styles.heroCard}>
<div className={styles.heroCardContent}>
<div className={styles.heroCardHeader}>
<span className={styles.heroCardEmoji}>{emoji}</span>
<h3 className={styles.heroCardTitle}>{title}</h3>
</div>
<p className={styles.heroCardText}>{text}</p>
<div className={styles.heroCardTags}>
{tags.map(tag => (
<span key={tag} className={styles.heroCardTag}>{tag}</span>
))}
</div>
</div>
<div className={styles.heroCardArrow}></div>
</Link>
);
}
function FeatureItem({ icon, title, desc }) {
return (
<div className={styles.featureItem}>
<span className={styles.featureIcon}>{icon}</span>
<div>
<div className={styles.featureTitle}>{title}</div>
<div className={styles.featureDesc}>{desc}</div>
</div>
</div>
);
}
export default function Home(): JSX.Element {
return (
<Layout
title="CodeDocs — 全栈技术文档"
description="覆盖后端、前端、算法面试的一站式技术文档库,为全栈工程师打造"
wrapperClassName={styles.homepageWrapper}
>
{/* ── Hero ──────────────────────────────────────── */}
<div className={styles.heroBg}>
<section className={styles.heroTop}>
<span className={styles.heroBadge}></span>
<h1 className={styles.heroTitle}>
<span className={styles.heroTitleAccent}></span>
</h1>
<p className={styles.heroSubtitle}>
<strong> · · </strong>
</p>
<div className={styles.heroButtons}>
<Link className={styles.btnPrimary} to="/docs/backend-doc/intro-docs">
</Link>
<Link className={styles.btnOutline} to="/docs/intro-docs">
</Link>
</div>
</section>
{/* ── Hero Cards ────────────────────────────── */}
<section className={styles.heroCards}>
{HERO_CARDS.map(card => (
<HeroCard key={card.id} {...card} />
))}
</section>
</div>
{/* ── Feature Strip ────────────────────────────── */}
<section className={styles.featuresStrip}>
<div className={styles.featuresInner}>
{FEATURES.map(f => (
<FeatureItem key={f.title} {...f} />
))}
</div>
</section>
</Layout>
);
}
+184
View File
@@ -0,0 +1,184 @@
<div class="tech-dropdown">
<!-- Left Panel: Category Nav -->
<div class="tech-dropdown-left">
<a
href="/docs/backend-doc/intro-docs"
class="tech-menu-item"
data-dropdown-tech-menu="backend"
onmouseover="document.body.setAttribute('data-tech-menu','backend')"
onfocus="document.body.setAttribute('data-tech-menu','backend')"
>
<span class="tech-menu-icon">⚙️</span>
<div class="tech-menu-item-text">
<div class="tech-menu-item-title">后端技术</div>
<p class="tech-menu-item-desc">Spring Boot / Cloud · 数据库 · 分布式</p>
</div>
</a>
<a
href="/docs/frontend-doc/intro-docs"
class="tech-menu-item"
data-dropdown-tech-menu="frontend"
onmouseover="document.body.setAttribute('data-tech-menu','frontend')"
onfocus="document.body.setAttribute('data-tech-menu','frontend')"
>
<span class="tech-menu-icon">⚛️</span>
<div class="tech-menu-item-text">
<div class="tech-menu-item-title">前端开发</div>
<p class="tech-menu-item-desc">React · Vue · 工程化 · 跨端</p>
</div>
</a>
<a
href="/docs/LeetCode/intro-docs"
class="tech-menu-item"
data-dropdown-tech-menu="algorithms"
onmouseover="document.body.setAttribute('data-tech-menu','algorithms')"
onfocus="document.body.setAttribute('data-tech-menu','algorithms')"
>
<span class="tech-menu-icon">🧠</span>
<div class="tech-menu-item-text">
<div class="tech-menu-item-title">算法与面试</div>
<p class="tech-menu-item-desc">LeetCode · 数据结构 · 系统设计</p>
</div>
</a>
</div>
<!-- Right Panel: Links -->
<div class="tech-dropdown-right">
<!-- Backend -->
<div class="tech-panel" data-dropdown-tech="backend">
<div class="tech-panel-group">
<h3 class="tech-panel-heading">Spring 全家桶</h3>
<ul class="tech-panel-links">
<li><a href="/docs/backend-doc/SpringBoot/helloboot" class="tech-link">
<span>🌿</span> Spring Boot 入门
</a></li>
<li><a href="/docs/backend-doc/SpringCloud/hellocloud" class="tech-link">
<span>☁️</span> Spring Cloud 微服务
</a></li>
<li><a href="/docs/backend-doc/intro-docs" class="tech-link">
<span>📖</span> 后端文档总览
</a></li>
</ul>
</div>
<div class="tech-panel-group">
<h3 class="tech-panel-heading">数据库 &amp; 缓存</h3>
<ul class="tech-panel-links">
<li><a href="/docs/backend-doc/intro-docs" class="tech-link">
<span>🗄️</span> MySQL 核心
</a></li>
<li><a href="/docs/backend-doc/intro-docs" class="tech-link">
<span></span> Redis 实战
</a></li>
</ul>
</div>
<div class="tech-panel-group">
<h3 class="tech-panel-heading">并发 &amp; JVM</h3>
<ul class="tech-panel-links">
<li><a href="/docs/backend-doc/intro-docs" class="tech-link">
<span>🧵</span> 并发编程
</a></li>
<li><a href="/docs/backend-doc/intro-docs" class="tech-link">
<span></span> JVM 调优
</a></li>
</ul>
</div>
<div class="tech-panel-group">
<h3 class="tech-panel-heading">分布式</h3>
<ul class="tech-panel-links">
<li><a href="/docs/backend-doc/intro-docs" class="tech-link">
<span>🔗</span> 消息队列
</a></li>
<li><a href="/docs/backend-doc/intro-docs" class="tech-link">
<span>🏗️</span> 微服务治理
</a></li>
</ul>
</div>
</div>
<!-- Frontend -->
<div class="tech-panel" data-dropdown-tech="frontend">
<div class="tech-panel-group">
<h3 class="tech-panel-heading">核心框架</h3>
<ul class="tech-panel-links">
<li><a href="/docs/frontend-doc/React/helloreact" class="tech-link">
<span>⚛️</span> React 进阶
</a></li>
<li><a href="/docs/frontend-doc/Vue/hellovue" class="tech-link">
<span>💚</span> Vue 3 全指南
</a></li>
<li><a href="/docs/frontend-doc/intro-docs" class="tech-link">
<span>📖</span> 前端文档总览
</a></li>
</ul>
</div>
<div class="tech-panel-group">
<h3 class="tech-panel-heading">工程化实践</h3>
<ul class="tech-panel-links">
<li><a href="/docs/frontend-doc/intro-docs" class="tech-link">
<span></span> Vite / Webpack
</a></li>
<li><a href="/docs/frontend-doc/intro-docs" class="tech-link">
<span>📦</span> 构建与部署
</a></li>
</ul>
</div>
<div class="tech-panel-group">
<h3 class="tech-panel-heading">状态管理</h3>
<ul class="tech-panel-links">
<li><a href="/docs/frontend-doc/intro-docs" class="tech-link">
<span>🔄</span> Redux / Zustand
</a></li>
<li><a href="/docs/frontend-doc/intro-docs" class="tech-link">
<span>🍍</span> Pinia
</a></li>
</ul>
</div>
<div class="tech-panel-group">
<h3 class="tech-panel-heading">性能 &amp; 跨端</h3>
<ul class="tech-panel-links">
<li><a href="/docs/frontend-doc/intro-docs" class="tech-link">
<span>🚀</span> 性能优化
</a></li>
<li><a href="/docs/frontend-doc/intro-docs" class="tech-link">
<span>📱</span> 小程序 / RN
</a></li>
</ul>
</div>
</div>
<!-- Algorithms -->
<div class="tech-panel" data-dropdown-tech="algorithms">
<div class="tech-panel-group">
<h3 class="tech-panel-heading">LeetCode 题解</h3>
<ul class="tech-panel-links">
<li><a href="/docs/LeetCode/1 - 100/hello" class="tech-link">
<span>📝</span> 1-100 题
</a></li>
<li><a href="/docs/LeetCode/100 - 200/hello 100" class="tech-link">
<span>📝</span> 100-200 题
</a></li>
<li><a href="/docs/LeetCode/CodingInterviews/StackAndQueue/MaxValueOfQueue" class="tech-link">
<span>🎯</span> 剑指 Offer
</a></li>
</ul>
</div>
<div class="tech-panel-group">
<h3 class="tech-panel-heading">专项突破</h3>
<ul class="tech-panel-links">
<li><a href="/docs/LeetCode/intro-docs" class="tech-link">
<span>🏗️</span> 系统设计
</a></li>
<li><a href="/docs/LeetCode/intro-docs" class="tech-link">
<span>🧮</span> 数据结构
</a></li>
</ul>
</div>
</div>
</div>
</div>
+6
View File
@@ -0,0 +1,6 @@
{
"extends": "@docusaurus/tsconfig",
"compilerOptions": {
"baseUrl": "."
}
}
-9799
View File
File diff suppressed because it is too large Load Diff