资讯详情

p5.js 友好错误系统(FES)开发者参考与实现解析

📅 2026/9/13 18:32:08 | 华诺云谱 👁 阅读
p5.js 友好错误系统(FES)开发者参考与实现解析
p5.js 友好错误系统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.jsp5.js 的友好错误系统Friendly Error SystemFES是一套内置于库中的错误诊断与提示机制当用户代码出现参数不匹配、文件加载失败、变量未定义、拼写错误、保留符号被覆盖等问题时FES 会在浏览器控制台输出带有「 p5.js says」前缀的友好提示并附带指向官方参考文档的链接。本文以 FES 开发者参考与注释 为骨架结合当前仓库中src/friendly_errors/目录下的真实实现fes_core.js、param_validator.js、sketch_verifier.js、browser_errors.js、fes.js完整梳理 FES 的各个函数入口、调用链、参数约定、性能开关与已知限制帮助你理解并扩展这套错误诊断系统。FES 概览五大入口与文件布局FES 由多个函数协作完成它们从不同位置收集错误信号浏览器触发的全局错误事件、扫描用户 sketch 代码时发现的错误、库内部调用时的参数检查等。生成友好错误消息的主要入口函数有五个_validateParameters()—— 参数验证_friendlyFileLoadError()—— 文件加载错误_friendlyError()—— 通用友好错误helpForMisusedAtTopLevelCode()—— 顶层代码误用检测_fesErrorMonitor()—— 浏览器全局错误监控这五个入口的说明直接写在 fes_core.js 的文件头注释 中。需要说明的是参考注释中提到的文件名为validate_params.js、file_errors.js、sketch_reader.js而在当前仓库中对应实现分别位于src/friendly_errors/下的param_validator.js、sketch_verifier.jsfile_errors.js中描述的_friendlyFileLoadError()逻辑在当前版本已并入fes_core.js体系stacktrace.js则保留原样其中的堆栈解析代码源自 stacktrace.js 项目由fesErrorMonitor()与拼写检查逻辑调用。各文件职责划分如下文件仓库相对路径职责src/friendly_errors/fes_core.jsFES 核心功能与杂项_report、_friendlyError、fesErrorMonitor、checkForUserDefinedFunctions、helpForMisusedAtTopLevelCode、拼写距离计算等src/friendly_errors/param_validator.js_validateParameters参数验证及相关代码src/friendly_errors/sketch_verifier.js读取用户代码、提取变量/函数声明、检查与 p5.js 保留符号的冲突对应参考注释中的fesCodeReadersrc/friendly_errors/browser_errors.js浏览器错误消息查找表errorTable与入口函数列表entryPointssrc/friendly_errors/stacktrace.js错误堆栈解析代码源自 stacktrace.jssrc/friendly_errors/fes.jsFES日志类、翻译tl-util、样式化消息输出核心输出管线_report()与_friendlyError()_report(message[, func][, color])_report()是 FES 的主输出函数负责把错误助手消息直接打印到控制台。其实现位于 fes_core.js先调用mapToReference()在消息末尾拼接指向对应函数参考文档的链接load开头的函数不加链接再通过FES.log输出。在测试环境中如果设置了_fesLogger_report会调用_fesLogger而不是console.log。_report(message); _report(message, func); _report(message, func, color);参数说明param {String} message 要打印的消息 param {String} [func] 函数名称 param {Number|String} [color] CSS 颜色代码消息的统一前缀为 p5.js says:该前缀定义在 fes.js 的#printMessage中并支持通过prefix: false选项省略前缀供嵌套输出如附加堆栈使用。_friendlyError(message[, func][, color])_friendlyError()是库中任何位置都能调用的通用友好错误生成器任何 p5 函数都可以调用它以提供友好错误消息。其调用顺序为_friendlyError _report在 fes_core.js 的实现 中_friendlyError首先检查p5.disableFriendlyErrors若为true则直接返回否则调用_report打印消息。参数与_report一致param {String} message 要打印的消息 param {String} [func] 函数的名称 param {Number|String} [color] CSS颜色代码按照参考注释_friendlyError已被以下模块/函数使用fesErrorMonitor()checkForUserDefinedFunctions()handleMisspelling()processStack()文件加载错误处理sketch 代码读取_friendlyParamError()参数错误_createFriendlyGlobalFunctionBinder()core/maincore/shape/vertexmath/p5.Vector此外_friendlyError与_checkForUserDefinedFunctions在压缩构建IS_MINIFIED环境中被替换为空函数见 fes_core.js这也是p5.min.js中 FES 默认被禁用的底层原因之一。文件加载错误_friendlyFileLoadError()当loadX()系列函数在加载过程中出错时会调用_friendlyFileLoadError(errorType, filePath)。它使用键值fes.fileLoadError.*生成并打印友好错误消息除了加载失败它还会检查文件是否过大并生成警告。_friendlyFileLoadError(errorType, filePath);参数说明param {Number} errorType 文件加载错误类型的数字 param {String} filePath 引起错误的文件路径当前版本中包含针对image、XML、table、text、json和font文件的错误消息模板。在仓库中各加载函数失败分支处保留了对应的调用注释例如 src/io/files.js 中的p5._friendlyFileLoadError(5, path)、src/io/files.js 中的p5._friendlyFileLoadError(6, path)以及 src/image/loading_displaying.js 中的p5._friendlyFileLoadError(0, path)。已实现此调用的函数包括image/loading_displaying/loadImage()io/files/loadFont()io/files/loadTable()io/files/loadJSON()io/files/loadStrings()io/files/loadXML()io/files/loadBytes()调用顺序为_friendlyFileLoadError _report文件加载错误示例以下代码试图加载一个不存在的字体文件/// missing font file let myFont; function preload() { myFont loadFont(assets/OpenSans-Regular.ttf); } function setup() { fill(#ED225D); textFont(myFont); textSize(36); text(p5*js, 10, 50); } function draw() {}FES 会在控制台生成类似下面的消息附参考文档链接 p5.js says: 看起来加载字体文件时出现了问题。请检查文件路径 [assets/OpenSans-Regular.ttf] 是否正确尝试将字体文件托管到在线服务器上或者运行本地服务器。参数验证_validateParameters()validateParameters()对外暴露为_validateParameters通过将输入参数与从内联文档生成的参数数据进行匹配执行参数验证。它检查函数调用是否使用了正确数量和正确类型的参数使用键值fes.friendlyParamError.*生成并打印友好错误消息。调用方式有两种静态版本p5._validateParameters(FUNCT_NAME, ARGUMENTS)建议一般情况下使用原型版本p5.prototype._validateParameters(FUNCT_NAME, ARGUMENTS)主要用于调试和单元测试。_validateParameters(func, args);参数说明param {String} func 函数名 param {Array} args 用户输入的参数按照参考注释_validateParameters已在以下模块的函数中实现accessibility/outputs、color/creating_reading、color/setting、core/environment、core/rendering、core/shape/2d_primitives、core/shape/attributes、core/shape/curves、core/shape/vertex、core/transform、data/p5.TypedDict、dom/dom、events/acceleration、events/keyboard、image/image、image/loading_displaying、image/p5.Image、image/pixel、io/files、math/calculation、math/random、typography/attributes、typography/loading_displaying、utilities/string_functions、webgl/3d_primitives、webgl/interaction、webgl/light、webgl/loading、webgl/material、webgl/p5.Camera。当前实现基于 Zod 的 Schema 校验参考注释中描述的调用链为validateParameters buildArgTypeCache addType lookupParamDoc scoreOverload testParamTypes testParamType getOverloadErrors _friendlyParamError ValidationError report friendlyWelcome当前仓库中的 param_validator.js 已演进为基于Zodzod/mini的实现它从 docs/parameterData.json 读取每个函数的重载参数数据例如background的重载列表[p5.Color]、[String, Number?]、[Number[]]等其中?表示可选参数通过generateZodSchemasForFunc()为每个重载组合生成 Zod schema再用funcSchemas.parse(args)做校验校验失败时通过findClosestSchema()找到与输入参数最接近的 schema参数个数不匹配会被加权计分权重为 4最后交给friendlyParamError()生成人类可读的错误消息。校验流程的核心入口validate()见 param_validator.js。底层还包含两类工程细节可选参数组合展开generateOverloadCombinations()param_validator.js会把含可选参数的函数展开为必选参数个数到全部参数个数的所有合法组合从而允许func(a, b)这类省略可选参数的调用通过校验内部调用抑制p5.registerDecorator包装了所有p5.prototype方法仅在非内部调用_isUserCall标志且未禁用校验时执行validate(name, args)param_validator.jsfn._internal(callback)则用于在await之后包装库内部调用避免误报。校验中还做了特殊处理所有参数均为undefined时直接返回 All arguments for xxx() are undefined 错误如果某参数是Promise则会提示是否忘了在加载函数前加await。缺少参数的示例arc(1, 1, 10.5, 10);FES 会在控制台生成以下消息附参考文档链接 p5.js 说看起来arc()在位置#4从零开始的索引收到了一个空变量。如果不是故意的这通常是作用域问题。 p5.js 说看起来arc()在位置#5从零开始的索引收到了一个空变量。如果不是故意的这通常是作用域问题。类型不匹配的示例arc(1, 1, 10.5, 10, 0, Math.PI, pie);FES 会在控制台生成以下消息附参考文档链接 p5.js 说arc()在参数#0从零开始的索引处期望接收Number但收到了字符串。全局错误监控fesErrorMonitor()fesErrorMonitor()对外暴露为_fesErrorMonitor处理浏览器捕获的各种错误并生成全局错误消息。它的实现位于 fes_core.js通过window.addEventListener(error, fesErrorMonitor)和window.addEventListener(unhandledrejection, fesErrorMonitor)挂载fes_core.js。除了错误事件与未处理的拒绝事件也可以在catch块中手动调用try { someCode(); } catch(err) { p5._fesErrorMonitor(err); }该函数生成并打印的消息包括使用键fes.globalErrors.syntax.*、fes.globalErrors.reference.*、fes.globalErrors.type.*的友好错误消息通过processStack()生成的内部库错误消息键fes.wrongPreload、fes.libraryError通过printFriendlyStack()生成的堆栈跟踪消息键fes.globalErrors.stackTop、fes.globalErrors.stackSubseq通过handleMisspelling()生成的拼写检查消息键fes.misspelling。_fesErrorMonitor的调用顺序大致如下_fesErrorMonitor processStack printFriendlyError 如果错误类型是ReferenceError _handleMisspelling computeEditDistance _report _report printFriendlyStack 如果错误类型是SyntaxError、TypeError等 _report printFriendlyStackfesErrorMonitor(event);参数param {*} e—— 错误事件。错误分类与浏览器差异当前函数可以处理部分ReferenceError、SyntaxError和TypeError支持的错误完整列表位于 browser_errors.js 的errorTable。该表的关键设计是不同浏览器对同一错误使用不同措辞因此errorTable为每个错误类型登记了多条浏览器特定的消息模板如ReferenceError的{{}} is not defined对应 Chrome/Firefox、Cant find variable: {{}}对应 Safari模板中的{{}}匹配标识符、{{.}}匹配任意内容、{}匹配但不捕获。fesErrorMonitor按错误名查表、用正则匹配浏览器消息、提取出错的符号名再按错误类型分发处理SyntaxErrorINVALIDTOKEN非法字符、UNEXPECTEDTOKEN意外 token、REDECLAREDVARIABLE变量重复声明、MISSINGINITIALIZERconst 未初始化、BADRETURNORYIELDreturn 位置错误ReferenceErrorNOTDEFINED未定义先走拼写检查与顶层误用检查、CANNOTACCESS初始化前访问TypeErrorNOTFUNC不可作为函数调用区分对象属性与独立调用两种解释、READNULL读取 null 属性、READUDEFINED读取 undefined 属性、CONSTASSIGN对 const 重新赋值。以内部库错误为例processStack()会先判断错误是否发生在 p5 库内部isInternal若是则直接返回、交由内部错误消息分支处理fes_core.js。内部错误示例 1在 preload 中调用 backgroundfunction preload() { // 由于在preload中调用background()而引发 // 错误 background(200); }FES 会在控制台中生成类似下面的消息附参考文档链接 p5.js说当调用background时位于sketch.js的第4行在p5js库内部发生了一个错误错误消息为无法读取未定义的属性background。如果没有另外说明这可能是由于从preload中调用了background。preload函数中除了load函数loadImage、loadJSON、loadFont、loadStrings等之外不应该有其他内容。内部错误示例 2mouseClicked 参数问题function setup() { cnv createCanvas(200, 200); cnv.mouseClicked(); }FES 会在控制台中生成类似下面的消息附参考文档链接 p5.js说当调用mouseClicked时位于sketch.js的第3行在p5js库内部发生了一个错误错误消息为无法读取未定义的属性bind。如果没有另外说明这可能是由于传递给mouseClicked的参数存在问题。用户示例中的作用域错误function setup() { let b 1; } function draw() { b 1; }FES 会在控制台中生成类似下面的消息 p5.js说由于当前范围内未定义b出现了一个错误位于sketch.js的第5行。如果在代码中定义了它请检查其作用域、拼写和大小写JavaScript区分大小写。用户示例中的拼写错误function setup() { colour(1, 2, 3); }FES 会在控制台中生成类似下面的消息 p5.js说您可能错误地将colour写成了color位于sketch.js的第2行。如果希望使用p5.js中的函数请将其更正为color。拼写检测依赖computeEditDistance()Wagner–Fischer 算法计算 Levenshtein 距离见 fes_core.jshandleMisspelling()会把报错符号与所有公开的 p5 属性逐一计算编辑距离若最小距离不超过阈值EDIT_DIST_THRESHOLD 2fes_core.js且与符号名确有差异就给出纠错建议多个候选时逐行列出每个建议及其参考文档链接。代码读取与保留符号检查fesCodeReader()与 sketch_verifier参考注释中的fesCodeReader()用于检查两类情况(1) 是否在setup()和/或draw()函数之外使用了任何 p5.js 常量或函数(2) 是否重新声明了任何 p5.js 保留常量或函数。它生成fes.sketchReaderErrors.reservedConst、fes.sketchReaderErrors.reservedFunc类型的错误消息并在load事件触发时执行。工作流程为提取用户编写的代码将代码转换为代码行的数组捕获变量和函数声明检查声明的函数/变量是否为保留的 p5.js 常量或函数并进行报告重新定义 p5.js 保留常量的示例function setup() { // PI 是 p5.js 的保留常量 let PI 100; }FES 会在控制台生成以下消息附参考文档链接 p5.js 提示您使用了 p5.js 的保留变量 PI请确保将变量名更改为其他名称。重新定义 p5.js 保留函数的示例function setup() { // text 是 p5.js 的保留函数 let text 100; }FES 会在控制台生成以下消息 p5.js 提示您使用了 p5.js 的保留函数 text请确保将函数名更改为其他名称。在当前仓库中这一职责由 sketch_verifier.js 承担且实现已升级为基于 acorn 的 AST 解析不再逐行扫描extractUserDefinedVariablesAndFuncs()使用 acorn 把用户代码解析为 AST再通过acorn-walk遍历VariableDeclarator、FunctionDeclaration、ClassDeclaration节点提取变量/函数名及其行号解析器行号偏移 1用lineOffset -1修正checkForConstsAndFuncs()随后做两类检查——用户定义名是否与src/core/constants.js中的常量冲突、是否与p5.prototype上公开不以_开头的方法冲突。为避免误报ignoreFunction列表sketch_verifier.js显式排除了setup、draw、preload及全部鼠标/触摸/键盘事件回调等允许用户自定义的函数。该检查通过lifecycles.presetup钩子在p5.disableFriendlyErrors与p5.disableSketchChecker均未开启时执行sketch_verifier.js。参考注释同时提醒sketch_reader()可能在提取变量/函数名时遗漏一些情况例如所有代码写在一行时这一限制在 AST 实现下仍未完全消除。用户定义函数的大小写检查checkForUserDefinedFunctions()checkForUserDefinedFunctions()用于检查是否以错误的大小写调用了用户定义的入口函数如setup()、draw()、mouseMoved()等生成fes.checkUserDefinedFns类型的错误消息。checkForUserDefinedFunctions(context);参数说明param {*} context 当前默认上下文。 在全局模式下设置为 window在实例模式下设置为 p5 实例。示例function preLoad() { loadImage(myimage.png); }FES 会在控制台生成以下消息附参考文档链接 p5.js 提示似乎您可能误写了 preLoad应该是 preload。如果这不是您的意图请进行更正。当前实现位于 fes_core.js逻辑要点实例模式下以 p5 实例为上下文否则回退到window依据 browser_errors.js 的entryPoints即setup、draw及各事件回调名建立小写名 → 正确名映射遍历上下文属性若某属性小写后命中映射、正确拼写的属性不存在、且该属性是函数类型则提示用户可能写错了大小写该函数通过window.addEventListener(load, checkForUserDefinedFunctions)在页面加载时自动执行fes_core.js并暴露为p5._checkForUserDefinedFunctions。另外在当前 2.0 版本中如果用户定义了preload()但构建环境不支持 preloadp5.isPreloadSupported()默认返回false见 fes_core.js该函数还会打印提示建议改用setup()中的async/await或回调方式加载资源。自动播放错误与顶层代码误用_friendlyAutoplayError()_friendlyAutoplayError()是在播放媒体如视频相关错误发生时内部调用的函数最常见原因是浏览器的自动播放策略。它生成并打印fes.autoplay类型的友好错误消息。实现位于core/friendly_errors/fes_core.js。helpForMisusedAtTopLevelCode()helpForMisusedAtTopLevelCode()由fes_core.js在窗口加载时调用作为fesErrorMonitor处理ReferenceError的候选分支之一用于检查是否在setup()或draw()之外使用了 p5.js 的函数或常量生成fes.misusedTopLevel类型的错误消息。param {*} err 错误事件 param {Boolean} log false实现位于 fes_core.js。它维护一个惰性初始化的misusedAtTopLevelCode列表defineMisusedAtTopLevelCode通过Object.getOwnPropertyNames收集所有公开的 p5 符号并按名称长度降序排列从而优先报告更具体的符号例如HALF_PI而非PI检测时用正则\W?{symbol}\W在错误消息中查找符号名——由于不同浏览器对未定义错误的措辞不同如 Edge 的PI is undefined、Firefox 的ReferenceError: PI is undefined、Chrome 的Uncaught ReferenceError: PI is not defined采用这种宽松匹配命中后提示用户把该符号移入setup()函数。开发者备注让 FES 认识你的对象为参数验证准备 p5.js 对象任何将被用于参数验证的 p5.js 对象都必须在类声明中为name参数对象的名称赋值例如p5.newObject function (parameter) { this.parameter some parameter; this.name p5.newObject; };内联文档中的类型标注约定允许的参数类型包括Boolean、Number、String以及对象的name见上一条对于任何数组参数请使用Array如果需要在描述部分解释数组内元素类型如Number[]、String[]可以结合docs/parameterData.json的写法补充说明——当前参数数据以重载列表形式描述如[Number, Number, Number, Number?]表示四个参数且最后一个可选Number[]表示数字数组p5.Image表示该位置必须是p5.Image实例目前支持的类类型具有其name参数p5.Color、p5.Element、p5.Graphics、p5.Renderer、p5.Renderer2D、p5.Image、p5.Table、p5.TableRow、p5.XML、p5.Vector、p5.Font、p5.Geometry、p5.Matrix、p5.RendererGL。在 param_validator.js 中这些约定落地为 schema 生成规则原始类型走schemaMapBoolean/Number/String/Array/Integer/Function等p5.*类型通过z.instanceof(p5Constructors[className])校验构造函数列表在lifecycles.presetup阶段由loadP5Constructors()从p5对象上以大写字母开头的函数收集param_validator.js全大写常量名会被映射为z.literal(constantsMap[常量])以校验字面值A|B语法生成z.unionType[]生成z.array[...]元组语法生成z.tuple此外还支持AudioNode、HTMLCanvasElement、KeyboardEvent、MouseEvent、RegExp等 Web API 对象的instanceof校验。其他 FES 函数friendlyWelcome()直接打印到控制台默认情况下隐藏stacktrace.js包含从 stacktrace.js 借用的堆栈解析代码由fesErrorMonitor()和handleMisspelling()调用。性能问题与开关p5.disableFriendlyErrors默认情况下p5.js未压缩版启用了 FES而p5.min.js中禁用了 FES以防止 FES 函数拖慢执行。错误检查系统可能显著降低代码执行速度在某些情况下高达约 10 倍。可以在代码顶部添加一行代码来禁用 FESp5.disableFriendlyErrors true; // 禁用 FES function setup() { // 执行设置操作 } function draw() { // 执行绘图操作 }需要注意这只会禁用导致性能下降的 FES 部分例如参数检查。没有性能成本的友好错误——如文件加载失败时的描述性错误、尝试在全局空间中覆盖 p5.js 函数时的警告——会保持启用。当前仓库对开关粒度的实现更为细致从源码可以确认三处独立开关p5.disableFriendlyErrors总开关。_friendlyErrorfes_core.js、checkForUserDefinedFunctionsfes_core.js、fesErrorMonitorfes_core.js、参数校验validate()param_validator.js以及 sketch 检查sketch_verifier.js都会先检查它该属性的 JSDoc 与示例位于 src/core/main.jsp5.disableParameterValidator仅关闭参数校验装饰器param_validator.jsp5.disableSketchChecker仅关闭 sketch 代码检查sketch_verifier.js。此外p5.Vectorsrc/math/p5.Vector.js与p5.Renderer3Dsrc/core/p5.Renderer3D.js也会读取该开关来决定是否跳过部分检查p5.strands 在内部 pass 期间会临时保存并恢复p5.disableFriendlyErrors的值src/strands/p5.strands.js。已知限制假阴性仍然存在。这通常源于设计与实际使用之间的不匹配例如绘图函数最初被设计为在 2D 与 3D 设置中可互换使用const x3; // 未定义 line(0, 0, 100, 100, x3, Math.PI);以上代码会逃过 FES 检测因为line()的内联文档中存在可接受的 2D 参数模式Number、Number、Number、Number。这也意味着当前版本的 FES 不会检查诸如_renderer.isP3D等环境变量。全局变量覆盖检测的声明方式限制FES 只能检测使用const或var声明时对全局变量的覆盖如果使用let则无法检测。由于let实例化变量的方式目前无法解决这个问题。fesErrorMonitor()的适用环境参考注释指出该函数下的功能仅在 Web 编辑器或本地服务器上运行时有效详见相关 PR #4730 的讨论。sketch_reader的提取遗漏在提取用户代码中的变量/函数名时可能遗漏一些情况例如所有代码写在一行时。未来工作方向参考注释中列出了 FES 的未来改进方向可作为贡献者的切入点为 Web 编辑器重新引入颜色编码增加更多单元测试以实现全面的测试覆盖更直观、更精确的输出信息所使用的所有颜色应对色盲友好识别更多常见错误类型并纳入 FES 的概括处理例如bezierVertex()、quadraticVertex()需要初始化的对象未启动即被使用检查nf()、nfc()、nfp()、nfs()的 Number 参数是否为正数扩展全局错误捕获捕获浏览器输出到控制台的错误并与友好消息匹配。fesErrorMonitor()目前能处理部分特定错误类型支持更多类型会更有帮助改进sketch_reader的代码读取与变量/函数名提取能力例如解决所有代码写在一行时无法正确提取的问题欢迎未来的提案识别这些逃逸情况并添加单元测试扩展sketch_reader的功能例如当用户在draw()函数中声明变量时向用户发出警告以更好地帮助用户参考注释中还附有一段包装window.console方法以修改其功能的代码片段用于提供格式更佳的错误消息目前尚未实现// 这段代码片段使用新函数包装了 window.console 方法以修改其功能 // 目前尚未实现但可以使用它来提供更好格式的错误消息 const original window.console; const original_functions { log: original.log, warn: original.warn, error: original.error }[(log, warn, error)].forEach(function (func) { window.console[func] function (msg) { // 在包装函数中处理捕获的消息然后调用原始函数 original_functions[func].apply(original, arguments); }; });从内联文档生成独立的 FES 参考文档作为与主参考文档分离的独立系统将 Sketch 与控制台的函数分开以减少可能的混淆。延伸阅读FES 开发者参考与注释本文档源 及其英文原版 fes_reference_dev_notes.mdFES 实现源码src/friendly_errors/fes_core.js、src/friendly_errors/param_validator.js、src/friendly_errors/sketch_verifier.js、src/friendly_errors/browser_errors.js、src/friendly_errors/fes.js参数验证数据docs/parameterData.json友好错误系统贡献指南contributor_docs/zh-Hans/fes_contribution_guide.md、contributor_docs/zh-Hans/how-to-add-friendly-error-messages.md单元测试可参考 test/unit 目录下与 FES 相关的测试用例与 test/manual-test-examples/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),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。