主题
大型代码库与 Monorepo
为 monorepo/大型代码库分层配置,让 Claude 只聚焦当前任务涉及的代码。
是什么
大型代码库可以是一个有数百万行代码的单仓库,也可以是包含多个 package 的 monorepo。Claude Code 在任何规模下都能工作,但随着代码库增大,那些为小项目调优的默认行为会把与任务无关的指令和文件读取塞满 context window,既消耗 token 又拉低表现。本指南介绍如何把 Claude 的关注范围收窄到任务真正触及的那部分代码。每项设置都标明是属于本机个人配置,还是提交进仓库共享。
怎么工作
- 分层 CLAUDE.md:Claude 启动时加载工作目录及其所有父目录的 CLAUDE.md,子目录的文件在 Claude 读取该处文件时按需加载;常见做法是根目录放全局规则,每个 package/子系统放各自约定。
- 选择启动位置:从仓库根启动可访问全部文件、仅加载根 CLAUDE.md(子目录按需);从子目录启动只能访问该子树、加载该目录及所有祖先的 CLAUDE.md。注意 .claude/settings.json 只从启动目录加载,不像 CLAUDE.md 那样从父目录继承。
- 减少读取:内容搜索默认遵守 .gitignore(node_modules/、dist/、build/ 等自动排除);对已签入的生成代码或 vendored 依赖,用 permissions.deny 的 Read 规则阻止打开。
- 代码智能(code intelligence)插件接语言服务器,让 Claude 直接跳转定义、查找引用、暴露类型错误,而不是逐文件扫描。
- worktree 作用域:--worktree 在新 git worktree 中开会话隔离改动;worktree.sparsePaths 用 git sparse-checkout 只写出列出的目录加根级文件,配 symlinkDirectories 可把 node_modules 软链到主仓库副本。
- 跨 package/仓库访问:用 additionalDirectories 设置或 --add-dir 标志授予工作目录之外的读写权限。
- 按目录的 skills:放在子目录的 .claude/skills/ 下,Claude 判定相关时才按需加载;也可用 frontmatter 的 paths glob 按文件模式触发。
- 当分层 CLAUDE.md 难以治理时,把约定迁移到按需加载的 skills、plugins 或 MCP servers(如已有代码搜索/RAG 索引则暴露为 MCP 工具)。
怎么配置 / 用法
排除无关 CLAUDE.md(glob 匹配绝对路径,相对模式以 **/ 开头;个人配置放 .claude/settings.local.json):
json
{
"claudeMdExcludes": [
"**/packages/admin-dashboard/**",
"**/packages/legacy-*/**"
]
}阻止读取生成/vendored 代码:
json
{
"permissions": {
"deny": [
"Read(./**/dist/**)",
"Read(./**/build/**)",
"Read(./**/*.generated.*)",
"Read(./vendor/**)"
]
}
}安装代码智能插件(TypeScript 示例):
shell
/plugin install typescript-lsp@claude-plugins-officialworktree 稀疏检出 + 软链:
json
{
"worktree": {
"sparsePaths": [".claude", "packages/api", "packages/shared"],
"symlinkDirectories": ["node_modules"]
}
}跨目录访问:
json
{
"permissions": { "additionalDirectories": ["../shared", "../web"] }
}运行时授予(--add-dir 加目录后加载 CLAUDE.md/rules 需设环境变量):
bash
CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 claude --add-dir ../shared什么时候用
- 代码库是数百万行的单仓库或多 package 的 monorepo,默认行为开始把无关指令和文件读取塞满 context。
- 想只加载所触及代码的约定,而非一份覆盖所有子系统的根文件。
- 任务跨多个 package/子系统(从根启动)或某个 package 范围内(从该目录启动)。
- 需要在同一会话读写兄弟 package 或另一个仓库。
- worktree 在大仓库里检出全树太慢/太占空间,想只检出任务所需目录。
限制 / 坑
- claudeMdExcludes 是静态列表而非按任务开关;要换聚焦的 package 应改从该目录启动。
- Managed policy 的 CLAUDE.md 无法被排除,组织级指令始终生效。
- Read deny 规则覆盖内置文件工具及 cat/head/grep/find 等可识别的 Bash 文件命令,但不会从递归搜索输出中过滤被拒路径,也不覆盖自行打开文件的任意子进程。
- 代码智能插件需每台机器装好对应语言的 language server 二进制;受限网络须改用内部 Git 源或本地路径。
- 当 skills 数量很多时,描述会被截短,可能丢掉关键词;descriptions 要简短并把请求中会出现的词放前面。
硬事实速查(11 条)
- 从仓库根启动:可访问每个文件,仅根 CLAUDE.md 在启动时加载,子目录文件在读取时按需加载。
- 从子目录启动:仅能访问该子树(除非另行授权),加载该目录及每个祖先目录的 CLAUDE.md。
- .claude/settings.json 只从启动目录加载,不从父目录继承。
- claudeMdExcludes 可设在 user/project/local/managed 任一作用域,数组跨作用域合并。
- permissions.deny 的 Read 规则用于阻止打开已签入的生成代码/vendored 依赖;.gitignore 中的路径默认已排出搜索结果。
- worktree.sparsePaths 中的路径相对仓库根,且应列目录而非单个文件;根级文件总会被检出、根级目录不会,故需 .claude 才能在 worktree 内用到根的 .claude/settings.json。
- 同一会话内所有 worktree 共享同一份 sparsePaths;symlinkDirectories 把每个 worktree 的目录软链回主仓库副本以避免重复 node_modules。
- additionalDirectories 仅授予文件访问,永不加载该目录的 CLAUDE.md/rules/skills;--add-dir 或 /add-dir 会加载 skills,且设 CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 后才加载其 CLAUDE.md/rules。
- skills 放在子目录 .claude/skills/ 下按需加载;paths frontmatter 字段接 glob 可按文件模式触发(如 /migrations/)。
- plugin 的 skill 使用 plugin-name:skill-name 命名空间,不会与按目录 skill 冲突。
- 跨 package 改动建议:在一个会话中一次性给出整组改动,并先把 plan 写到仓库内的 markdown 文件(长会话会 compact,落盘 plan 能留存)。