open-code-review:配置驱动的开源代码评审工具实战指南
1. 为什么“代码评审”这件事值得单独造一个轮子第一次看到 open-code-review 这个名字我脑子里冒出来的第一个念头是GitHub、GitLab、Gerrit 这些平台自带的评审功能已经够用了为什么还要折腾一个独立的开源代码评审工具后来在一个十几人的小团队里待了一段时间我才真正理解这个需求是怎么长出来的。大平台的评审功能确实强但它的前提是“你已经把代码托管在它上面并且团队愿意接受它的工作流”。现实情况是很多团队代码放在自建 Git 服务上或者干脆是内网环境评审流程靠邮件、靠群里甩 diff、靠口头沟通。这种状态下评审质量完全取决于个人自觉没有留痕没有检查清单新人不知道看什么老人看两眼就点通过。open-code-review 这类工具要解决的核心问题就是把“评审”从一种依赖个人经验的随机行为变成一套可配置、可复用、可追溯的流程。它适合谁我觉得有三类人特别值得关注。第一类是中小团队的技术负责人没有资源去搭一套完整的 DevOps 平台但确实需要把代码质量卡住。第二类是开源项目的维护者PR 一多就顾不过来需要工具帮忙做初筛。第三类是想把评审能力沉淀下来的个人开发者把自己踩过的坑变成检查项下次评审直接照着走。这篇文章我会从设计思路、核心机制、实操落地到问题排查完整拆一遍尽量让你看完就能在自己项目里跑起来。2. 整体设计思路评审流程到底该怎么拆2.1 评审的本质是“检查清单 上下文 记录”在动手看任何工具之前我习惯先把这件事的本质想清楚。代码评审说白了就三件事看什么检查清单、在什么背景下看上下文、看完留下什么记录。大部分评审工具做得不好往往不是功能不够而是这三件事里有一件没做好。open-code-review 的设计思路我理解下来是把这三件事显式地拆开。检查清单不是写死在代码里的而是通过配置文件定义的你可以针对不同语言、不同目录配不同的规则。上下文这块它强调把 diff 和相关的文件、提交信息、issue 关联一起呈现而不是只给一个孤零零的 diff。记录这块评审结果会结构化保存方便后续统计和回溯。这个拆法看起来朴素但好处很明显规则可以随团队成长而演进不用改工具本身上下文可以按需扩展比如接入静态分析结果记录可以拿来做质量度量比如“这个模块最近三个月评审打回了多少次”。2.2 为什么选择“配置驱动”而不是“插件驱动”很多同类工具走的是插件路线核心很小功能全靠插件堆。open-code-review 更偏向配置驱动我觉得这个选择跟它的目标用户有关。插件路线灵活但门槛高你得会写插件才能定制。配置驱动门槛低改个 YAML 或者 JSON 就能调整行为对中小团队更友好。当然配置驱动也有代价就是表达能力有上限。遇到特别复杂的逻辑配置写起来会很绕。我的经验是把 80% 的常见规则用配置覆盖剩下 20% 的极端情况留一个扩展点就够了。open-code-review 在这块留了自定义脚本的入口算是兼顾了两头。2.3 评审粒度按提交、按分支还是按合并请求这是落地时第一个要做的决策。按提交评审粒度最细但噪音大一个功能拆成十个提交评审十次谁都受不了。按分支评审适合长期分支但分支一多就乱。按合并请求或者叫变更集评审是最贴近实际工作的一个变更集对应一个完整的功能或修复评审一次上下文完整。open-code-review 默认是按变更集来组织的我觉得这个默认值选得对。它把一次评审绑定到一个明确的变更范围上diff 是完整的讨论是聚焦的记录也是干净的。如果你团队习惯按提交走也可以在配置里调整但我不太推荐除非你们提交粒度控制得非常好。3. 核心机制拆解规则、上下文与记录怎么落地3.1 规则引擎检查项是怎么被匹配和执行的规则引擎是这类工具的心脏。open-code-review 的规则匹配我实测下来分两层第一层是文件路径匹配第二层是内容模式匹配。文件路径匹配决定这条规则对哪些文件生效比如src/**/*.java只对 Java 源码生效。内容模式匹配决定具体检查什么比如是否包含某个关键字、是否符合某个正则、行数是否超过阈值。这里有个细节值得说规则执行的顺序。如果多条规则同时命中一个文件是按配置顺序串行执行还是并行我翻了下它的实现思路是串行按优先级执行高优先级的规则先跑跑完可以决定是否短路。这个设计的意义在于你可以把“致命问题”的规则优先级调高一旦命中就直接阻断不用再跑后面的规则省时间也省注意力。配置示例大概长这样我用的是 YAMLrules: - id: no-console-log description: 生产代码禁止提交 console.log paths: - src/**/*.js - src/**/*.ts pattern: console\\.log severity: error priority: 100 - id: max-function-length description: 单个函数不超过 80 行 paths: - src/**/*.java type: function-length threshold: 80 severity: warning priority: 50severity决定命中后的处理方式error 阻断warning 提示info 仅记录。priority决定执行顺序数字越大越先跑。这套配置我用了两个月最大的感受是规则不要一次加太多先加三条最痛的跑顺了再慢慢加否则一开始就几十条规则评审的人会被淹没。3.2 上下文聚合让评审者不用来回跳转评审效率低的一个大原因是评审者要不停地在 diff、源文件、issue、文档之间跳。open-code-review 在上下文聚合上做了几件事我觉得都挺实用。第一diff 会带上足够的上下文行数。默认是前后各 5 行可以在配置里调。我一般调到 10 行因为很多 bug 的线索就在改动点附近十几行内。第二相关的文件会被关联进来。比如你改了一个接口实现了这个接口的类会被自动列出来评审者一眼能看到影响面。第三提交信息和关联的 issue 会展示在评审界面顶部评审者不用去别的地方查这个改动是为什么做的。这个聚合逻辑背后其实是一个“影响面分析”的思路。改动的直接 diff 只是冰山一角真正要评审的是这个改动带来的连锁反应。工具帮你把连锁反应的第一层捞出来评审者就能把精力放在判断上而不是找信息上。3.3 记录与追溯评审结果怎么存、怎么查评审记录如果只是存个“通过/不通过”那价值很有限。open-code-review 的记录是结构化的每条规则的命中情况、评审者的评论、最终结论都会存下来。我比较看重的是它支持按规则维度统计比如“no-console-log 这条规则最近一个月命中了多少次”这个数据能反过来告诉你团队在哪个问题上反复犯错是不是该做一次专项培训或者加一道 CI 卡点。存储格式我看了下是 JSON 为主方便程序处理。如果你要接自己的报表系统直接读这些 JSON 就行。我自己的做法是每周拉一次记录看看 error 级别的命中趋势如果某条规则一直高居榜首说明要么规则太严要么团队习惯没养成得针对性处理。4. 实操落地从零把 open-code-review 跑起来4.1 环境准备与安装假设你是在一个 Linux 或者 macOS 的开发机上操作Windows 用 WSL 也行。前置依赖主要是运行时环境我用的版本是 Node.js 18 以上Python 3.9 以上也支持看你团队熟悉哪个。安装方式我推荐用包管理器省得自己处理依赖。# 以 npm 为例 npm install -g open-code-review # 验证安装 ocr --version装完之后第一件事是初始化配置。在项目根目录跑ocr init它会生成一个.ocr目录里面包含默认的规则配置和项目级设置。我建议把这个目录纳入版本管理这样团队每个人的评审规则是一致的。默认配置里有一些通用规则比如禁止提交大文件、禁止提交密钥这些先留着后面按需增删。4.2 配置你的第一条自定义规则默认规则跑通之后就可以加自己的规则了。我拿一个真实场景举例我们团队之前出过一次事故有人在配置文件里写死了数据库密码提交上去了。后来我加了一条规则专门扫配置文件里的敏感字段。rules: - id: no-hardcoded-secret description: 配置文件中禁止硬编码密码或密钥 paths: - config/**/*.yaml - config/**/*.yml - config/**/*.properties pattern: (password|secret|token|key)\\s*[:]\\s*[\]?[A-Za-z0-9/]{8,} severity: error priority: 200这条规则的关键在正则。password|secret|token|key匹配字段名后面跟冒号或等号再跟一个长度至少 8 的字符串。这个长度阈值是我调过的太短会误报太长会漏报。实测下来 8 是个比较平衡的值。priority设成 200比默认规则高保证它先跑一旦命中直接阻断。加完规则记得跑一次验证ocr check --config .ocr/rules.yaml它会输出所有规则的加载情况如果有语法错误会直接报出来。我踩过的坑是 YAML 缩进用 Tab 导致解析失败一定要用空格。4.3 接入现有的工作流工具本身跑起来只是第一步关键是让它嵌入团队现有的工作流。open-code-review 提供了几种接入方式我按推荐程度排一下。第一种是命令行直接跑适合本地开发时自查。在提交前跑一次ocr review --staged只检查暂存区的改动速度快反馈及时。第二种是接入 CI在流水线里加一步对合并请求做全量检查。这种方式能保证卡点但反馈慢一些。第三种是接入 Git 钩子在 pre-push 阶段跑介于两者之间。我自己的组合是本地用 pre-commit 钩子跑轻量规则CI 里跑全量规则。轻量规则只包含 error 级别的保证不阻断正常开发全量规则包含所有级别作为合并前的最后一道关。这个组合跑了大半年误报导致的阻塞很少团队接受度比较高。CI 配置示例以常见的流水线配置为例stages: - review code-review: stage: review script: - ocr review --base $CI_MERGE_REQUEST_TARGET_BRANCH --head $CI_COMMIT_SHA --format json review-result.json - ocr report --input review-result.json --fail-on error only: - merge_requests--fail-on error的意思是只要有 error 级别的命中这一步就失败合并被阻断。warning 和 info 只记录不阻断。这个阈值可以根据团队成熟度调整刚开始可以设成--fail-on none只观察不阻断等规则调稳了再收紧。4.4 评审结果怎么看、怎么用跑完之后的结果展示我比较喜欢它的 JSON 输出因为可以自己加工。默认的文本输出长这样[ERROR] src/config/db.yaml:12 - no-hardcoded-secret 配置文件中禁止硬编码密码或密钥 命中内容: password: abc12345 [WARNING] src/service/UserService.java:45 - max-function-length 单个函数不超过 80 行 当前长度: 92 行文本输出适合人看JSON 输出适合机器处理。我一般会把 JSON 结果存下来按周做一次汇总看看哪些规则命中最多。这个数据对调整规则很有帮助命中太多的规则要么放宽阈值要么说明团队确实需要加强这方面的意识。5. 常见问题与排查技巧实录5.1 规则误报太多怎么办这是最常见的问题没有之一。我刚开始配规则的时候一条正则写得太宽把正常的日志输出全命中了评审界面一片红团队直接炸锅。后来我总结了一个调参流程先设成 info 级别跑一周收集命中数据看看误报率。如果误报超过 30%就收紧正则或者加排除路径。如果误报在 10% 以下可以升到 warning。error 级别一定要慎用只有那种“命中就一定是问题”的规则才配 error。排除路径的配置也很重要比如测试文件、生成的代码、第三方库这些通常不需要按生产标准检查。配置里加一个exclude字段就行rules: - id: no-console-log paths: - src/**/*.js exclude: - src/**/*.test.js - src/**/__tests__/**5.2 大仓库跑得太慢怎么优化仓库一大全量扫描就慢。我试过在一个几万文件的仓库上跑第一次跑了快十分钟完全没法接受。优化思路有几个第一只扫变更集涉及的文件不要全量扫--staged或者--diff参数就是干这个的。第二规则按路径分组只加载跟变更文件相关的规则减少无效匹配。第三把耗时的规则比如需要解析 AST 的放到 CI 里跑本地只跑轻量的文本匹配规则。实测下来只扫变更文件能把时间压到几秒到几十秒完全可接受。全量扫描留给 CI 的定时任务比如每天凌晨跑一次作为兜底。5.3 团队不配合怎么推工具再好团队不用也是白搭。我推这个工具的时候踩过的坑是一上来就加了一堆规则还设成 error 阻断结果大家提交代码频繁被卡怨声载道。后来我改了策略分三步走。第一步只观察不阻断跑两周把数据拿出来给大家看让大家意识到问题确实存在。第二步挑三条大家公认最痛的规则设成 warning提示但不阻断。第三步等大家习惯了提示再把其中最重要的一条升到 error。整个过程花了大概两个月但推下来之后没人抵触因为每一步都是大家参与决策的。5.4 常见问题速查表问题现象可能原因排查方法解决方式规则不生效路径匹配写错用ocr check --verbose看规则加载情况检查 glob 语法注意**和*的区别误报率高正则太宽导出命中记录人工抽样看收紧正则加 exclude 路径跑得慢全量扫描看日志里扫描的文件数改用--diff只扫变更CI 里失败但本地通过环境差异对比两边的配置文件和版本锁定工具版本配置纳入版本管理记录查不到存储路径没配看配置里的output字段指定绝对路径确保有写权限5.5 几个我踩过的坑第一个坑是配置文件编码。有一次在 Windows 上编辑配置存成了 GBK 编码工具读出来乱码规则全部失效。后来统一要求 UTF-8再没出过问题。第二个坑是规则优先级冲突。两条规则同时命中一个文件优先级一样执行顺序不确定导致结果不稳定。后来我给所有规则都显式指定了 priority避免依赖默认顺序。第三个坑是忽略了大文件。有个仓库里有个几十兆的日志文件被误提交扫描的时候直接把内存吃满了。后来加了一条规则超过一定大小的文件直接跳过。6. 进阶玩法把评审数据用起来6.1 用评审记录做质量度量评审记录不只是用来卡点的它其实是一份很好的质量数据。我现在的做法是每月拉一次记录统计几个指标error 命中总数、按规则分组的命中分布、按目录分组的命中分布。这几个指标能回答一些问题比如“哪个模块的代码质量最差”“哪类问题反复出现”。举个例子我发现no-hardcoded-secret这条规则连续三个月命中数最高说明团队在配置管理上确实有系统性问题。后来我们专门做了一次配置管理的规范培训下个月这条规则的命中数直接降了 70%。这个反馈闭环是单纯靠人工评审很难做到的。6.2 和静态分析工具配合open-code-review 的规则引擎擅长文本模式和简单的结构检查但复杂的语义分析它做不了。这时候可以跟静态分析工具配合比如 ESLint、Checkstyle、SonarQube。做法是把静态分析的结果转成 open-code-review 能识别的格式统一展示。我试过把 ESLint 的 JSON 输出转成 open-code-review 的规则命中格式然后在评审界面里一起展示。这样评审者只需要看一个界面不用在多个工具之间切换。转换脚本不复杂核心就是字段映射把 ESLint 的ruleId映射成规则 idmessage映射成描述line映射成行号。6.3 自定义脚本扩展配置覆盖不到的场景可以用自定义脚本。open-code-review 支持在规则里指定一个脚本路径命中之后执行脚本做进一步判断。比如你可以写一个脚本检查某个函数是否被正确加了注解这种逻辑用正则很难写准用脚本就灵活多了。脚本的接口很简单输入是文件路径和命中位置输出是一个布尔值或者一个结构化的结果。我用 Python 写过一个检查数据库迁移脚本命名规范的扩展跑得挺稳。需要注意的是脚本的执行权限和超时设置别让一个死循环的脚本把整个评审卡死。7. 我对这套工具的真实体会用 open-code-review 这段时间最大的感受是它把“评审”这件事从模糊变清晰了。以前评审靠感觉现在评审有清单、有记录、有数据。当然它也不是银弹规则配得不好照样会变成噪音源团队不配合照样推不动。我的经验是工具只是载体真正起作用的是背后那套“发现问题、沉淀规则、持续改进”的循环。如果你正准备在团队里引入类似的工具我的建议是从小处着手先解决一个最痛的问题跑通了再扩展。别一上来就追求大而全那样大概率会半途而废。另外规则是活的要定期回顾和调整半年前合适的阈值现在可能就不合适了。我自己是每季度做一次规则评审该删的删该改的改保持规则集精简有效。最后分享一个小技巧把评审记录里的高频问题整理成一个“团队避坑清单”放在项目文档里新人入职先看这个。这比任何培训都管用因为每一条都是真实踩过的坑。

