- IoT
- 机器人
- 嵌入式
【免费下载链接】johnny-five
JavaScript Robotics and IoT programming framework, developed at Bocoup.
导读
CONTRIBUTING.md 是 Johnny-Five(JavaScript 机器人与物联网编程框架)官方维护的贡献规范文档。本文以此文档为核心,系统拆解贡献者应遵循的完整工作流——包括如何报告 Issue、请求新功能与新硬件支持、提交 Pull Request、编写单元测试、维护文档示例,并结合仓库中真实的 Gruntfile.js、package.json、test/common/bootstrap.js 与 tpl/programs.json 等源码佐证,帮助你在动手之前理解项目方"代码必须通过测试与规范校验、硬件功能必须附带文档"的硬性验收标准,从而一次通过审查。
Johnny-Five 是一个开源、基于 Firmata 协议的物联网与机器人编程框架,支持 Arduino(全系列)、Intel Edison、Raspberry Pi、Particle/Spark、Tessel 2 等大量平台(详见 README.md)。它由 Nodebots 社区维护,代码质量门槛较高:所有贡献代码必须通过 lint、代码风格检查与单元测试,涉及新硬件的功能还要求附带接线图与可运行示例。下面按贡献路径逐一展开。
贡献途径总览
根据 CONTRIBUTING.md 的 "Guideline Contents",任何人均可通过以下七种途径参与:
- 报告 Issue(Reporting an Issue)
- 请求新功能(Requesting Features)
- 请求新硬件支持(Hardware Support)
- 提交 Pull Request(Submitting Pull Requests)
- 编写测试(Writing Tests)
- 编写文档(Writing Documentation)
- 提交示例项目(Sample Projects)
报告 Issue:信息完备是排查硬件问题的前提
硬件项目的 bug 排查极度依赖现场信息。文档要求报告者在提交 Issue 前先在仓库的 Issue 中搜索确认该问题是否已被报告过;若已存在但你有新的排查线索,则在原线程中以评论方式补充以下同样格式的信息。
新建 Issue 时必须包含的字段如下:
| 字段 | 说明与示例 |
|---|---|
| Board | 开发板型号,如 Arduino Uno、Intel Edison 等 |
| Shield | 若使用了扩展板,注明类型 |
| Hardware you are having an issue with | 出问题的硬件及其品牌/型号,例如 servo、led、sensor |
| Version of Johnny-Five | Johnny-Five 版本号 |
| What your expectations are | 你期望的行为 |
| What the actual outcome is | 实际发生的行为 |
| Steps to reproduce (including code samples) | 复现步骤,必须附带代码示例 |
此外,文档特别建议:如果可能,附上一段演示视频(可上传至任意支持视频托管的平台),这在实际调试硬件问题时往往极为有效。
从仓库实现看,Issue 模板要求"附带代码示例"是有充分理由的——Johnny-Five 的程序必须先等board触发ready事件才能操作引脚(见 eg/board.js 中board.on("ready", ...)的写法)。大量所谓"硬件不工作"的 Issue 实际是初始化时序或引脚编号问题,一份可复现的最小代码能让维护者快速定位是硬件、固件还是库本身的问题。
请求功能与硬件支持
请求新功能
若希望为现有类(class)增加功能,创建一个 Issue 并说明:
- What feature you'd like to see:希望看到的功能
- Why this is important to you:为什么这对你很重要(了解社区成员正在做什么有趣的事,也便于其他成员在功能未实现前给出 work-around 建议)
请求新硬件支持
社区维护者可能并不拥有你手中的新硬件,因此请求支持时必须:
- 创建 Issue;
- 附带该硬件的规格说明书链接与购买渠道;
- 若你已拥有该产品,通常会被建议由你自己协助实现支持。
仓库中可观察到硬件支持的实际形态:每个硬件控制器都有对应的lib/实现与test/测试(例如 test/led.js、test/accelerometer.js),并在 tpl/programs.json 中登记对应示例条目,docs/下则有按硬件型号命名的文档(如 docs/led-PCA9685.md)。这说明"硬件支持"不是一句承诺,而是一整套可运行的代码、测试与文档交付物。
提交 Pull Request:代码、测试、文档三者缺一不可
分支与准备流程
- 将项目 fork 到自己的 GitHub 账号,在独立分支中完成工作;
- 提交 PR 前,将 master 变基(rebase)进你的分支,确保包含最新改动、不产生冲突;
- 使用 grunt 进行lint 与测试;
- 将提交squash 压缩到合理数量后再提交。
代码风格规范
所有贡献代码必须遵循Idiomatic.js Style Guide,并保持与现有代码一致的风格。仓库中的实际规范配置可从以下文件确认:
- .jshintrc:启用
esversion: 9、强制curly、eqeqeq、双引号quotmark: "double"、检测未使用变量unused: true等; - .jscsrc:配合
grunt-jscs使用的代码风格规则。
硬性验收标准
文档强调两条不可妥协的红线:
- 贡献代码必须附带单元测试:测试在缺少该功能代码时失败、加入实现后通过;
- 提交 PR 前必须运行
grunt jsbeautifier修复语法格式问题。
从 Gruntfile.js 可以确认默认任务链:
grunt.registerTask("default", ["jshint", "jscs", "nodeunit"]);即一次grunt会依次执行 JSHint 语法检查、JSCS 风格检查与 nodeunit 单元测试,任何一环失败即视为整体失败。devDependencies 中对应配置了grunt-contrib-jshint、grunt-jscs、grunt-jsbeautifier、grunt-contrib-nodeunit、sinon、mock-firmata等(见 package.json)。
新硬件功能的文档要求
当贡献的是支持新硬件的新功能时,PR 必须包含:
- Fritzing 接线图(面包板接线图)
eg/目录中的带注释示例脚本- wiki 中的 API 文档
文档明确指出:未附带文档的代码 PR 将不被接受("Pull requests with undocumented code will not be accepted")。仓库中docs/breadboard/下有大量.png+.fzz成对出现的接线图资源,即为该要求的落地产物。
常用开发命令速查
结合 Gruntfile.js 与 package.json,贡献者常用命令如下:
| 命令 | 作用 |
|---|---|
grunt/npm test | 默认任务:jshint + jscs + nodeunit 全套检查 |
grunt jsbeautifier | 修复代码格式问题 |
grunt qc | 仅运行 JSHint 与 JSCS 检查(可指定文件,如grunt qc:eg/led.js) |
grunt nodeunit:file:<file.ext> | 运行指定测试文件 |
grunt examples | 由eg/示例重新生成docs/对应文档并更新 README |
grunt example:<file-name> | 在eg/下生成一个新的示例程序骨架 |
grunt test-examples | 运行 examples 任务并检查docs/是否有未提交改动 |
grunt watch | 监听文件变更并自动运行默认任务 |
编写测试:nodeunit + sinon + mock-firmata 的组合
测试框架与技术栈
文档明确说明测试使用nodeunit与sinon编写。仓库 test/common/bootstrap.js 展示了完整的测试引导方式:
- 引入全局
EventEmitter、Collection、Emitter、Withinable、five(即 lib/johnny-five.js)等; - 引入第三方库
color-convert、serialport、firmata、temporal; - 引入测试依赖
mock-firmata(global.mocks、global.MockFirmata、global.MockSerialPort),使测试无需真实硬件即可在模拟 Firmata 设备上运行; - 通过
newBoard()辅助函数创建Board实例并触发connect/ready事件。
以 test/led.js 为例,可见典型测试结构:setUp中创建newBoard()、建立 sinon sandbox、用 fake timers 与 spy 拦截digitalWrite/pinMode调用,再断言 Led 的原型方法与实例属性(on、off、toggle、blink、id、pin、value等)是否符合预期。这正是文档所要求的"缺少实现则测试失败、实现存在则测试通过"的验证思路。
extended 测试目录的特殊地位
文档特别指出:涉及时间要素的测试(例如动画 animation、音调/歌曲 tone/song)在部分硬件上可能不稳定,容易导致 Travis CI 构建失败,这类测试应放入test/extended目录。
仓库中 test/extended/README.md 对此做了印证:该目录下的测试"存在长时间运行或在慢速硬件上失败的风险,不随默认测试命令运行"。而 Gruntfile.js 提供了独立任务:
grunt.registerTask("nodeunit:extended", () => { grunt.config("nodeunit.tests", [ "test/extended/animation.js", "test/extended/led.js", "test/extended/piezo.js", "test/extended/servo.js", ]); grunt.task.run("nodeunit"); });test/extended/目前包含 animation.js、led.js、piezo.js、servo.js 四个文件。需要运行完整测试(含扩展测试)时使用grunt nodeunit:extended。另外,默认的nodeunit任务会先加载test/common/bootstrap.js再加载test/*.js下的全部测试(见 Gruntfile.js)。
仅想写测试练手?
如果你对项目还不太熟悉,可以关注 Issue 中带Tests标签的任务,专挑写测试来加深对项目的理解。
编写文档:docs 与 eg 的自动生成联动机制
文档维护是 Johnny-Five 贡献体系中自动化程度最高的一环,理解其机制可避免大量无效劳动:
- 示例的唯一事实来源是
eg/目录:eg/中的每个示例文件都是用户可直接node eg/<file>运行的完整脚本; docs/下的文档由eg/自动生成:修改eg/中的示例后,运行grunt examples,会依据 tpl/programs.json 的条目自动重写docs/<name>.md与 README 中的示例索引;- 提交时二者必须一起提交:Gruntfile.js 中的
grunt test-examples任务专门检查——若docs/有未提交的生成改动,构建会直接失败,提示 "The generated examples don't match the committed examples. Please ensure you've run 'grunt examples' before committing."; - 新增文档需登记:若新增了一个文档/示例文件,必须将其加入
tpl/programs.json,否则不会出现在生成流程中。
@markdown注释块:示例内嵌文档
grunt examples的生成逻辑还支持一种"注释即文档"的写法。看 eg/led.js:
led.blink(); }); /* @markdown This script will make `led` available in the REPL, by default on pin 13. Now you can try, e.g.: ```js >> led.stop() // to stop blinking then >> led.off() // to shut it off (stop doesn't mean "off") then >> led.on() // to turn on, but not blink@markdown */
从 [Gruntfile.js](https://link.gitcode.com/i/34d2401c68527b6592c8d1bd0ca9b9d7#L264-L284) 的实现可以看到:生成文档时,`@markdown` 标记之间的注释行会被提取出来作为 markdown 正文,而脚本本体中的 `../lib/` 与 `.js` 后缀会被替换(模拟 npm 安装后的 `require("johnny-five")` 写法)。也就是说,**为示例写文档只需在脚本注释里写清楚,运行 `grunt examples` 即可产出正式文档**。 ### 文档写作的受众原则 文档应包含**经过测试且可运行的示例代码**、Fritzing 接线图、照片与视频(适用时)。由于 Johnny-Five 的许多用户是第一次接触硬件编程,文档写作应以**初学者**为目标受众,措辞和步骤要足够平易。 ## 示例项目:让作品被更多人看到 如果你用 Johnny-Five 做出了有趣的作品,欢迎让社区知晓——项目希望建立一个优秀项目目录,帮助那些正在做类似项目的开发者寻找灵感、帮助与代码。可通过文档中提及的渠道(例如 Issue 或社区讨论区)提交你的作品信息。 ## 附:本地开发环境速览 仓库根目录下还提供了若干配套资源,贡献时可作为参考: - [lib/johnny-five.js](https://link.gitcode.com/i/bd03e1eadef1903adac1033ca2aed3e2):框架主入口(`package.json` 的 `main` 字段); - [lib/](https://link.gitcode.com/i/ec20a832a658252258839edcb8700667):各模块实现,如 [lib/led/](https://link.gitcode.com/i/a67b91e9b2c002685d6b51447c123d1f)、[lib/mixins/](https://link.gitcode.com/i/629f987bc0f1911b461eaf355498b228)、[lib/board.js](https://link.gitcode.com/i/9def10235e370aacc8744c47a6344cd4) 等; - [docs/](https://link.gitcode.com/i/39b1f5cb08ef040bda93d0f660dfbd1f):按硬件/功能主题组织的文档,与 `eg/` 示例一一对应; - [firmwares/](https://link.gitcode.com/i/115c535b5dfcb5267cee9911dcef6329):部分硬件(如 I2C 背板)所需的 Arduino 固件(`.ino`); - [assets/](https://link.gitcode.com/i/fe841e3dd52271760e6baf6269f42280):Logo 与示例动图等素材; - [appveyor.yml](https://link.gitcode.com/i/cda7ccd2ceb6e36dd0509bb9bcebd12f) 与 [package.json](https://link.gitcode.com/i/ad8612be921249b1a8606b91fd259967) 中的 CI 配置:展示自动化检查的范围。 > 提醒:Johnny-Five 与 Node REPL 不兼容——直接 `node` 进入交互式 REPL 运行会崩溃(见 [README.md](https://link.gitcode.com/i/9d3afadd33ec36e38f89401640c5beed) 的说明)。请将脚本写入文件后执行,board 实例自身会创建其上下文 REPL。 ## 小结:一次合规贡献的检查清单 结合本文全部内容,向 Johnny-Five 提交代码前请逐项自检: 1. 已 rebase 到最新 master,无冲突; 2. `grunt`(jshint + jscs + nodeunit)全部通过,代码风格符合 Idiomatic.js; 3. 已运行 `grunt jsbeautifier`; 4. 新增/修改的功能有配套单元测试,且测试在无实现时失败、有实现时通过; 5. 涉及时间要素的测试放入 [test/extended/](https://link.gitcode.com/i/5a098d567a3cba0215e19f42987a2217); 6. 新硬件功能附带 Fritzing 接线图、`eg/` 带注释示例、API 文档; 7. 修改示例后运行 `grunt examples` 重新生成 `docs/`,并将二者一起提交,新文件已在 [tpl/programs.json](https://link.gitcode.com/i/207fb3cb37f7f20a837212fa7acbfe21) 登记; 8. 提交已 squash 为合理数量。 遵循这套流程,你的贡献就能顺畅通过 CI 与维护者审查,真正帮助到全球的 NodeBots 开发者。- IoT
- 机器人
- 嵌入式
【免费下载链接】johnny-five
JavaScript Robotics and IoT programming framework, developed at Bocoup.
相关推荐
kotlinx.coroutines 贡献指南:从 Issue 提交到 PR 合入的完整工作流
kotlinx.coroutines 贡献指南:从 Issue 提交到 PR 合入的完整工作流 本篇指南面向希望在 kotlinx.coroutines 仓库中
异步编程并发编程FreshRSS 贡献指南:从提 Issue 到提交 PR 的 GitHub 开发工作流
FreshRSS 贡献指南:从提 Issue 到提交 PR 的 GitHub 开发工作流 本文面向希望参与 FreshRSS 开发的贡献者,完整讲解官方推荐的问
后端前端CLITrianglify开源贡献者指南:从提交issue到PR的完整流程
Trianglify开源贡献者指南:从提交issue到PR的完整流程 你是否在使用Trianglify时遇到过bug却不知如何反馈?或者有了新功能想法却不知从何
图形学
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考