如何为 p5.js 新方法添加参数校验的友好错误消息?
【免费下载链接】p5.jsp5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Processing. Looking for p5.js 2.0? http://beta.p5js.org项目地址: https://gitcode.com/GitHub_Trending/p5/p5.js
当你在 p5.js 源码仓库中新增一个需要特定数量、特定类型参数的方法时,如果用户传参错误,控制台只会抛出普通的 JavaScript 错误。p5.js 的友好错误系统(Friendly Error System,FES,🌸)可以让这类错误变成带文件行号、带参考链接、可读性更高的提示,例如:
🌸 p5.js says: [sketch.js, line 9] circle() was expecting at least 3 arguments, but received only 1.本文面向 p5.js 的贡献者,介绍如何为自带参数要求的新方法添加 FES 参数校验,并通过仓库自带的空示例完成测试验证。操作依据是 how-to-add-friendly-error-messages.md 中的 “Adding parameter validation using FES” 章节和 friendly_error_system.md。
一个关键前提:FES 只存在于非压缩构建中。压缩版p5.min.js只保留了国际化的基础框架,不包含实际的翻译与 FES 实现,因此所有测试都必须使用构建产物lib/p5.js,而不是lib/p5.min.js。
FES 如何生成参数校验消息
理解消息来源,才能判断哪些步骤必须做。FES 的所有消息内容都通过基于 i18next 的translator()函数动态生成(英文也不例外),translator()按检测到的浏览器语言环境从translations/{{locale}}/translation.json中读取文本并拼装成最终消息,语言标识可以带地区信息(如es-PE),代码位置见 src/friendly_errors/fes_core.js。
参数校验消息使用翻译文件中内置的键值,无需为新方法新增翻译条目。例如 translations/en/translation.json 中的内置条目:
"type_TOO_FEW_ARGUMENTS": "{{location}} {{func}}() was expecting at least {{minParams}} arguments, but received only {{argCount}}.", "type_TOO_MANY_ARGUMENTS": "{{location}} {{func}}() was expecting no more than {{maxParams}} arguments, but received {{argCount}}.", "type_WRONG_TYPE": "{{location}} {{func}}() was expecting {{formatType}} for the {{position}} parameter, received {{argType}} instead."{{...}}是 i18next 的插值占位符,由 FES 在运行时填入实际的参数信息。消息会随浏览器语言环境本地化:同样的参数错误,在浏览器语言为ko-KR时展示为韩文消息。
第一步:补全方法的行内文档参数列表
FES 依据方法的行内文档(inline documentation)中的参数列表来校验实参,所以这一步是校验生效的基础。行内文档的写法见 contributing_to_the_p5js_reference.md。
以circle()为例,其行内文档以方法描述开头,接着是完整的@param参数列表,然后是示例代码:
/** * Draws a circle on the canvas. A circle is a round shape. Every point on the * edge of a circle is the same distance from its center. By default, the first * two parameters set the location of the center of the circle. The third * parameter sets the shape's width and height (diameter). The origin may be * changed with the <a href="#/p5/ellipseMode">ellipseMode()</a> function. * * @method circle * @param {Number} x x-coordinate of the center of the circle. * @param {Number} y y-coordinate of the center of the circle. * @param {Number} d diameter of the circle. * @chainable * @example * <div> * <code> * circle(30, 30, 20); * describe('A white circle with black outline in the middle of a gray canvas.'); * </code> * </div> * */其中 FES 用来做校验的部分是:
* @method circle * @param {Number} x x-coordinate of the center of the circle. * @param {Number} y y-coordinate of the center of the circle. * @param {Number} d diameter of the circle.确认你的新方法拥有同样完整的@method/@param列表(包括每个参数的类型,如{Number})后再进入下一步。
第二步:在方法实现中调用p5._validateParameters()
回到新方法的实现代码,按p5._validateParameters('[方法名]', arguments);的格式调用校验函数:
p5._validateParameters('circle', arguments);这行调用通常放在方法内部的第一行——在所有其他逻辑执行之前。这样当实参不符合预期时,方法不会继续往下执行。circle()的实现即采用这种写法(见 src/shape/2d_primitives.js):
p5.prototype.circle = function () { p5._validateParameters('circle', arguments); const args = Array.prototype.slice.call(arguments, 0, 2); // ... 其余实现省略 ... };将'circle'替换为你的方法名即可。
第三步:重新构建并用空示例测试三类参数错误
1. 重新构建 p5.js
在仓库根目录执行:
npm run build该脚本对应 package.json 中定义的"build": "rolldown -c",会在lib/下生成构建产物。
2. 切换到非压缩版脚本
打开 lib/empty-example/index.html,将其中的
<script src="../p5.min.js"></script>替换为
<script src="../p5.js"></script>lib/p5.min.js不支持 FES 消息,这一步不能省略。
3. 在示例脚本中写入典型错误用例
编辑 lib/empty-example/sketch.js,针对新方法测试三类典型参数错误:缺少参数、参数数量错误(过多)、参数类型错误。文档中针对circle()的示例如下:
// Missing arguments circle(100); // Wrong number of arguments (more than required) // Notice this code still successfully draws a circle. circle(100, 100, 100, 1000); // Wrong type(s) of argument(s) circle(100, 100, 'hello');用支持本地运行的方式打开lib/empty-example/index.html,检查浏览器 JavaScript 控制台。文档示例的期望输出(消息末尾原本附带方法参考页链接,此处略去):
🌸 p5.js says: [sketch.js, line 9] circle() was expecting at least 3 arguments, but received only 1. 🌸 p5.js says: [sketch.js, line 14] circle() was expecting no more than 3 arguments, but received 4. 🌸 p5.js says: [sketch.js, line 12] circle() was expecting Number for the third parameter, received string instead.这是文档给出的示例结果,消息中的sketch.js, line N指向你在sketch.js中写下对应调用的行号,实际行号以你的文件为准。控制台出现这三条带 🌸 前缀的消息,即说明参数校验已按预期工作。
(可选)为校验消息添加单元测试
how-to 文档 建议为新消息补充单元测试,以便尽早发现回归问题。文档给出的示例:
suite('validateParameters: multi-format', function() { test('color(): optional parameter, incorrect type', function() { assert.validationError(function() { p5._validateParameters('color', [0, 0, 0, 'A']); }); }); });其中assert.validationError是仓库自定义的断言,定义在 test/js/chai_helpers.js:当p5.ValidationError存在时断言fn抛出p5.ValidationError,否则断言不抛出意外异常。测试的完整写法参考 unit_testing.md,运行方式为npm test(对应 package.json 中的"test": "vitest")。
限制与注意事项
- 只在非压缩构建中生效:
p5.min.js不包含 FES 的翻译与实现,向用户演示或排查 FES 消息时必须使用lib/p5.js。 - 消息内容来自内置翻译键:参数校验的三类消息(参数过少、参数过多、类型错误)复用
translations/{{locale}}/translation.json中已有的条目,添加校验本身不需要改动翻译文件;翻译文件的结构与 i18next 格式说明见 friendly_error_system.md。 - FES 可被全局关闭:用户或宿主代码将
p5.disableFriendlyErrors设为true后 FES 会被禁用,这属于用户侧行为,不影响你在源码中的实现。 - 校验依据是行内文档:如果后续修改了方法的参数列表,行内文档中的
@param需要同步更新,否则 FES 的校验预期会与真实实现脱节。
完成以上步骤后,你的新方法在实参数量或类型不符合行内文档声明时,会在控制台输出带行号与参考链接的友好错误消息,这就是本次扩展的完成状态。
【免费下载链接】p5.jsp5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Processing. Looking for p5.js 2.0? http://beta.p5js.org项目地址: https://gitcode.com/GitHub_Trending/p5/p5.js
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考