相关新闻

MCP生态崛起:AI应用连接外部系统的标准化协议实践指南

MCP生态崛起:AI应用连接外部系统的标准化协议实践指南

“MCP生态”这四个字,最近在我周围的技术讨论里出现的频率高得吓人。前一阵还在聊Function Calling怎么做得更顺手,过了一个月,几乎所有一线大厂都在往MCP上砸资源。连接不同数据源的组件仓库存量一下子多了起来,各家AI编程助手也…

2026/10/19 3:33:12 阅读更多 →
AI新范式:从预测下一个词到预测世界状态

AI新范式:从预测下一个词到预测世界状态

最近很多朋友在转一份技术趋势报告,某AI前沿研究机构把2026年的核心议题锚定在一个转换上:从“预测下一个词”到“预测世界状态”。这句话我读了三遍,越读越觉得它不是在造概念,而是在给过去几年大模型的发展阶段收尾,…

2026/10/19 3:33:12 阅读更多 →
open-code-review 从零搭建:开放式代码评审方法论与落地实践

open-code-review 从零搭建:开放式代码评审方法论与落地实践

1. 从零搭建 open-code-review 的动机与整体思路第一次听到“open-code-review”这个词,很多人会下意识以为它又是一个代码托管平台自带的评审插件。实际上,它更像是一套开放式的代码评审方法论与工具链组合——核心思路是把“评审”这件事从某个特定平台…

