ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

vConsole 内置插件公共属性与方法完全指南:log / system / network 面板 API 源码级详解

vConsole 内置插件公共属性与方法完全指南:log / system / network 面板 API 源码级详解 vConsole 内置插件公共属性与方法完全指南log / system / network 面板 API 源码级详解【免费下载链接】vConsoleA lightweight, extendable front-end developer tool for mobile web page.项目地址: https://gitcode.com/gh_mirrors/vc/vConsole导读vConsole 作为一款轻量、可扩展的移动端 Web 调试面板其内置插件会对外暴露一组公共方法供业务代码在运行时向 Log / System / Network 面板写入或清空数据。本篇以官方文档《Builtin Plugin: Properties Methods》为骨架结合仓库源码逐一拆解vConsole.log、vConsole.system、vConsole.network的完整 API 签名、参数含义、返回值与底层实现帮助你正确、安全地在业务代码中调用这些方法。1. 公共方法从哪里来插件 Exporter 机制在 vConsole 中vConsole.log、vConsole.system、vConsole.network并不是随意挂在实例上的属性而是**内置插件导出器Exporter**的实例。每个内置插件在初始化时会通过bindExporter()将自己的 exporter 挂载到vConsole实例上插件 id 为default即 Log 面板时挂载为vConsole.log其他插件以其 id 命名例如vConsole.network、vConsole.system、vConsole.storage、vConsole.element。对应源码位于 src/lib/plugin.ts#L123-L136protected bindExporter() { if (!this._vConsole || !this.exporter) { return; } const id this.id default ? log : this.id; this._vConsole[id] this.exporter; } protected unbindExporter() { const id this.id default ? log : this.id; if (this._vConsole this._vConsole[id]) { this._vConsole[id] undefined; } }1.1 关键前提插件未被加载时方法为undefined由于 exporter 是随插件实例一起挂载的如果某个内置插件没有被添加到 vConsole 中对应属性将是undefined此时直接调用其方法会抛错。官方文档给出了明确的示例vConsole new VConsole({ defaultPlugins: [system] }); // network 插件未加载 vConsole.network.clear(); // Error: network is undefined从 src/core/core.ts 的_addBuiltInPlugins()逻辑可以看到defaultPlugins配置决定了哪些内置插件会被实例化并挂载。因此使用vConsole.network.xxx()前必须确认初始化配置中包含network默认配置包含使用vConsole.storage.xxx()前需确认defaultPlugins中包含storage。建议在使用前做存在性判断例如if (vConsole.network) { vConsole.network.add({ ... }); }1.2 移除插件后方法会被置回undefinedremovePlugin()会触发插件的remove事件src/core/core.ts#L422-L446插件基类的onRemove()会调用unbindExporter()将vConsole[pluginId]置为undefined。这意味着插件的动态移除也会同步摘除对应的公共方法调用前需要格外留意运行时机。2. Log 面板 APIvConsole.log2.1vConsole.log.log()/info()/debug()/warn()/error()Log 面板提供与console系列一一对应的五个方法vConsole.log.log(...) vConsole.log.info(...) vConsole.log.debug(...) vConsole.log.warn(...) vConsole.log.error(...)与console.log()的关键区别通过vConsole.log.xxx()输出的日志只进入 vConsole 的 Log 面板不会输出到浏览器原生 console。这一点可以从源码得到印证VConsoleLogExporter直接调用model.addLog()而addLog()内部在默认情况下noOrig为false会额外调用callOriginalConsole()将日志转发到原生 consolesrc/log/log.model.ts#L290-L323。但 exporter 的方法走的是纯 vConsole 通道因此行为与文档描述一致——只会出现在 vConsole 面板中。从源码看addLog()会经过以下链路src/log/log.model.tsgetLogDatasWithFormatting()对参数做格式化支持对象、数组、字符串等类型的展示_signalLog()将日志推入队列通过requestAnimationFrame批量刷新节流避免高频调用阻塞 UI_flushLogs()将日志分发到对应插件的 store 并渲染_limitLogListLength()按maxLogNumber默认 1000截断列表超出部分自动丢弃src/log/log.model.ts#L450-L467。因此vConsole.log.xxx()也适用于高频日志场景vConsole 内部已经做了节流与上限保护。2.2vConsole.log.clear()清空 Log 面板的所有日志行为类似console.clear()。项目说明参数无返回值void底层实现为model.clearPluginLog(default)先清空尚未刷新的 logQueue 中属于该插件的日志再将 store 中的logList置空src/log/log.model.ts#L269-L285。3. System 面板 APIvConsole.system3.1vConsole.system.log()/info()/debug()/warn()/error()与vConsole.log.xxx()完全一致的行为区别仅在于日志输出到 System 面板vConsole.system.info(device info); vConsole.system.warn(deprecated api);System 面板本质上继承自 Log 面板源码中VConsoleSystemPlugin extends VConsoleLogPluginsrc/log/system.ts#L3因此它天然拥有 Log 插件的全部方法与行为只是以system为 id 独立挂载。另外可以留意System 面板在onReady()时会自动调用printSystemInfo()src/log/system.ts#L10-L106输出 UA、客户端Android / iOS / WeChat、网络类型、性能耗时navigation / dns / tcp / request / response / domComplete / loadEvent等系统信息——这些内容正是通过console.info([system], ...)进入 System 面板的。理解了这套机制你也可以用vConsole.system.xxx()输出自定义的系统级诊断信息。3.2vConsole.system.clear()清空 System 面板的所有日志。项目说明参数无返回值void底层与vConsole.log.clear()相同调用model.clearPluginLog(system)。4. Network 面板 APIvConsole.networkNetwork 面板的公共 API 最为丰富支持手动添加自定义请求、更新请求状态与清空记录。其实现位于 src/network/network.exporter.ts。4.1vConsole.network.add(item)向 Network 面板添加一条自定义请求记录vConsole.network.add(item: VConsoleNetworkRequestItem): VConsoleNetworkRequestItemProxy参数item: VConsoleNetworkRequestItem自定义请求对象完整结构如下interface VConsoleNetworkRequestItem { // HTTP method method: | GET | POST | PUT | DELETE | HEAD | CONNECT | OPTIONS | TRACE | PATCH; // Full URL, E.g: https://www.abc.com/foo?ab url: string; // HTTP status code, E.g: 200 status: number | string; // XMLHttpRequest.readyState readyState?: XMLHttpRequest[readyState]; // Response header, key-value pairs header: { [key: string]: string }; // XMLHttpRequest.responseType responseType?: XMLHttpRequest[responseType]; // xhr: XMLHttpRequest, custom: custom request requestType: xhr | fetch | ping | custom; // Correspond XMLHttpRequest.setRequestHeader() or fetchs headers requestHeader?: HeadersInit; // The body of response response: any; // Timestamp startTime: number; // Timestamp endTime: number; // Query string parameters, key-value pairs or JSON string getData?: { [key: string]: string } | null; // Request payload, key-value pairs or JSON string postData?: { [key: string]: string } | string | null; }返回值VConsoleNetworkRequestItemProxy调用add()后返回一个新对象其内容继承自传入的item并增改部分属性interface VConsoleNetworkRequestItemProxy extends VConsoleNetworkRequestItem { // The internal id of the request id: string; // If possible, response will be parsed to JSON string, otherwise original value response: string | any; // endTime - startTime costTime?: number; }源码级细节src/network/network.exporter.ts#L8-L17public add(item: VConsoleNetworkRequestItem) { const itemProxy new VConsoleNetworkRequestItemProxy(new VConsoleNetworkRequestItem()); for (let key in item) { itemProxy[key] item[key]; } itemProxy.startTime itemProxy.startTime || Date.now(); itemProxy.requestType itemProxy.requestType || custom; this.model.updateRequest(itemProxy.id, itemProxy); return itemProxy; }可以确认三点id是自动生成的内部唯一 id由VConsoleNetworkRequestItemProxy构造时生成后续update()需要用它来定位请求startTime缺省时自动补为当前时间戳Date.now()requestType缺省时自动设为custom新增请求会进入VConsoleNetworkModel.updateRequest()src/network/network.model.ts#L66-L89该函数还会对 URL 做ignoreUrlRegExp过滤并通过limitListLength()按maxNetworkNumber默认 1000控制列表长度。4.2vConsole.network.update(id, item)更新一条自定义请求vConsole.network.update(id: string, item: VConsoleNetworkRequestItem | VConsoleNetworkRequestItemProxy)参数id: string自定义请求的内部 id可通过vConsole.network.add()的返回值获取item: VConsoleNetworkRequestItem | VConsoleNetworkRequestItemProxy新的自定义请求对象。返回值void⚠️ 重要注意官方文档明确强调直接修改VConsoleNetworkRequestItemProxy.response的属性值不会生效若要更新response内容必须重新赋值整个对象。原因在于add()时response已被序列化处理若可能会尝试转成 JSON 字符串见 src/network/requestItem.ts 中的VConsoleNetworkRequestItemProxy定义此时item.response.foo xxx只是修改了一个已脱钩的值无法触发 store 更新。正确做法是整体替换const item vConsole.network.add({ response: { foo: bar }, ... // 其他请求字段 }); item.response.foo newbar; // 不生效response 不会有变化 item.response { foo: newbar }; // 有效 vConsole.network.update(item.id, item);从源码看update()最终调用model.updateRequest(id, item)src/network/network.model.ts#L66-L89。updateRequest()会按 id 查找已有记录若存在则逐 key 覆盖并强制重新赋值确保 store 响应式更新同时每条更新都会重新执行ignoreUrlRegExp过滤——即被过滤的 URL 请求不会进入面板。4.3vConsole.network.clear()清空 Network 面板的所有请求记录vConsole.network.clear()项目说明参数无返回值void底层实现为model.clearLog()直接将请求列表 store 重置为空对象src/network/network.model.ts#L58-L61。5. 实战示例完整模拟一条自定义请求结合以上 API一个典型的手动上报一条耗时请求的完整流程如下// 1. 添加请求获得 proxy 对象与内部 id const req vConsole.network.add({ method: POST, url: https://www.abc.com/api/login, status: 200, requestType: custom, header: { Content-Type: application/json }, requestHeader: { X-Token: abc123 }, getData: { from: h5 }, postData: { username: tester }, response: { code: 0, msg: ok }, startTime: Date.now() - 200, endTime: Date.now(), }); // 2. 中途更新如状态从 pending 变为 200 vConsole.network.update(req.id, { ...req, status: 200, response: { code: 0, msg: ok }, // 整体重新赋值 response }); // 3. 清空面板 vConsole.network.clear();6. 这些方法在底层与内置拦截的关系理解内置公共 API 的价值需要看清 Network / Log 插件的完整工作方式Network 面板除了vConsole.network.add()手动添加外插件在初始化时通过多个 Proxy 自动接管全局请求能力src/network/network.model.ts#L95-L159包括XMLHttpRequestsrc/network/xhr.proxy.ts、fetchsrc/network/fetch.proxy.ts、navigator.sendBeaconsrc/network/beacon.proxy.ts、资源加载src/network/resource.proxy.ts与WebSocketsrc/network/websocket.proxy.ts。所有被拦截的请求最终都走同一个updateRequest()通道。手动add()与自动拦截是同一套数据模型因此自定义请求可以与其他真实请求统一展示、排序与统计。Log 面板插件的mockConsole()会钩住window.console的 log/info/warn/debug/error/time/group/clear 等方法src/log/log.model.ts#L109-L137将原生 console 调用重定向进 vConsole 面板而vConsole.log.xxx()则是一个只进面板、不回写原生 console的独立入口。System 面板作为 Log 插件的子类src/log/system.ts除了继承全部日志能力外还会在就绪时自动输出系统环境与性能信息。若需扩展自定义插件并暴露类似vConsole.myPlugin.xxx()的公共方法可参考 插件构建指南 与 插件生命周期事件通过自定义VConsolePlugin并在插件内绑定 exporter 实现机制与本篇内置插件完全一致。7. 小结与最佳实践API作用关键注意点vConsole.log.log/info/debug/warn/error()向 Log 面板输出日志仅进 vConsole 面板不回写原生 consolevConsole.log.clear()清空 Log 面板无参数返回voidvConsole.system.log/info/debug/warn/error()向 System 面板输出日志与 Log 面板行为一致vConsole.system.clear()清空 System 面板无参数返回voidvConsole.network.add(item)添加自定义请求返回带id的 Proxy 对象vConsole.network.update(id, item)更新自定义请求更新response需整体重新赋值vConsole.network.clear()清空 Network 面板无参数返回void实践要点调用前判空插件未加载或已被移除时vConsole.log / system / network均为undefined建议先做存在性检查善用返回的idadd()返回的 Proxy 对象中id是后续update()的唯一凭证务必保存更新response时整体替换不要修改item.response.xxx属性应重新赋值整个response对象再调用update()合理利用默认值add()时startTime与requestType可省略源码会自动补Date.now()与custom数量上限Log 与 Network 面板默认最多保留 1000 条记录maxLogNumber/maxNetworkNumber可通过 options.interface.ts 中的log.maxLogNumber、network.maxNetworkNumber配置超出后自动淘汰无需担心面板被刷爆。【免费下载链接】vConsoleA lightweight, extendable front-end developer tool for mobile web page.项目地址: https://gitcode.com/gh_mirrors/vc/vConsole创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表