vConsole核心源码学习

2024-06-14 17:28
文章标签 源码 学习 核心 vconsole

本文主要是介绍vConsole核心源码学习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

      • 概述
      • 核心类 `VConsole`
        • 1. 导入模块和定义常量
        • 2. 类的定义和构造函数
        • 3. 添加内置插件
        • 4. 初始化 Svelte 组件
        • 5. 自动运行
        • 6. 添加和移除插件
        • 7. 显示和隐藏面板
      • 总结


vConsole 核心类的实现,该工具由腾讯开发,用于在移动端进行调试。代码主要涉及 vConsole 的初始化、插件管理、事件触发和销毁等功能。以下是对代码的详细解析:

概述

  • vConsole 是一个用于移动端的调试工具。
  • 提供日志、网络、系统信息、元素查看和存储等调试功能。
  • 使用 Svelte 作为前端框架来构建调试面板。

核心类 VConsole

1. 导入模块和定义常量
import type { SvelteComponent } from 'svelte';
import type { VConsoleOptions } from './options.interface';
import * as tool from '../lib/tool';
import $ from '../lib/query';
import { default as CoreCompClass } from './core.svelte';
import type { IVConsoleTopbarOptions, IVConsolePluginEventName } from '../lib/plugin';
import { VConsolePlugin } from '../lib/plugin';
import { VConsoleLogPlugin } from '../log/log';
import { VConsoleDefaultPlugin } from '../log/default';
import { VConsoleSystemPlugin } from '../log/system';
import { VConsoleNetworkPlugin } from '../network/network';
import { VConsoleElementPlugin } from '../element/element';
import { VConsoleStoragePlugin } from '../storage/storage';
import { VConsoleLogExporter } from '../log/log.exporter';
import { VConsoleNetworkExporter } from '../network/network.exporter';const VCONSOLE_ID = '#__vconsole';
  • 导入必要的模块和类型。
  • 定义常量 VCONSOLE_ID,用于标识 vConsole 的 DOM 元素。
