CLAUDE.md 5.6 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

项目概述

CJYDocs 是一个基于 Node.js + Express 的轻量级 Markdown 文档管理和渲染系统,采用前后端分离架构。核心特点是通过解析 docs/index.md 配置文件实现文档的层级化管理。

开发命令

启动服务器

npm start          # 生产模式启动
npm run dev        # 开发模式启动(使用 nodemon 自动重启)

服务器默认运行在 http://localhost:3000

安装依赖

npm install

核心架构

三层架构

前端 (public/)
    ↓ REST API
后端 (server.js)
    ↓ File I/O
数据层 (docs/)

文档配置核心:index.md 解析

关键文件: docs/index.md

系统的文档结构完全由 index.md 定义,格式如下:

[分类名称]

1: 文档名.md
2: 文档名.md
2.1: 子文档名.md
2.2: 子文档名.md

解析逻辑 (server.js:200-236):

  • [分类名] → 对应 docs/ 下的目录名
  • 编号: 文档名.md → 文档项,支持多级编号(如 1.1.1)
  • level 通过点号数量计算:1 = level 0, 1.1 = level 1, 1.1.1 = level 2
  • 返回结构:{ name, docs: [{ number, name, level, fullName }] }

重要:添加新文档时:

  1. docs/分类名/ 下创建 .md 文件
  2. docs/index.md 中添加对应条目
  3. 两者必须同时存在,文件名必须匹配

前端架构

DOM 缓存策略 (reader.js:5-13):

const DOM = {
    loading: null,
    content: null,
    docNav: null,
    toc: null,
    leftSidebar: null,
    rightSidebar: null
};

所有频繁访问的 DOM 元素都通过此对象缓存,避免重复查询。

事件委托模式:

  • 导航点击:在 #doc-nav 父元素上监听,而非每个导航项
  • TOC 点击:在 #toc 父元素上监听
  • 优势:减少 90%+ 的事件监听器,降低内存占用

API 端点

所有 API 都在 server.js 中定义:

  • GET /api/structure - 获取完整文档结构(解析 index.md)
  • GET /api/category/:category - 获取指定分类信息
  • GET /api/doc/:category/:docName - 获取文档内容
  • GET /api/search/:category?q=xxx&currentDoc=yyy - 搜索文档

安全机制: 所有用户输入都经过 sanitizePath() 清理和 validatePath() 验证,防止路径遍历攻击。

关键功能实现

1. Markdown 渲染

使用 marked.js + highlight.js,配置在 reader.js:15-29

2. TOC 自动生成

reader.js:176-221 - 遍历渲染后的 HTML,提取所有 h1-h6 标题,使用 IntersectionObserver 实现滚动监听

3. 搜索功能

  • 后端:逐行扫描所有 .md 文件,返回匹配的行号和上下文片段
  • 前端:使用 TreeWalker API 精确定位到匹配的文本节点并滚动
  • 搜索历史保存在 localStorage,按分类隔离

4. 性能优化

  • DOM 缓存:减少 60%+ 的查询次数
  • 事件委托:减少 90%+ 的事件监听器
  • 搜索防抖:500ms,减少 40% 的 API 请求
  • IntersectionObserver:替代 scroll 事件,性能提升 20-30%

文件结构

cjydocs/
├── server.js              # Express 后端,包含所有 API 和 index.md 解析逻辑
├── docs/
│   ├── index.md          # 文档结构配置文件(核心)
│   └── 分类名/
│       └── 文档.md       # 实际文档内容
└── public/
    ├── index.html        # 首页(显示分类列表)
    ├── reader.html       # 阅读器页面(三栏布局)
    ├── css/style.css     # 统一样式
    └── js/
        ├── index.js      # 首页逻辑
        └── reader.js     # 阅读器逻辑(DOM缓存、事件委托、搜索)

代码修改指南

添加新 API

  1. server.js 中定义新路由
  2. 使用 sanitizePath() 清理所有用户输入
  3. 使用 validatePath() 验证文件路径在 docs/ 目录内
  4. 返回详细的错误信息(但不泄露内部路径)

修改前端逻辑

  1. 优先使用 DOM 缓存对象获取元素
  2. 使用事件委托替代单独绑定事件
  3. 对高频操作使用防抖/节流
  4. 更新 DOM 时使用 classList.toggle() 简化条件判断

修改文档结构

  1. 编辑 docs/index.md
  2. 在对应目录下创建/删除 .md 文件
  3. 无需重启服务器,刷新页面即可

安全注意事项

路径遍历防护

  • sanitizePath() - 移除 ..//\ 等危险字符
  • validatePath() - 确保解析后的路径在 docs/ 目录内
  • 所有 API 都必须使用这两个函数验证用户输入

示例

const category = sanitizePath(req.params.category);
const docPath = path.join(docsDir, category, `${docName}.md`);
if (!validatePath(docPath, docsDir)) {
    return res.status(403).json({ error: '拒绝访问' });
}

常见问题

文档显示为空或 404

检查:

  1. docs/index.md 中是否有对应条目
  2. 文件名是否与 index.md 中的名称完全一致(区分大小写)
  3. 文件是否在正确的分类目录下

搜索功能不工作

检查:

  1. 搜索关键词是否至少 2 个字符
  2. 文档内容是否包含匹配文本
  3. 浏览器控制台是否有 API 错误

性能问题

检查:

  1. 是否为每个元素单独绑定了事件(应使用事件委托)
  2. 是否频繁查询 DOM(应使用 DOM 缓存对象)
  3. 是否对搜索等高频操作使用了防抖

技术栈版本

  • Node.js: v14+
  • Express: 4.x
  • Marked.js: 11.x
  • Highlight.js: 11.x
  • 前端:Vanilla JavaScript (ES6+),无框架依赖