2026/10/19 3:33:12 阅读更多 →

最新新闻

AI春节档深度观察:拜年玩法、创作工具与行业真相

AI春节档深度观察:拜年玩法、创作工具与行业真相

1. 春节档的主角,从电影院跑到了AI里我这两年有个很直观的感受:一进腊月,朋友圈里的AI产品广告比年货广告还密集。今天这家上线"拜年大模型",明天那家推出"国风写真生成器",后天又有人发布"数…

2026/10/19 5:59:36 阅读更多 →
Hadoop+Python租房数据分析:从环境搭建到答辩演示全流程

Hadoop+Python租房数据分析:从环境搭建到答辩演示全流程

每年到这个节点,总能在后台收到一大堆“求救”私信,十个里有八个是问大数据方向毕业设计怎么落地。倒不是题目难想,而是很多人拿到题目之后才发现:环境搭不出来、数据填不进去、图表显示空、演示时一跑就崩。今天拿一个很典型的题…

2026/10/19 5:59:36 阅读更多 →
Function Calling与MCP:给AI模型装“手脚”的选型指南

Function Calling与MCP:给AI模型装“手脚”的选型指南

最近跟几个搞AI应用的同行聊天,发现大家关注的话题在变:前一阵子还停留在“你接哪个模型”,现在冒出来两个高频词——Function Calling 和 MCP。前者代表“让模型学会调用外部工具”的成熟玩法,后者是刚火起来的一套统一协议。说直…