2. 类的定义和构造函数
export class VConsole {public version: string = __VERSION__;public isInited: boolean = false;public option: VConsoleOptions = {};protected compInstance: SvelteComponent;protected pluginList: { [id: string]: VConsolePlugin } = {}; // plugin instance// Export plugin methodspublic log: VConsoleLogExporter;public system: VConsoleLogExporter;public network: VConsoleNetworkExporter;// Export static classespublic static VConsolePlugin: typeof VConsolePlugin;public static VConsoleLogPlugin: typeof VConsoleLogPlugin;public static VConsoleDefaultPlugin: typeof VConsoleDefaultPlugin;public static VConsoleSystemPlugin: typeof VConsoleSystemPlugin;public static VConsoleNetworkPlugin: typeof VConsoleNetworkPlugin;public static VConsoleElementPlugin: typeof VConsoleElementPlugin;public static VConsoleStoragePlugin: typeof VConsoleStoragePlugin;constructor(opt?: VConsoleOptions) {if (!!VConsole.instance && VConsole.instance instanceof VConsole) {console.debug('[vConsole] vConsole is already exists.');return VConsole.instance;}VConsole.instance = this;this.isInited = false;this.option = {defaultPlugins: ['system', 'network', 'element', 'storage'],log: {},network: {},storage: {},};// merge optionsif (tool.isObject(opt)) {for (let key in opt) {this.option[key] = opt[key];}}// check deprecated optionsif (typeof this.option.maxLogNumber !== 'undefined') {this.option.log.maxLogNumber = this.option.maxLogNumber;console.debug('[vConsole] Deprecated option: `maxLogNumber`, use `log.maxLogNumber` instead.');}if (typeof this.option.onClearLog !== 'undefined') {console.debug('[vConsole] Deprecated option: `onClearLog`.');}if (typeof this.option.maxNetworkNumber !== 'undefined') {this.option.network.maxNetworkNumber = this.option.maxNetworkNumber;console.debug('[vConsole] Deprecated option: `maxNetworkNumber`, use `network.maxNetworkNumber` instead.');}// add built-in pluginsthis._addBuiltInPlugins();// try to initconst _onload = () => {if (this.isInited) {return;}this._initComponent();this._autoRun();};if (document !== undefined) {if (document.readyState === 'loading') {$.bind(<any>window, 'DOMContentLoaded', _onload);} else {_onload();}} else {// if document does not exist, wait for itlet _timer;const _pollingDocument = () => {if (!!document && document.readyState == 'complete') {_timer && clearTimeout(_timer);_onload();} else {_timer = setTimeout(_pollingDocument, 1);}};_timer = setTimeout(_pollingDocument, 1);}}
  • 定义 VConsole 类,并在构造函数中进行初始化。
  • 检查是否已有实例存在,如果有则返回现有实例。
  • 初始化选项并合并用户传入的选项。
  • 检查并处理已弃用的选项。
  • 添加内置插件。
  • 尝试初始化组件,等待文档加载完成后进行初始化。
3. 添加内置插件
/*** Add built-in plugins.*/
private _addBuiltInPlugins() {// add default log pluginthis.addPlugin(new VConsoleDefaultPlugin('default', 'Log'));// add other built-in plugins according to user's configconst list = this.option.defaultPlugins;const plugins = {'system': { proto: VConsoleSystemPlugin, name: 'System' },};if (__TARGET__ === 'web') {plugins['network'] = { proto: VConsoleNetworkPlugin, name: 'Network' };plugins['element'] = { proto: VConsoleElementPlugin, name: 'Element' };plugins['storage'] = { proto: VConsoleStoragePlugin, name: 'Storage' };}if (!!list && tool.isArray(list)) {for (let i = 0; i < list.length; i++) {const pluginConf = plugins[list[i]];if (!!pluginConf) {this.addPlugin(new pluginConf.proto(list[i], pluginConf.name));} else {console.debug('[vConsole] Unrecognized default plugin ID:', list[i]);}}}
}
  • 根据用户配置添加内置插件。
  • 支持日志、系统、网络、元素查看和存储等插件。
4. 初始化 Svelte 组件
/*** Init svelte component.*/
private _initComponent() {if (! $.one(VCONSOLE_ID)) {const switchX = <any>tool.getStorage('switch_x') * 1;const switchY = <any>tool.getStorage('switch_y') * 1;let target: HTMLElement;if (typeof this.option.target === 'string') {target = document.querySelector(this.option.target);} else if (this.option.target instanceof HTMLElement) {target = this.option.target;}if (! (target instanceof HTMLElement)) {target = document.documentElement;}this.compInstance = new CoreCompClass({target,props: {switchButtonPosition: {x: switchX,y: switchY,},},});// bind eventsthis.compInstance.$on('show', (e) => {if (e.detail.show) {this.show();} else {this.hide();}});this.compInstance.$on('changePanel', (e) => {const pluginId = e.detail.pluginId;this.showPlugin(pluginId);});}// set options into componentthis._updateComponentByOptions();
}
  • 初始化 Svelte 组件并绑定事件。
  • 设置开关按钮的位置并绑定显示和切换面板事件。
5. 自动运行
/*** Auto run after initialization.* @private*/
private _autoRun() {this.isInited = true;// init pluginsfor (let id in this.pluginList) {this._initPlugin(this.pluginList[id]);}// show first pluginthis._showFirstPluginWhenEmpty();this.triggerEvent('ready');
}
  • 初始化所有插件。
  • 如果没有激活的插件,显示第一个插件。
  • 触发 ready 事件。
6. 添加和移除插件
/*** Add a new plugin.*/
public addPlugin(plugin: VConsolePlugin) {// ignore this plugin if it has already been installedif (this.pluginList[plugin.id] !== undefined) {console.debug('[vConsole] Plugin `' + plugin.id + '` has already been added.');return false;}this.pluginList[plugin.id] = plugin;// init plugin only if vConsole is readyif (this.isInited) {this._initPlugin(plugin);// if it's the only plugin, show it by defaultthis._showFirstPluginWhenEmpty();}return true;
}/*** Remove a plugin.*/
public removePlugin(pluginID: string) {pluginID = (pluginID + '').toLowerCase();const plugin = this.pluginList[pluginID];// skipif is has not been installedif (plugin === undefined) {console.debug('[vConsole] Plugin `' + pluginID + '` does not exist.');return false;}// trigger `remove` event before uninstallplugin.trigger('remove');try {delete this.pluginList[pluginID];delete this.compInstance.pluginList[pluginID];} catch (e) {this.pluginList[pluginID] = undefined;this.compInstance.pluginList[pluginID] = undefined;}this.compInstance.pluginList = this.compInstance.pluginList;// show the first plugin by defaultif (this.compInstance.activedPluginId == pluginID) {this.compInstance.activedPluginId = '';this._showFirstPluginWhenEmpty();}return true;
}
  • addPlugin 方法用于添加新插件,初始化插件并在需要时显示第一个插件。
  • removePlugin 方法用于移除插件,并在需要时显示第一个插件。
7. 显示和隐藏面板
/*** Show console panel.*/
public show() {if (!this.isInited) {return;}this.compInstance.show = true;this._triggerPluginsEvent('showConsole');
}/*** Hide console panel.*/
public hide() {if (!this.isInited) {return;}this.compInstance.show = false;this._triggerPluginsEvent('hideConsole');
}/*** Show switch button*/
public showSwitch() {if (!this.isInited) {return;}this.compInstance.showSwitchButton = true;
}/*** Hide switch button.*/
public hideSwitch() {if (!this.isInited) {return;}this.compInstance.showSwitchButton = false;
}/*** Show a plugin panel.*/
public showPlugin(pluginId: string) {if (!this.isInited) {return;}if (!this.pluginList[pluginId]) {console.debug('[vConsole] Plugin `' + pluginId + '` does not exist.');}// trigger plugin eventthis.compInstance.activedPluginId && this._triggerPluginEvent(this.compInstance.activedPluginId, 'hide');this.compInstance.activedPluginId = pluginId;this._triggerPluginEvent(this.compInstance.activedPluginId, 'show');
}
  • showhide 方法用于显示和隐藏调试面板。
  • showSwitchhideSwitch 方法用于显示和隐藏开关按钮。
  • showPlugin 方法用于显示指定插件的面板。

总结

vConsole 是一个功能强大的移动端调试工具,通过插件机制提供了日志、网络、系统信息、元素查看和存储等功能。核心类 VConsole 负责初始化、插件管理、事件触发和销毁等操作,使用 Svelte 组件来构建调试面板,并提供了一系列方法来管理插件和显示调试信息。

这篇关于vConsole核心源码学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1061044

相关文章

Python列表去重的4种核心方法与实战指南详解

《Python列表去重的4种核心方法与实战指南详解》在Python开发中,处理列表数据时经常需要去除重复元素,本文将详细介绍4种最实用的列表去重方法,有需要的小伙伴可以根据自己的需要进行选择... 目录方法1:集合(set)去重法(最快速)方法2:顺序遍历法(保持顺序)方法3:副本删除法(原地修改)方法4:

SpringQuartz定时任务核心组件JobDetail与Trigger配置

《SpringQuartz定时任务核心组件JobDetail与Trigger配置》Spring框架与Quartz调度器的集成提供了强大而灵活的定时任务解决方案,本文主要介绍了SpringQuartz定... 目录引言一、Spring Quartz基础架构1.1 核心组件概述1.2 Spring集成优势二、J

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

Linux find 命令完全指南及核心用法

《Linuxfind命令完全指南及核心用法》find是Linux系统最强大的文件搜索工具,支持嵌套遍历、条件筛选、执行动作,下面给大家介绍Linuxfind命令完全指南,感兴趣的朋友一起看看吧... 目录一、基础搜索模式1. 按文件名搜索(精确/模糊匹配)2. 排除指定目录/文件二、根据文件类型筛选三、时间

Spring 中 BeanFactoryPostProcessor 的作用和示例源码分析

《Spring中BeanFactoryPostProcessor的作用和示例源码分析》Spring的BeanFactoryPostProcessor是容器初始化的扩展接口,允许在Bean实例化前... 目录一、概览1. 核心定位2. 核心功能详解3. 关键特性二、Spring 内置的 BeanFactory

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步