Files
chan/CLAUDE.md
2026-08-11 16:17:49 +08:00

6.0 KiB
Raw Blame History

CLAUDE.md

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

项目:缠论研习社——缠中说禅《教你炒股票》原文与杂文的沉浸式阅读站。

命令

pnpm install      # 安装依赖(需 Node 20+ 与 pnpm
pnpm dev          # 开发服务器 → http://localhost:5173vite open 自动开浏览器)
pnpm build        # vue-tsc -b 类型检查 + vite 生产构建
pnpm build:only   # 跳过类型检查,仅 vite build
pnpm typecheck    # 仅 vue-tsc -b 类型检查(改完 TS/Vue 先跑这个)
pnpm preview      # 预览生产构建

本机 pnpm v11 用 pnpm-workspace.yamlallowBuilds(不是 onlyBuiltDependencies)放行 esbuild / vue-demi 的构建脚本;新增带构建脚本的 devDep 时需在此手动放行,否则安装会被拦。

样式约定(重要)

每个用 Tailwind 写的元素必须带一个「标记类名」

用 Tailwind 工具类写样式时,必须给每个有独立含义的元素加一个语义化的标记 class并放在 class 列表最前面。这样用户在对话里能精确指代「改哪个 div」。

<!--  不要纯工具类堆叠用户无法指代 -->
<div class="flex items-center gap-2 rounded-md bg-surface px-3 py-2">

<!--  标记类名打头组件名__部位kebab-case -->
<div class="article-card__lesson flex items-center gap-2 rounded-md bg-surface px-3 py-2">

命名规则:<组件或区块名>__<部位>,如 home-hero__titlereader-metaarticle-card__tags。一个 .vue 文件内的标记类名以该组件的功能名为前缀,保证跨组件不撞。

现存组件(如 ArticleCard.vue)尚未遵循此约定;新建或重写元素时一律补上,改动既有元素时顺手补。

颜色必须走设计 Token禁止裸色值

所有颜色用 src/style.css@theme inline 定义的语义类,不要写 bg-white / text-gray-500 / #fff 这类

  • 背景:bg-app(应用底)/ bg-background(卡片)/ bg-surface / bg-surface-2 / bg-hover
  • 文本:text-foreground / text-muted / text-subtle / text-faint
  • 品牌/语义:text-primary / bg-primary-soft / text-success / text-warning / text-danger
  • 边框:border-line / border-line-strong / border-line-card
  • 圆角用 rounded-xs/sm/md/lg/xl/2xl4/8/12/16/20/24阴影用 shadow-xs/sm/soft/md/lg/xl

亮/暗主题切换靠 <html class="dark">,所有语义色自动适配——只要用 Token就不用单独写 dark: 变体

class 合并用 cn()

src/utils/cn.tscn() = clsx条件+ tailwind-merge冲突后写覆盖前写px-2 px-4 → px-4)。有条件 class 或动态拼接时用它,别手写字符串拼接。

架构(需要跨文件理解的)

技术栈Vue 3 <script setup> + Vite 6 + Tailwind v4CSS-first @theme+ TS strict + Pinia + Vue Router 4 + markdown-it + lucide-vue-next。@ 别名 → src/

数据层是完全解耦的(核心设计)

页面不直接读数据文件,而是通过 src/composables/useArticles.ts:它把 chanlunLessonsdata/chanlun.ts)和 essaysdata/essays.ts)合并,提供 chanlun / essaysList / latest / featured / find() / neighbors() / search()

  • 接入真实抓取数据时:只改数据源(替换 data/*.ts)或把 useArticles.ts 内的静态数组改成异步请求,页面和组件无需改动
  • 文章正文是 markdown 字符串Article.content,见 types/article.ts)。抓取的 HTML 入库时转 markdown或扩展 useMarkdown.ts 直接渲染 HTML。

文章正文排版 = .prose-chan(不要手写)

正文区一律挂 prose-chan 类(定义在 style.css@layer components),它已处理 h2/h3/p/blockquote/code/table/列表等全部排版。字号/字体不写死,而是通过 data-sizesm|base|lg|xl)和 data-fontserif|sans)属性驱动,值来自 reading store。

两个 Pinia store 驱动全局体验

  • stores/theme.tslight | dark | system,持久化到 localStorage['chan-theme'],靠给 <html>.dark 生效。
  • stores/reading.ts:字号 / 字体 / 专注模式,分别持久化。
  • 防闪烁FOUCindex.html 里有段内联脚本在 Vue 挂载前同步读 chan-theme.dark。改主题存储 key 时,index.html 脚本和 stores/theme.ts 必须同步改,否则首屏会闪。

路由与布局

5 个 view两种 layout

  • DefaultLayout/):顶栏 + 侧栏 + 内容 + 页脚,包 home / chanlun / articles / about。
  • ReaderLayout/read/:category/:slug):沉浸阅读,含阅读进度、阅读设置、上下篇导航。
  • markdown 的 h2/h3 会被 useMarkdown.ts 注入 idslug 来自 utils/slug.ts),便于锚点跳转。

现存组件缺标记类名

components/ui/BaseButton/Badge/Card/SearchInputcomponents/layout/AppHeader/AppSidebar/AppFooterArticleCard 等目前是纯工具类。改动它们时按上面的「标记类名」约定补齐。

其他约定

  • TS strict 且开了 noUnusedLocals / noUnusedParameters未用的 import / 变量会直接让 pnpm build 失败,删代码时记得清干净。
  • <script setup lang="ts"> + Composition API。
  • 图标:默认用 lucide-vue-nextVue 组件,按需 tree-shake。另装了 Remix Iconwebfont补 lucide 缺的图标,品牌 Logo 即用 ri-line-chart-line
    • CSS 已在 main.ts 全局引入 remixicon/fonts/remixicon.css,直接用 <i class="ri-xxx-line" aria-hidden="true"></i>
    • webfont 字号靠 text-*font-size 驱动,不用 size-*);颜色继承 currentColor,所以放在 text-white 的容器里就是白色。
    • 图标名查 https://remixicon.comv4.9,无 candlestick走势/图表类可用 ri-line-chart-line / ri-bar-chart-line / ri-stock-line / ri-funds-line)。
  • verbatimModuleSyntax: true:类型 import 必须写 import type { ... }