2026/10/19 5:59:36 阅读更多 →
Python疫情数据分析与可视化完整课设:爬虫、预测与NLP情感分析实战

Python疫情数据分析与可视化完整课设:爬虫、预测与NLP情感分析实战

简介:这是一份面向计算机、电子信息工程、数学等专业学生的新冠肺炎疫情数据分析与可视化Python课程设计/大作业完整项目,可作为毕业设计参考。项目由导师指导并获98分,完整覆盖数据采集、清洗、时序预测、NLP情感分析与可视化展示全流程。压…

2026/10/19 5:59:36 阅读更多 →
命令模式实战:告别万能if-else,搞定撤销与宏命令

命令模式实战:告别万能if-else,搞定撤销与宏命令

干开发这些年,我重构过不少“万能控制器”——一个按钮类,从开灯、关灯、开空调、调温度,到撤销、重做、一键全关,几十个if-else分支堆在一起。每次加需求都像在雷区里行走,改一处逻辑,另外三处跟着崩。后来…

2026/10/19 5:59:36 阅读更多 →
直流伺服电机电气信号分层解析与示波器调试指南

直流伺服电机电气信号分层解析与示波器调试指南

循环系统建立后,电气信号的观察大局做嵌入式这几年,直流伺服电机是我打交道最多的执行部件之一。你可能会觉得“电信号嘛,无非就是电源线加两根控制线”,可真把示波器探头挂上去,你会看到同时存在功率线、逻辑线、反馈…

2026/10/19 5:58:35 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →