ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

深入 p5.js 友好错误系统(FES):fesErrorMonitor 错误识别与保留符号重声明检测实战

深入 p5.js 友好错误系统(FES):fesErrorMonitor 错误识别与保留符号重声明检测实战 深入 p5.js 友好错误系统FESfesErrorMonitor 错误识别与保留符号重声明检测实战【免费下载链接】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 在 GSoC 2021 中针对 Friendly Error SystemFES友好错误系统的两阶段增强工作为主线详见 项目总结文档系统讲解 FES 如何将浏览器原始报错翻译为易懂的提示信息以及如何在代码运行前静态检测用户对 p5.js 保留常量/函数的重声明问题。读完本文你将掌握errorTable的匹配机制、fesErrorMonitor的完整调用链以及sketch_verifier.js即原文档所述sketch_reader.js的现行实现基于 AST 解析的重声明检测原理并能在自己的 p5.js 应用中正确启用、关闭与调试这些能力。一、FES 是什么面向初学者的错误翻译层FES 是 p5.js 内置的一项特性核心目标是支持初学者当用户写出常见错误代码时FES 会先检查常见错误模式并输出简单、易理解、带修复建议和参考链接的错误信息而不是让用户直面晦涩的浏览器原生报错。在源码层面FES 由 src/friendly_errors 目录下的多个模块协同工作fes.js定义FES类提供FES.log/FES.error/FES.warn等消息输出接口并维护多语言翻译模板fes_core.js实现fesErrorMonitor、handleMisspelling、helpForMisusedAtTopLevelCode等核心检测逻辑browser_errors.js维护浏览器错误消息与错误类型的对照数据表errorTableparam_validator.js校验 p5.js 函数的参数个数与类型sketch_verifier.js在preload前扫描用户代码检测与 p5.js 保留符号的冲突stacktrace.js解析并简化浏览器提供的调用栈index.js将上述模块统一注册进 p5 实例。GSoC 2021 的两个阶段目标正是围绕这套体系展开阶段一扩展fesErrorMonitor可识别的错误类型阶段二新增当时命名为sketch_reader.js现行代码中演进为sketch_verifier.js的保留符号重声明检测能力。二、阶段一扩展fesErrorMonitor的错误识别清单2.1fesErrorMonitor的职责与注册方式fesErrorMonitor由 GSoC 2020Akshay Padte引入其职责是捕获浏览器全局错误事件识别错误类型并以简洁形式展示错误及其细节。从源码看它通过两类全局事件完成挂载fes_core.jswindow.addEventListener(error, fesErrorMonitor, false); window.addEventListener(unhandledrejection, fesErrorMonitor, false);也就是说无论是同步代码抛出的Error/ErrorEvent还是异步 Promise 未捕获的PromiseRejectionEvent都会进入fesErrorMonitor处理管线。2.2 识别流程从浏览器报错到友好消息fesErrorMonitor的核心处理逻辑fes_core.js大致如下解析事件对象分别处理Error、ErrorEvent取e.error与PromiseRejectionEvent取e.reason简化调用栈借助stacktrace.js的processStack将堆栈简化为friendlyStack若错误来自 p5.js 库内部则直接返回只聚焦用户代码查表匹配依据error.name如SyntaxError、ReferenceError、TypeError在errorTable中取出候选列表用正则把模板中的占位符替换为捕获组后与error.message匹配生成友好消息匹配成功后按错误类型如INVALIDTOKEN、UNEXPECTEDTOKEN、REDECLAREDVARIABLE等输出带解释、修复建议和 MDN 参考链接的中文/英文提示。2.3errorTable浏览器差异的统一对照表阶段一的核心工作是扩充errorTable这张查找表browser_errors.js。该文件顶部注释说明了设计动机不同浏览器对同一个错误会给出不同措辞因此预先建立一张“错误消息 → 错误类型”的对照表可以让信息提取更干净、更稳定。表中的每条记录由三部分组成字段含义示例msg浏览器错误消息模板{{}}捕获符号名字母数字下划线{{.}}捕获任意文本{}匹配任意标识符但不捕获{{}} is not definedtype归一化后的错误类型标识NOTDEFINEDbrowser该消息适用的浏览器all/Chrome/Firefox/Safari例如ReferenceError家族ReferenceError: [ { msg: {{}} is not defined, type: NOTDEFINED, browser: all }, { msg: Cant find variable: {{}}, type: NOTDEFINED, browser: Safari }, { msg: Cannot access {{.}} before initialization, type: CANNOTACCESS, browser: Chrome }, { msg: cant access lexical declaration {{.}} before initialization, type: CANNOTACCESS, browser: Firefox } ]同一语义错误如“变量未定义”在不同浏览器措辞不同但都归一化到同一个type这正是 GSoC 2021 阶段一期间与导师反复打磨的成果保证错误信息一针见血、易于理解。2.4 阶段一新增的错误类型结合 browser_errors.js 与 fes_core.js 的实现扩展后的错误覆盖主要分为三类SyntaxError语法错误type触发场景友好提示要点INVALIDTOKEN非法/意外字符如中英文引号混用let x abc提示 JavaScript 不识别该符号需检查引号等字符UNEXPECTEDTOKEN期望某语法结构却出现其他符号如for (let i 0; i 5,; i)提示多为笔误检查行内多余/缺失符号REDECLAREDVARIABLE变量重复声明如let a 10; let a 100;提示 JavaScript 不允许重复声明变量并指出声明行MISSINGINITIALIZERconst声明未初始化如const a;解释 const 必须同时赋值BADRETURNORYIELDreturn位于函数之外多为括号缺失提示检查括号让 return 回到函数内ReferenceError引用错误type触发场景友好提示要点NOTDEFINED引用了不存在的变量先进入handleMisspelling检查是否拼错 p5.js 函数名否则提示检查作用域、拼写与大小写CANNOTACCESS在初始化前访问词法声明TDZ 问题提示变量声明顺序问题TypeError类型错误type触发场景友好提示要点NOTFUNC把非函数当函数调用如let a 10; a();提示该符号不是函数READNULL/READUDEFINED读取null/undefined的属性提示对象可能未创建成功CONSTASSIGN给const变量赋值提示常量不可重新赋值值得注意的是NOTDEFINED分支中fesErrorMonitor还会先尝试handleMisspelling(errSym, error)即拼写纠错当用户把 p5.js 的rect写成retc时FES 会给出“你是指 rect 吗”的提示这正是“检查常见错误模式”的典型体现。三、阶段二检测 p5.js 保留常量/函数的重声明3.1 问题场景用户很容易无意间覆盖 p5.js 的保留符号例如// 用户重定义了 p5.js 的 text 函数 let text function () { console.log(hello world); }; // 之后在代码里想用 p5.js 的 text() 绘制文字时将不再生效这种“静默失效”对新手极具迷惑性——代码不报错但行为完全不符合预期。阶段二正是为此新增了专门的检测功能解决“用户误重定义 p5.js 保留常量/函数”这一常见问题。3.2 从sketch_reader.js到sketch_verifier.js原文档描述的新特性文件名为sketch_reader.js在当前仓库中该功能已经演进并更名为 sketch_verifier.js以p5.registerAddon(sketchVerifier)方式注册并通过生命周期钩子lifecycles.presetup在setup()执行之前异步运行sketch_verifier.jsfunction sketchVerifier(p5, _fn, lifecycles) { lifecycles.presetup async function () { if (!p5.disableFriendlyErrors !p5.disableSketchChecker) { verifierUtils.runFES(p5); } }; }检测流程runFES由三步组成sketch_verifier.jsgetUserCode()获取用户代码extractUserDefinedVariablesAndFuncs(code)解析代码并提取用户自定义的变量与函数checkForConstsAndFuncs(definitions, p5)与 p5.js 保留符号比对发现冲突即输出友好错误。这正对应原文档中列出的核心步骤提取用户代码 → 转换为代码行数组 → 捕获变量/函数声明 → 检查是否为 p5.js 保留符号并报告。3.3 基于 acorn 的 AST 静态分析与fesErrorMonitor依赖“运行时浏览器报错”不同重声明检测是纯静态分析extractUserDefinedVariablesAndFuncssketch_verifier.js使用 acorn 将用户代码解析为 AST再用acorn-walk遍历三类节点VariableDeclaratorlet/const/var声明的变量若初始化表达式是箭头函数或函数表达式则归类为functions如let text function(){...}FunctionDeclarationfunction foo(){}形式的函数声明归类为functionsClassDeclaration类声明被视为一种特殊形式的变量声明归类为variables。每个捕获项记录name与line行号并通过lineOffset -1修正解析器普遍存在的行号偏移。解析失败时仅打印错误而不中断运行保证检测过程本身不干扰用户程序。3.4 双重检查常量冲突与全局函数冲突checkForConstsAndFuncssketch_verifier.js将变量与函数定义合并后执行两层校验检查一与 p5.js 常量冲突。遍历所有用户定义若名称出现在 src/core/constants.js 导出的常量对象中如HALF_PI、TWO_PI、RGB、CENTER等即判定为常量重声明const libDefinition constants[name]; if (libDefinition ! undefined) { const message generateFriendlyError(constant, name, line 1); FES.log${message}(); return true; }检查二与 p5.js 全局函数冲突。收集p5.prototype上所有不以_开头、且非constructor的属性作为“全局函数集合”再逐一比对用户定义sketch_verifier.jsconst globalFunctions new Set( Object.getOwnPropertyNames(p5.prototype).filter( key !key.startsWith(_) key ! constructor ) );同时维护一个ignoreFunction白名单sketch_verifier.js包含setup、draw、preload以及deviceMoved、mousePressed、keyPressed等全部事件生命周期函数——这些函数本来就允许且必须由用户定义理应豁免否则会产生大量误报。一旦发现冲突输出如下格式的友好错误消息模板定义于 fes.jsconstant HALF_PI on line 3 is being redeclared and conflicts with a p5.js constant. p5.js reference: https://p5js.org/reference/p5/HALF_PI function text on line 1 is being redeclared and conflicts with a p5.js function. p5.js reference: https://p5js.org/reference/p5/text消息中带有冲突符号名、行号、冲突类型constant/function与官方参考文档链接并用FES.log统一输出享受多语言翻译与样式格式化能力。3.5 配套的手动测试示例仓库在 test/manual-test-examples/fes/redeclare-p5-member 与 test/manual-test-examples/fes/top-level-p5-member 提供了两个典型用例redeclare-p5-member/sketch.js顶层声明let circle 10;且在setup内声明let fill blue;用于触发“p5.js 成员常量/函数被重声明”的提示top-level-p5-member/sketch.js在顶层直接调用circle(10, 10, 10);对应原文档所述的“检查用户是否在setup/draw之外使用了 p5.js 常量/函数”场景。这两个示例覆盖了阶段二设计的两个检测维度声明冲突与顶层误用。3.6 原文档中的检测步骤如何落地原文档把sketch_reader.js的能力概括为两部分与现行源码逐条对应原文档描述现行源码实现(I) 检查用户在setup/draw之外声明 p5.js 常量/函数并报告getUserCode假定用户代码是页面最后一个script元素checkForConstsAndFuncs对全部顶层定义执行常量/函数双重比对sketch_verifier.js(II) 在setup/draw内提取代码 → 转为代码行数组 → 捕获声明 → 比对保留符号并报告extractUserDefinedVariablesAndFuncs用 acorn 解析 AST 并按行号捕获全部VariableDeclarator/FunctionDeclaration/ClassDeclaration再交由checkForConstsAndFuncs比对sketch_verifier.js四、开关控制何时启用、如何关闭FES 的重声明检测受两个开关共同控制见 sketch_verifier.jsp5.disableFriendlyErrors关闭整个 FES包括fesErrorMonitor参见 fes_core.js 的短路判断p5.disableSketchChecker仅关闭本阶段的代码静态检查不影响参数校验等其余 FES 能力。两者都需要在 p5 实例化之前设置。对于追求极致性能、或已明确知晓自己代码不会触雷的生产环境可以关闭静态检查以减少preload前的解析开销对于教学与调试场景则建议保持默认开启让 FES 充当“新手引导”。五、总结通过 GSoC 2021 的两阶段工作p5.js 的 FES 能力得到了显著增强横向扩展errorTable覆盖了SyntaxError、ReferenceError、TypeError三大类、十余种细分错误并兼容 Chrome、Firefox、Safari 的不同措辞全部归一化为统一类型后输出友好提示纵向新增基于 AST 的静态检测现行sketch_verifier.js即原sketch_reader.js能在代码运行前发现用户对 p5.js 保留常量与全局函数的重声明输出带行号、类型与官方文档链接的精确提示并通过ignoreFunction白名单规避对事件生命周期函数的误报。从架构上看fesErrorMonitor走“运行时事件监听 消息查表”路线适合兜底所有未被静态检查覆盖的运行时错误sketch_verifier.js走“预设钩子 AST 静态分析”路线把最常见的声明冲突消灭在程序启动之前。两者互为补充共同构成了 p5.js 面向初学者友好、可诊断的错误处理闭环。读者如需深入了解实现细节可继续阅读 fes_core.js、browser_errors.js 与 sketch_verifier.js 的完整源码并在 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),仅供参考
返回列表