资讯动态

Marked 贡献开发指南:从源码结构、测试体系到 NPM 脚本的全流程解析

发布时间:2026/9/19 22:38:34 来源:尧图企业网站定制
前端【免费下载链接】markedA markdown parser and compiler. Built for speed.项目地址https://gitcode.com/gh_mirrors/ma/marked点击查看免费下载导读本文以 Marked 官方贡献指南docs/CONTRIBUTING.md为核心系统讲解向这个以速度著称的 Markdown 解析器提交代码的完整工作流包括仓库源码目录的职责划分、基于 SOLID 的设计原则、五级优先级标签体系、五大测试规格目录与 front-matter 配置技巧以及全部 NPM 脚本的真实执行链路。读完本文你将能够独立完成一次从 Fork、改码、测试到提交 Pull Request 的高质量贡献并理解 Marked 内部测试引擎与构建管道的运作原理。一、贡献前的准备仓库结构与「为什么只改 src 不碰 lib」Marked 的贡献流程详见 docs/CONTRIBUTING.md要求贡献者按以下步骤操作Forkmarkedjs/marked到自己的账号下使用 GitHub Desktop 或命令行将仓库克隆到本地确保当前处于master分支运行npm install或npm update安装依赖创建一个独立的功能分支在src文件夹中更新代码lib文件夹是自动编译生成的代码禁止手工修改运行npm test修复所有问题对于 lint 问题可运行npm run lint让 linter 自动修复运行npm run build:reset清除对编译产物的改动提交 Pull Request。其中第 6 步是理解整个仓库的关键。从 package.json 的脚本定义可以看到build:reset: rimraf ./lib ./public, build:esbuild: node esbuild.config.js, build:types: tsc dts-bundle-generator --export-referenced-types --project tsconfig.json -o lib/marked.d.ts src/marked.ts,而 esbuild.config.js 明确写着lib下的产物全部由./src/生成构建横幅banner甚至直接声明了 DO NOT EDIT THIS FILE / The code in this file is generated from files in ./src/。因此贡献者只需专注于 src 目录lib目录esm、umd 与 d.ts 类型声明会在构建时由 src/marked.ts 统一产出。npm run build:reset之所以出现在提交前的工作流中正是为了避免把构建产物中的无关 diff 带进 Pull Request。二、设计原则SOLID 在 Marked 源码中的落地贡献指南指出Marked 倾向于遵循 SOLID 软件设计原则尤其是其中的单一职责原则Single Responsibility与开闭原则Open/Closed单一职责Marked 以及它的各个组成部分唯一的职责就是把 Markdown 字符串转换成 HTML开闭Marked 更倾向于让开发者能够轻松地扩展库及其组件而不是通过不断堆叠配置项来改变行为。这两条原则可以从 src 目录的模块划分中直观印证模块文件职责Lexer.ts词法分析将 Markdown 源文本切分为 token 流并持有全部编译规则Lexer.rulesTokenizer.ts具体的 token 匹配逻辑按块级/行内规则逐一识别Parser.ts语法解析将 token 流渲染为 HTML 字符串Renderer.ts各 token 类型的 HTML 输出实现是自定义渲染的首选扩展点TextRenderer.ts纯文本无 HTML 标签输出用于摘要等场景Hooks.ts钩子机制允许在不改动解析核心的前提下介入处理流程MarkedOptions.ts选项类型定义与解析defaults.ts默认配置项rules.ts正则规则的定义来源marked.ts入口与 API 封装聚合以上模块这种「解析器 / 渲染器 / 扩展点」分离的架构正是开闭原则的体现新增语法能力时优先通过扩展如自定义 Renderer、Hooks实现而不是在核心里塞入更多开关配置。贡献者在修改时也应遵循同样的取向尽量让改动落在可扩展的边界内。三、优先级标签体系Issue 与 PR 的「工作量排序表」贡献指南认为优先级已经为「构建质量」做好了排序并用一组票证类型标签Ticket type label来标注 Issue 或 PR 的工作性质按优先级从高到低排列票证类型标签描述L0 - security在 Marked 库中发现安全漏洞L1 - broken合法用法得到与支持规范相比不正确的输出或导致 marked 崩溃且该问题没有已知的绕过方案L2 - annoying与 L1broken类似但该问题存在已知的绕过方案RR - refactor and re-engineer能够给 Marked 的开发者更好的可读性或最终用户更快的性能或两者带来改进NFS - new feature (spec related)Marked 目前不具备、但属于所支持规范之内的能力NFU - new feature (user requested)Marked 目前不具备、但用户已经提出需求的能力NFE - new feature (should be an extension)Marked 目前不具备、且不属于任何规范的能力应作为扩展实现这套标签直接指导贡献者判断自己提交的内容属于哪个等级、应该如何被对待。例如修复一个会崩溃的解析问题应标注 L1而引入规范之外的全新语法则应标记为 NFE因为它更适合做成扩展而非并入核心。四、测试体系Test early, often, and everything贡献指南强调项目会为「验证输出」依据支持规范编写测试和「最小化回归」为已修复的 issue 编写测试两种目的编写用例。因此了解测试装置test harness是参与贡献的前提。五大测试规格目录如下位置描述test/specs/commonmark针对 CommonMark 规范的合规性测试test/specs/gfm针对 GFMGitHub Flavored Markdown规范的合规性测试test/specs/new与原始markdown.pl无关的测试test/specs/original对照原始markdown.pl的验证测试test/specs/redos针对 ReDoS正则表达式拒绝服务漏洞的测试这五个目录的运行逻辑可以在 test/run-spec-tests.js 中找到源码级印证测试引擎从这五个目录批量读取用例getTests并对不同目录施加不同的默认选项——CommonMark 目录使用{ gfm: false, pedantic: false }GFM 目录使用{ gfm: true, pedantic: false }original 目录使用{ gfm: false, pedantic: true }而 redos 目录使用{ silent: false }。也就是说同一个 Markdown 用例在不同的规格目录下会按该目录对应的方言选项被解析。每个.md测试用例文件如foo.md都对应一个同名的.html期望输出文件如foo.html。如果你的测试需要指定选项——比如假设gfm被设置为false——可以在.md文件顶部添加 front-matterYAML 头来覆盖选项例如--- gfm: false ---仓库中已有大量真实用例采用这种写法例如 test/specs/new/nogfm_hashtag.md 同时声明了gfm: false与pedantic: true以测试在非 GFM、pedantic 模式下#header是否被当作标题test/specs/new/breaks.md 则声明breaks: true与gfm: true来验证换行行为。front-matter 中的键名直接对应 Marked 的选项如gfm、pedantic、breaks等运行时会被解析进 Marked 实例的配置中。对于 redos 目录除常规的.md/.html配对用例外还存在以.cjs结尾的动态用例见 test/specs/redos例如 quadratic_underscores.cjs 以module.exports导出一个包含 101 个下划线字符的markdown输入及其期望html输出用于在自动化检查中探测正则表达式的二次方/指数级回溯风险。此外package.json 中还有专门的test:redos脚本node test/recheck.ts vuln.js配合 recheck 依赖对规则进行 ReDoS 静态扫描。五、提交 PR 与 Issue模板与检查清单Marked 为 Pull Request 和 Issue 都提供了提交模板。当你开始新建 PR 或 Issue 时会看到使用模板的指引说明。PR 模板中同时包含提交者与审查者两套检查清单在大多数情况下这两者并不是同一个人——提交者负责确认代码质量、测试与文档审查者负责从维护者的视角复核正确性与合入条件。请务必逐项勾选并如实回答这能显著加快审查流程。六、NPM 脚本全解每一条命令背后实际发生了什么在 NPM 命令方面Marked 尽量使用 NPM 框架自带的原生脚本。下面结合 package.json 的真实定义逐条拆解。6.1 运行测试npm testnpm test这条命令并非只跑一遍测试而是build:reset→build:docs→test:specs→test:unit→test:umd→test:cjs→test:types→test:lint的完整流水线先清空并重建文档再依次运行规格测试test/run-spec-tests.js、单元测试test/unit、UMD 产物验证test/umd-test.js、CommonJS 产物验证test/cjs-test.cjs、类型声明验证test/types与 ESLint 校验。对于日常快速验证可以使用npm run test:only仅构建后跑 specs 与 unit或用npm run test:specs:only/npm run test:unit:only单独运行某一类测试npm run test:update则用于在确认行为正确后批量更新期望输出。6.2 语法规范检查npm run test:lintnpm run test:lint用于检测你是否使用了项目标准的语法规则即 ESLint 规则集。它对应eslint命令不做自动修复而npm run lint则对应eslint --fix会自动修复可修复的格式问题——这正是贡献指南中「让 linter 帮你修复」的由来。6.3 性能对比npm run benchnpm run bench用于查看 Marked 与其他主流 Markdown 库之间的耗时对比。它在 package.json 中定义为npm run build node test/bench.js即先构建最新产物再执行 test/bench.js 基准脚本。注意运行前提是本地已安装基准对比所需的依赖如 commonmark、markdown-it 等 devDependencies。6.4 查看编译后的规则npm run rulesnpm run rules用于查看从src/rules.js编译出的全部正则规则。它的实现位于 test/rules.js从Lexer.rules读取规则对象将其中的正则toString()后按 JSON 格式打印。你也可以指定一个或多个「规则路径」来只看特定规则npm run rules -- block.gfm.item inline.pedantic.br { block: { gfm: { item: /^( *)((?:[*-]|\d{1,9}\.)) ?[^\n]*(?:\n(?!\1(?:[*-]|\d{1,9}\.) ?)[^\n]*)*/gm } }, inline: { pedantic: { br: /^( {2,}|\\)\n(?!\s*$)/ } } }点号分隔的路径对应规则对象的嵌套层级如block.gfm.item即块级规则中 GFM 方言下的列表项规则未指定的分支会被省略。该脚本对规则对象做了递归序列化并把noopTest等无意义规则过滤为null/undefined方便直观审阅某条规则的实际正则。6.5 构建产物npm run buildnpm run build用于构建你自己的 es5、esm 和 minified 版本注构建目标与配置以当前仓库为准实际产物为 esm 与 umd 两个 bundle 及类型声明。它展开为三步build:esbuildnode esbuild.config.js以 src/marked.ts 为入口产出 lib/marked.esm.js 与 lib/marked.umd.jsUMD 通过esbuild-plugin-umd-wrapper包装为全局marked、build:typestsc配合 dts-bundle-generator 生成 lib/marked.d.ts、build:man用marked-man从 man/marked.1.md 生成 man 手册。构建横幅会注入当前版本号并保留 MarkedJS 与原作者 Christopher Jeffrey 的 MIT 版权声明。七、适用前提与限制说明Node 版本根据 package.json 的engines字段本仓库要求Node 20本地开发前请先确认环境满足要求产物目录lib为构建生成目录手工修改会在npm run build:reset或重新构建时被覆盖请始终修改 src 下的 TypeScript 源码测试期望更新npm run test:update会直接改写.html期望文件仅应在确认新行为正确时使用切勿用它掩盖未修复的回归。遵循上述流程你就能以与维护者一致的节奏完成一次干净的贡献改src、跑测试、让 linter 自修、build:reset清理产物、最后提交带齐检查清单的 Pull Request。赞分享前端【免费下载链接】markedA markdown parser and compiler. Built for speed.项目地址https://gitcode.com/gh_mirrors/ma/marked点击查看免费下载相关推荐ESPectre开发者指南从代码结构到贡献流程全解析ESPectre开发者指南从代码结构到贡献流程全解析 ESPectre是一个基于Wi Fi频谱分析CSI的运动检测系统具有原生的Home Assista人工智能机器学习物联网嵌入式智能硬件边缘计算rainfrog开发指南从源码构建到贡献代码全流程rainfrog开发指南从源码构建到贡献代码全流程 作为一款轻量级终端数据库管理工具Terminal User Interface, TUIrainfr数据库CLI开发工具React/Vue项目集成指南js-file-download在前端框架中的最佳实践React/Vue项目集成指南js file download在前端框架中的最佳实践 js file download 是一款轻量级JavaScript库能创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价