
highlight.js 贡献指南从语言语法到核心解析引擎的开源参与完整实战【免费下载链接】highlight.jsJavaScript syntax highlighter with language auto-detection and zero dependencies.项目地址: https://gitcode.com/gh_mirrors/hi/highlight.js导读CONTRIBUTING.md 是 highlight.js 项目面向所有潜在贡献者的官方入门文档它定义了项目的设计哲学、功能与语言请求流程、Bug 报告规范、Pull Request 工作流以及 AI 辅助贡献政策。本篇指南以该文档为主线结合当前仓库中的 package.json、tools/build.js、test/index.js 与 docs/ai-contributions.md 等源码与文档逐层展开讲解非程序员如何参与社区、如何正确提出新语言支持、如何搭建开发环境并完成一次合格的构建与测试以及如何遵循项目规范提交被维护者认可的 PR。读完本文你将掌握参与 highlight.js包括但不限于语言语法贡献、核心解析引擎修复、文档完善所需的完整实操路径。欢迎与项目哲学贡献者先要理解的事highlight.js 是一个零依赖的 JavaScript 语法高亮引擎其核心引擎致力于保持小巧、简单、易用——目标只是覆盖语法高亮的happy path常见路径而把边缘情况交给插件体系处理。这一点直接决定了贡献者的工作边界具体体现为三条设计原则拥抱插件与扩展而非堆砌小特性核心不会为了每个边缘需求新增配置旋钮而是鼓励通过插件机制扩展能力。一个典型案例就是行号功能——官方文档 docs/line-numbers.rst 明确指出缺少行号被视为特性需要行号的场景应交给插件或第三方扩展解决。尽力理解局部上下文但绝不追求成为完整的语言解析器highlight.js 做得比纯关键字着色更多会尝试理解局部上下文如区分字符串、注释、正则字面量但不会去实现完整的编译原理级语法分析。这意味着贡献语法时应当够用即可不必追求面面俱到。语言自动检测不是魔法自动检测是尽力而为best effort的实现项目方对此有清醒认识。如果你认为自己能改进自动检测的相关性评分relevance算法那将是非常有价值的贡献方向。不编程也能贡献项目明确强调你不必是程序员。贡献路径是多元的包括但不限于在社区频道中帮助解答用户问题报告新 Bug 或参与已有 issue 的讨论提交解决具体 issue 的 Pull Request编写扩展核心能力的插件可参考 docs/plugin-api.rst 与 docs/plugin-recipes.rst编写第三方语言语法定义以提升语言支持可参考 docs/language-guide.rst 与 docs/language-contribution.rst设计新主题可参考 docs/theme-guide.rst仓库中的 src/styles 目录即存放全部现成主题改进文档让说明更清晰易懂。各项贡献所需的前提技能贡献方向前提技能要求解答 issue 或社区提问只需友善、乐于助人语言语法定义通常需要熟悉正则表达式语法规则的核心载体核心解析引擎需要掌握JavaScript文档工作愿意且擅长把事情写清楚语法细节审校对某门被支持语言的专家级知识会非常有帮助仓库中约 200 个语言定义都存放在 src/languages/ 目录下例如 src/languages/javascript.js、src/languages/python.js。如果你对其中某门语言有专家级认知审校与修复这些语法文件就是天然的切入点。功能请求先讨论归属再动手实现功能请求Feature Request永远受欢迎但项目方有一条明确的引导如果该功能不属于核心库项目乐于建议你以插件方式开发。因此在动手实现之前正确姿势是先开一个 issue讨论该功能应当进入核心还是做成插件。这样做的好处是能获得实现思路的提示可以链接到历史上关于该主题的讨论获得更多上下文避免实现方向与维护者预期不符而白费功夫。语言请求直接请求支持某语言通常没有意义这是新手最容易踩的坑。项目方的立场非常明确详见 docs/language-requests.rst核心团队通常不亲自开发新语言他们的精力集中在解析器开发、Bug 修复和现有语言的支持上也没有时间评审、合并和维护额外语言的语法。项目鼓励贡献者自己开发并维护第三方语言语法——无论这门语言多么冷门项目都乐意在 highlightjs 组织下托管或者由贡献者自己托管并提供链接。因此只提交请支持语言 Xyz的 issue 会被直接关闭并附上上述说明链接。如果你希望某门语言被支持最佳路径是自己动手编写语法或找到愿意开发的开发者。相关指引见 docs/language-guide.rst语法开发与 docs/language-contribution.rst第三方语言模块打包规范。报告问题高质量 issue 的正确打开方式发现 Bug 或想到改进点时可以打开一个新 issue 提交。项目对报告语言高亮问题给出了非常实用的建议用可复现的最小测试用例来呈现问题这样维护者与贡献者都能快速定位。一个高质量的 Bug 报告应包含清晰的标题指明受影响的语言或模块触发问题的输入代码片段当前的高亮输出错误行为期望的高亮输出正确行为可复现的最小化示例。提交 PR从 fork 到 merge 的完整工作流如果你具备 前提技能可以从带有 good first issue 标签的入门级 issue 开始也可以直接参与更复杂 issue 的讨论。对于 GitHub 协作流程不熟悉的开发者项目建议先了解通用的 fork 协作模型然后按以下步骤操作在 GitHub 上 fork 本项目克隆到本地git clone gitgithub.com:username/highlight.js.git在当前镜像仓库语境下可等效使用git clone https://gitcode.com/gh_mirrors/hi/highlight.js获取源码副本用于本地开发与测试创建工作分支git checkout -b my-branch提交改动git commit -m my changes执行构建与测试推送分支git push origin my-branch从你的 fork 向本仓库打开 Pull Request。开 PR 前的Keep in Mind清单项目方给出了三条重要的代码纪律先开 issue 再写代码请在你提交 PR 之前先开一个新 issue或加入已有 issue 的讨论让主题先被探索和讨论。这是对双方时间的尊重——你的时间宝贵维护者的更宝贵。通常应附带 markup 测试当你做了显著的语法改动或修复 Bug 时应当添加对应的 markup 测试唯一例外是仅添加keywords这类纯关键字清单的改动。改动最小化只改需要改的部分修复小 Bug 时不要顺手重新 lint 或重写整个文件。Lint 或大规模重构必须用独立的 commit提交与功能改动分开。构建与测试体系贡献者的体检关卡highlight.js 的构建测试体系可以从 package.json 的 scripts 字段一窥全貌scripts: { mocha: mocha, lint: eslint src/*.js src/lib/*.js demo/*.js tools/**/*.js --ignore-pattern vendor, lint-languages: eslint --no-eslintrc -c .eslintrc.lang.js src/languages/**/*.js, build_and_test: npm run build npm run test, build_and_test_browser: npm run build-browser npm run test-browser, build: node ./tools/build.js -t node, build-cdn: node ./tools/build.js -t cdn, build-browser: node ./tools/build.js -t browser :common, test: mocha test, test-markup: mocha test/markup, test-detect: mocha test/detect, test-browser: mocha test/browser, test-parser: mocha test/parser }可以看到构建与测试被明确区分为Node.js 构建和浏览器构建两条链路详见 docs/building-testing.rst。最小化验证只跑 Node.js 链路贡献 PR 时只要你的改动不涉及浏览器专属特性通常只需构建并测试 Node.js 构建即可——CI 会保证浏览器构建依然通过npm run build npm run test浏览器库需要单独构建与测试npm run build-browser npm run test-browser也可以使用组合命令一次完成npm run build_and_test与npm run build_and_test_browser对应 package.json。环境要求当前仓库 package.json 声明node: 20.0.0即需要 Node.js 20 及以上版本首次开发前需执行npm install安装依赖。对于 Debian 系系统如 Ubuntu如果 node 二进制名为nodejs可能需要创建别名或软链接指向node因为测试依赖中引用了 node。构建工具与常用参数构建工具位于 tools/build.js它基于commander解析命令行参数见 tools/build.js支持的构建目标为all、browser、cdn、node四种默认browser。核心用法# 仅用常用语言构建浏览器版本 node tools/build.js :common # 为 Node.js 构建包含全部语言的版本 node tools/build.js -t node # 调试用仅构建 python 和 ruby 两个语言且不做压缩 node tools/build.js -n python ruby # 构建全部目标cdn/browser/node输出到 build/ 下各自子目录 node tools/build.js -t all常用选项说明-t, --target name指定构建目标all | browser | cdn | node-n, --no-minify禁用压缩调试语言语法时尤其有用便于阅读浏览器报错信息--no-esm禁用 ESM 构建language...位置参数指定要打包的语言名或语言类别如:common不指定则按目标默认包含全部语言。各目标的行为差异源码注释见 tools/build.js目标产物与用途browser默认目标。将核心与全部语言打包为highlight.js默认同时生成压缩版除非传入--no-minifycdn打包为highlight.min.js并把全部语言与样式拆分为独立文件供 cdnjs、jsdelivr 等 CDN 使用此目标忽略--no-minifynode转换为 CommonJS 模块生成供 Node.js 或 browserify 导入的index.js默认包含全部语言可能偏重可通过指定语言列表瘦身这也是发布到 npm 的构建all构建全部目标各自输出到build/下以目标命名的子目录所有构建结果都会输出到build/目录。测试矩阵五类测试各管一摊测试统一使用 Mocha入口见 test/index.jsnpm test会按顺序加载以下测试套件test/api/针对hljs对象暴露的 API 进行测试例如highlight、getLanguage、registerAlias、数字与二进制数字解析、beginKeywords等test/parser/核心解析引擎的回归测试覆盖beginEndScope、reuseEndsWithParent、compiler-extensions、命名分组反向引用、最大关键字命中数等历史 Bug 修复场景test/detect/语言自动检测highlightAuto的测试test/markup/各语言 HTML 渲染标记测试防止已修复的高亮错误复发test/regex/正则的致命问题检查如指数级回溯 backtrackingtest/special/仅在浏览器场景生效的测试借助jsdom在 Node 中模拟浏览器检查已有自定义标记、禁用高亮的代码块等行为。这也是 docs/building-testing.rst 中必要时还要单独跑npm run test-markup、npm run test-detect、npm run test-parser的实践来源。可视化调试tools/developer.html开发语言定义时最高效的调试方式是可视化调试。你需要先用目标语言单独构建不压缩然后打开开发者工具页tools/developer.html需先执行npm run build-browser生成浏览器构建在其中将测试片段粘贴到编辑区在 Language 下拉框中显式选择你的语言自动检测在此场景下往往不可靠点击 Update highlighting 查看渲染结果并可切换主题、切换 Show/hide structure 查看标记结构。该工具还支持 visible-structure 视图用带data-klass属性的 span 直观展示每个 token 的类别。测试片段应当短小精悍能体现该语言的整体观感即可不必覆盖每一种语法元素甚至不必具有实际语义。自动化验证detect 与 markup 测试当你对可视化结果满意后需要确保你的语法定义不会破坏整个语言套件的自动检测将调试用的片段保存到test/detect/language/default.txt如 test/detect 下各语言子目录所示用全部语言构建 Node 版本并运行测试套件如果检测被破坏需要通过改进**相关性评分relevance**来修复——这是文档中特别提到的black art一门玄学拿不准时应回到讨论组求助。对于隔离的语法构造测试例如某语言有 19 种字符串字面量或需要复杂启发式区分除法/与正则/.../应提供 markup 测试。一个 markup 测试用例由一对文件组成test/markup/language/test_name.txt测试代码test/markup/language/test_name.expect.txt期望渲染结果。仓库中现成的例子例如 test/markup/c/atomic-types.txt 与对应的atomic-types.expect.txt。期望渲染结果可通过tools/developer.html生成显式选择语言后渲染将输出保存为.expect.txt。对于尚未支持或作为未来工作跟踪的边缘情况测试套件不允许携带失败的测试。正确做法是使用.skip后缀提交这对文件test/markup/language/test_name.skip.txttest/markup/language/test_name.skip.expect.txt这些用例会被 Mocha 注册为跳过skipped的测试它们出现在报告中但不会使 CI 失败。这比直接省略该用例更好因为缺口保持可见添加 skip 用例时应在 PR 中链接跟踪 issue或在附近注释说明。用 Docker 构建与预览可选如果你不想在宿主机安装依赖可以使用仓库根目录的 Dockerfile 构建一个容器docker build -t highlight-js . docker run -d --name highlight-js --rm -p 80:80 highlight-js然后打开http://127.0.0.1/tools/developer.html即可预览开发者页面端口可通过-p 80:8080等映射方式调整也可以不绑定端口直接交互式进入容器作为开发环境。进阶用法是绑定源码目录并热更新docker run -d --name highlight-js --volume $PWD/src:/var/www/html/src --rm -p 80:80 highlight-js docker exec highlight-js node tools/build.js :common改完代码后在容器内重新构建、刷新页面即可看到效果完成后用docker stop highlight-js清理容器。完整的构建与测试细节可参考 docs/building-testing.rst。AI 辅助贡献政策工具是工具作者是你随着 AI 编程工具普及项目方在 docs/ai-contributions.md 中明确了完整的 AI 辅助贡献政策态度可以概括为欢迎使用但你必须仍然是作者。CONTRIBUTING.md 中的核心要求是提交前务必自行审查理解你的改动不要把未经检查的机器输出直接丢给维护者。政策的关键条款包括人在回路Human in the loop在请求维护者评审前必须阅读并审查工具产出的全部内容不得提交未经检查的机器生成的 PR、issue 或评审意见。你拥有这项改动你必须足够理解所提交的内容能够在评审中解释并回答问题如果你无法为某一行代码辩护就不要提交它。拒绝垃圾输出No slop未经验证、低质量、批量流水线式输出会浪费稀缺的维护者评审时间不是可接受的贡献。优先做小而聚焦、评审价值大于评审成本的改动。与任何 PR 同等的标准测试、风格、范围以及常规贡献指南仍然适用工具不会降低门槛。鼓励透明声明如果贡献在很大程度上借助了工具建议在 PR 描述或 commit trailer 中说明例如Assisted-by: model (effort)例如Assisted-by: Claude Sonnet 4 (high)、Assisted-by: Copilot未知时只写工具名也可以。明确不允许的行为包括未经人工逐个批准就自动开/更新 PR 或 issue 的无人值守机器人用 AI 端到端代劳完成 good first issue 而不学习代码库——这些 issue 存在的意义就是让人成长完全自动化就失去了意义。此外贡献者需自行确保有权在项目许可BSD-3-Clause见 LICENSE下贡献相关材料用工具重新生成受版权保护的材料并不会使其可自由再授权。维护者处理违规时按梯度执行先请求修改附简短说明与政策链接若 PR 明显偏离轨道则关闭同一账号二次明显违规则升级到仓库管理员限制其继续开 PR 的能力。结语从阅读这份指南到提交第一个 PR综合来看参与 highlight.js 的路径清晰而务实先理解核心保持小巧、边缘交给插件的哲学再按规范提出功能或语言请求用最小化且带测试的改动提交 PR并遵守 AI 辅助贡献的透明与责任要求。对于语言语法贡献者本指南与 docs/language-guide.rst、docs/language-contribution.rst 构成了从入门到打包发布的完整链路对于核心引擎贡献者docs/mode-reference.rst 与 src/lib/ 下的解析器源码如 src/lib/mode_compiler.js、src/lib/compile_keywords.js则值得进一步研读。无论选择哪条路一句建议贯穿始终改动前先讨论改动后先自测提交前先自审。【免费下载链接】highlight.jsJavaScript syntax highlighter with language auto-detection and zero dependencies.项目地址: https://gitcode.com/gh_mirrors/hi/highlight.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考