# Technical Documentation: Tencent/vConsole

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/Tencent/vConsole)

### Overview (`README.md`)

English | [简体中文](./README_CN.md)

vConsole
===

A lightweight, extendable front-end developer tool for mobile web page.

vConsole is framework-free, you can use it in Vue or React or any other framework application.

Now vConsole is the official debugging tool for WeChat Miniprograms.

---

## Features

- Logs: `console.log|info|error|...`
- Network: `XMLHttpRequest`, `Fetch`, `sendBeacon`
- Element: HTML elements tree
- Storage: `Cookies`, `LocalStorage`, `SessionStorage`
- Execute JS command manually
- Custom plugins

For details, please see the screenshots below.

---

## Release Notes

Latest version: [](https://www.npmjs.com/package/vconsole)

Detailed release notes for each version are available on [Changelog](./CHANGELOG.md).

---

## Guide

See [Tutorial](./doc/tutorial.md) for more usage details.

For installation, there are 2 primary ways of adding vConsole to a project:

#### Method 1: Using npm (Recommended)

```bash
$ npm install vconsole
```

```javascript
import VConsole from 'vconsole';

const vConsole = new VConsole();
// or init with options
const vConsole = new VConsole({ theme: 'dark' });

// call `console` methods as usual
console.log('Hello world');

// remove it when you finish debugging
vConsole.destroy();
```

#### Method 2: Using CDN in HTML:

```html
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
<script>
  // VConsole will be exported to `window.VConsole` by default.
  var vConsole = new window.VConsole();
</script>
```

Available CDN:

- https://unpkg.com/vconsole@latest/dist/vconsole.min.js
- https://cdn.jsdelivr.net/npm/vconsole@latest/dist/vconsole.min.js

---

## Preview

[http://wechatfe.github.io/vconsole/demo.html](http://wechatfe.github.io/vconsole/demo.html)



---

## Screenshots

### Overview

<details>
  <summary>Light theme</summary>


</details>

<details>
  <summary>Dark theme</summary>


</details>

### Log Panel

<details>
  <summary>Log styling</summary>


</details>

<details>
  <summary>Command line</summary>


</details>

### System Panel

<details>
  <summary>Performance info</summary>


</details>

<details>
  <summary>Output logs to different panel</summary>

```javascript
console.log('output to Log panel.')
console.log('[system]', 'output to System panel.')
```
</details>

### Network Panel

<details>
  <summary>Request details</summary>


</details>

### Element Panel

<details>
  <summary>Realtime HTML elements structure</summary>


</details>

### Storage Panel

<details>
  <summary>Add, edit, delete or copy Cookies / LocalStorage / SessionStorage</summary>


</details>

---

## Documentation

vConsole:

 - [Tutorial](./doc/tutorial.md)
 - [Public Properties & Methods](./doc/public_properties_methods.md)
 - [Builtin Plugin: Properties & Methods](./doc/plugin_properties_methods.md)

Custom Plugin:

 - [Plugin: Getting Started](./doc/plugin_getting_started.md)
 - [Plugin: Building a Plugin](./doc/plugin_building_a_plugin.md)
 - [Plugin: Event List](./doc/plugin_event_list.md)

---

## Third-party Plugins

 - [vConsole-sources](https://github.com/WechatFE/vConsole-sources)
 - [vconsole-webpack-plugin](https://github.com/diamont1001/vconsole-webpack-plugin)
 - [vconsole-stats-plugin](https://github.com/smackgg/vConsole-Stats)
 - [vconsole-vue-devtools-plugin](https://github.com/Zippowxk/vue-vconsole-devtools)
 - [vconsole-outputlog-plugin](https://github.com/sunlanda/vconsole-outputlog-plugin)
 - [vite-plugin-vconsole](https://github.com/vadxq/vite-plugin-vconsole)

---

## Feedback

QQ Group: 497430533



---

## License

[The MIT License](./LICENSE)

---

### Doc A Doc Index (`doc/a_doc_index.md`)

English | [简体中文](./a_doc_index_CN.md)

Documentation Index
==============================


## vConsole

 - [Tutorial](./tutorial.md)
 - [Public Properties & Methods](./public_properties_methods.md)
 - [Buitin Plugin: Properties & Methods](./plugin_properties_methods.md)


## Plugin

 - [Plugin: Getting Started](./plugin_getting_started.md)
 - [Plugin: Building a Plugin](./plugin_building_a_plugin.md)
 - [Plugin: Event List](./plugin_event_list.md)

---

### Doc A Doc Index CN (`doc/a_doc_index_CN.md`)

[English](./a_doc_index.md) | 简体中文

文档索引
==============================


## vConsole 本体

 - [使用教程](./tutorial_CN.md)
 - [公共属性及方法](./public_properties_methods_CN.md)
 - [内置插件：属性及方法](./plugin_properties_methods_CN.md)


## Plugin 插件

 - [插件：入门](./plugin_getting_started_CN.md)
 - [插件：编写插件](./plugin_building_a_plugin_CN.md)
 - [插件：Event 事件列表](./plugin_event_list_CN.md)

---

### Doc Plugin Building A Plugin (`doc/plugin_building_a_plugin.md`)

Plugin: Building a Plugin
==============================

3 steps to build a plugin:

- create an vConsole plugin object
- bind plugin events to this object
- add this object to vConsole


## 1. Create plugin object

Make sure you have imported vConsole, then simply `new` an instance of class `VConsolePlugin`:

```javascript
VConsole.VConsolePlugin(id, name)
```

- `id` (required) is an unique string.
- `name` (optional) is a string used for tab's display name.



Example:

```javascript
var myPlugin = new VConsole.VConsolePlugin('my_plugin', 'My Plugin');
```


## 2. Bind plugin events

While installing and running a plugin, vConsole will trigger some events to allow a plugin customizing it's functions.

use `.on()` to bind an event:

```javascript
on(eventName, callback)
```

- `eventName` (required) is a string.
- `callback` (required) is a callback function when an event is triggered.



Example:

```javascript
myPlugin.on('init', function() {
	console.log('My plugin init');
});
```

See [Event List](./plugin_event_list.md) to learn more about each event.



In this tutorial, we'd like to build a plugin with a tab and a tool button.

To add a tab, use `renderTab` event:

```javascript
myPlugin.on('renderTab', function(callback) {
	var html = '<div>Click the tool button below!</div>';
	callback(html);
});
```

`renderTab` will be triggered while a plugin is being initialized. We simply pass a HTML string to `callback`, then this HTML will be rendered as the content of a new tab, which name is `name`.

To add a tool button, use `addTool` event:

```javascript
myPlugin.on('addTool', function(callback) {
	var button = {
		name: 'Reload',
		onClick: function(event) {
			location.reload();
		}
	};
	callback([button]);
});
```

Again, `addTool` will be triggered during initialized, after `renderTab`. It's `callback` receives an `array` of tool button list. We make a button which can reload the current page.


## 3. Add to vConsole

The final step is add your new plugin to vConsole:

```javascript
vConsole.addPlugin(pluginObject)
```

`pluginObject` (required) is an `VConsolePlugin` object.

Example:

```javascript
vConsole.addPlugin(myPlugin);
```

Make sure you have finish binding all necessary events to your plugin before adding to vConsole. Some events (related to initialization) would not be trigger for second time after adding.


[Back to Index](./a_doc_index.md)

---

### Doc Plugin Building A Plugin CN (`doc/plugin_building_a_plugin_CN.md`)

插件：编写插件
==============================

3 步即可编写一个 vConsole 插件：

- 实例化 vConsole 插件
- 绑定事件到插件
- 将插件添加到 vConsole


## 1. 实例化插件

插件原型挂载在 `VConsole.VConsolePlugin` 中：

```javascript
VConsole.VConsolePlugin(id, name)
```

- `id` (必填) 字符串，插件的 id，必须保证唯一，不能与其他插件冲突。
- `name` (选填) 字符串，展示为 tab 面板的名字。

所以这一步只需将插件 `new` 出来即可：

```javascript
var myPlugin = new VConsole.VConsolePlugin('my_plugin', 'My Plugin');
```



## 2. 绑定插件事件

在初始化插件、后续运行时，vConsole 会对插件触发一些事件（event）。插件须通过这些事件来完成自定义功能。

使用 `.on()` 方法来绑定一个事件：

```javascript
on(eventName, callback)
```

- `eventName` (必填) 字符串，事件的名字。
- `callback` (必填) 回调函数，事件被触发时执行。



例子：

```javascript
myPlugin.on('init', function() {
	console.log('My plugin init');
});
```

关于每个事件的具体功效，请查阅[Event 事件列表](./plugin_event_list_CN.md)。



在本教程中，我们准备编写一个既有 tab 面板，又有 tool 按钮（位于面板底部）的插件。

添加新 tab 面板，需要绑定 `renderTab` 事件：

```javascript
myPlugin.on('renderTab', function(callback) {
	var html = '<div>Click the tool button below!</div>';
	callback(html);
});
```

插件初始化过程中，就会触发 `renderTab` 事件。在这里我们简单地回传了一个 HTML 字符串给 `callback`，然后这段 HTML 就会被选染成新 tab 面板的主体部分。这个新 tab 的名字就是刚才实例化时的 `name`。

此外，若不绑定 `renderTab`，那么 vConsole 就不会添加新 tab。



接下来要添加一个底部的 tool 按钮，需要绑定 `addTool` 事件：

```javascript
myPlugin.on('addTool', function(callback) {
	var button = {
		name: 'Reload',
		onClick: function(event) {
			location.reload();
		}
	};
	callback([button]);
});
```

同样地，`addTool` 会在插件初始化过程中触发，且在 `renderTab` 之后。回调函数 `callback` 的参数接收一个 `array` 数组，数组元素是用于配置按钮的 `object` 对象。本例中，点击这个按钮会重新加载当前网页。



## 3. 添加到 vConsole

最后一步，就是将写好的插件添加到 vConsole 中：

```javascript
vConsole.addPlugin(pluginObject)
```

`pluginObject` (必填) 必须为 `VConsolePlugin` 实例化的对象。

例子：

```javascript
vConsole.addPlugin(myPlugin);
```

在添加到 vConsole 之前，请确保已经绑定完所有需要用到的事件。一些初始化相关的事件只会在插件被添加时触发一次，并不会在其他时机被触发。


[返回索引](./a_doc_index_CN.md)

---

### Doc Plugin Event List (`doc/plugin_event_list.md`)

Plugin: Event List
==============================

All events are optional. But some features (like adding tool buttons) are depended on specific events.

Each event has a callback function, which will be called when event is triggered.

## init
Trigger before starting to initialize a plugin. You can configure plugin's properties in this event. This event will only be trigger once.
Note that plugin's DOM is not ready now.

##### Callback Arguments:
- none

##### Example:
```javascript
myPlugin.on('init', function() {
	// do something to init plugin
	this.list = []; // `this` == `myPlugin`
});
```


## renderTab
Trigger while vConsole trying to create a new tab for a plugin. This event will only be triggered once.
After binding this event, vConsole will get HTML from your callback to render a tab. A new tab will definitely be added if you bind this event, no matter what tab's HTML you set. Do not bind this event if you don't want to add a new tab.

##### Callback Arguments:
- (required) function(html, options): a callback function that receives the content HTML of the new tab. `html` can be a HTML `string` or an `HTMLElement` object (Or object which supports `appendTo()` method, like JQuery object), and an optional `object` for tab options.

A tab option is an object with properties:

Property |         |         |        |
------- | ------- | ------- | -------
fixedHeight | boolean | optional | Whether the height of tab is fixed to 100%.

##### Example:

```javascript
myPlugin.on('renderTab', function(callback) {
	var html = '<div>Hello</div>';
	callback(html);
});
```


## addTopBar
Trigger while vConsole trying to add new tab buttons which are under the tab bar. This event will only be triggered once.

#### Callback Arguments:

- (required) function(btnList): a callback function that receives an `array` of tab buttons.

A tab button is an object with properties:

Property |         |         |        |
------- | ------- | ------- | -------
name      | string | required | The display name of the button.
data      | object | optional | Custom data of the button, key-value format.
className | string | optional | The className of the button.
actived   | boolean | optional | Button's actived style.
onClick   | (event, data) => boolean | required | A callback function when user click the button. The target button will automatically be added actived style after this callback unless it returns `false`.

##### Example:

```javascript
var type;
myPlugin.on('addTopBar', function(callback) {
	var btnList = [];
	btnList.push({
		name: 'Apple',
		className: '',
		data: {type: 'apple'},
		onClick: function(event, data) {
			if (type != data.type) {
				// `this` points to current button
				type = data.type;
			} else {
				return false;
			}
		}
	});
	btnList.push({
		name: 'Orange',
		className: '',
		data: {type: 'orange'},
		onClick: function(event, data) {
			type = data.type;
		}
	}
	});
	callback(btnList);
});
```


## addTool
Trigger while vConsole trying to add new tool buttons for a plugin. This event will only be triggered once.

##### Callback Arguments:

- (required) function(toolList): a callback function that receives an `array` of tool buttons.

A tool button is an object with properties:

Property |         |         |         |
------- | ------- | ------- | -------
name      | string | required | The display name of the button.
data      | object | optional | Custom data of the button, key-value format.
global    | boolean | optional, default `false` | When `false`, the button will be hidden while switching to other tab. When `true`, the button will be available to all tabs.
onClick   | (event, data) => void | required | A callback function when user click the button.

##### Example:

```javascript
myPlugin.on('addTool', function(callback) {
	var toolList = [];
	toolList.push({
		name: 'Reload',
		global: false,
		data: {},
		onClick: function(event, data) {
			location.reload();
		}
	});
	callback(toolList);
});
```


## ready

Trigger when all initialization is finished. This event will only be triggered once.
Now plugin is installed and it's DOM is ready.

##### Callback Arguments:

- none

##### Example:

```javascript
myPlugin.on('ready', function() {
	// do something...
});
```


## remove

Trigger before starting to uninitialize a plugin. This event will only be triggered once.

Note that this event may be called before `init` event if you remove a plugin before vConsole is ready.

##### Callback Arguments:

- none

##### Example:

```javascript
myPlugin.on('remove', function() {
	// do something...
});
```


## show

Trigger when a tab is shown. Only the plugin binded with `renderTab` will receive this event.

##### Callback Arguments:

- none

##### Example:

```javascript
myPlugin.on('show', function() {
	// do something
});
```


## hide

Trigger when a tab is hidden. Only the plugin binded with `renderTab` will receive this event.

##### Callback Arguments:

- none

##### Example:

```javascript
myPlugin.on('hide', function() {
	// do something
});
```


## showConsole

Trigger when vConsole is shown.

##### Callback Arguments:

- none

##### Example:

```javascript
myPlugin.on('showConsole', function() {
	// do something
});
```


## hideConsole

Trigger when vConsole is hidden.

##### Callback Arguments:

- none

##### Example:

```javascript
myPlugin.on('hideConsole', function() {
	// do something
});
```


## updateOption

Trigger when `vConsole.setOption()` is called.

##### Callback Arguments:

- none

##### Example:

```javascript
myPlugin.on('updateOption', function() {
	// do something
});
```


[Back to Index](./a_doc_index.md)

---

### Doc Plugin Event List CN (`doc/plugin_event_list_CN.md`)

插件：Event 事件列表
==============================

插件的所有事件（event）都是可选的，不强制绑定。但一些特性（比如添加 tool 按钮）依赖于指定的事件，所以若要实现那些特性，就必须绑定指定的事件。

每个事件都会有一个 callback 回调函数，当事件被触发时，就会执行 callback。一些 callback 可能会带有参数。



## init

当插件开始初始化时触发。这个事件触发时，代表 vConsole 开始安装此插件，开发者可以在此时初始化一些配置。
这个事件只会触发一次。

注意，此时插件的 DOM 仍未就绪，插件还未被渲染到页面中。

##### Callback 参数：
- 无

##### 例子：
```javascript
myPlugin.on('init', function() {
	// 在这里可以初始化一些自用的配置
	this.list = []; // `this` == `myPlugin`
});
```


## renderTab

当 vConsole 尝试为此插件渲染新 tab 时触发。这个事件只会触发一次。

绑定此事件后，vConsole 会认为此插件需要创建新 tab，并会将 callback 中获取的 HTML 用于渲染 tab。因此，只要绑定了此事件，新 tab 肯定会被渲染到页面中，无论 callback 传入的 HTML 是否为空。如果不需要添加新 tab，请不要绑定此事件。

##### Callback 参数
- (必填) function(html, options): 回调函数，第一个参数接收一个 HTML 参数用于渲染 tab。`html` 可以为 HTML 字符串，或者 `HTMLElement` 对象（或支持 `appendTo()` 方法的对象，如 jQuery 对象）。第二个参数接收一个可选配置信息。

配置的参数为：

Property | | | |
------- | ------- | ------- | -------
fixedHeight | boolean | 选填 | tab 高度固定为 100%。

##### 例子：

```javascript
myPlugin.on('renderTab', function(callback) {
	var html = '<div>Hello</div>';
	callback(html);
});
```


## addTopBar

当 vConsole 尝试为此插件添加新的 topbar 按钮时触发。这个事件只会触发一次。

#### Callback 参数：

- (必填) function(btnList): 回调函数，接收一个带有按钮配置信息的 `array` 数组。

按钮的参数为：

Property | | | |
------- | ------- | ------- | -------
name      | string | 必填 | 按钮展示的名字。
data      | object | 选填 | 按钮的自定义数据，key-value 格式。
className | string | 选填 | 按钮的 className。
actived   | boolean | optional | 按钮是否处在选中样式。
onClick   | (event, data) => boolean | 必填 | 点击按钮时的回调函数。触发回调后，除非回调函数返回 `false`，此按钮将自动变为选中的样式。

##### 例子：

```javascript
var type;
myPlugin.on('addTopBar', function(callback) {
	var btnList = [];
	btnList.push({
		name: 'Apple',
		className: '',
		data: {type: 'apple'},
		onClick: function(event, data) {
			if (type != data.type) {
				// `this` 指向当前按钮
				type = data.type;
			} else {
				return false;
			}
		}
	});
	btnList.push({
		name: 'Orange',
		className: '',
		data: {type: 'orange'},
		onClick: function(event, data) {
			type = data.type;
		}
	}
	});
	callback(btnList);
});
```



## addTool

当 vConsole 尝试为此插件添加新的 tool 按钮时触发。这个事件只会触发一次。

##### Callback 参数：

- (必填) function(toolList): 回调函数，接收一个带有按钮配置信息的 `array` 数组。

tool 按钮的参数为：

Property |         |         |         |
------- | ------- | ------- | -------
name      | string | 必填 | 按钮展示的名字。
data      | object | 选填 | 按钮的自定义数据，key-value 格式。
global    | boolean | 选填，默认 `false` | `false` 时，当切换到别的 tab 后，按钮就会被隐藏；`true` 时，按钮变成全局可见。
onClick   | (event, data) => void | 必填 | 点击按钮时的回调函数。

##### 例子：

```javascript
myPlugin.on('addTool', function(callback) {
	var toolList = [];
	toolList.push({
		name: 'Reload',
		global: false,
		onClick: function(event, data) {
			location.reload();
		}
	});
	callback(toolList);
});
```


## ready

当插件初始化结束后触发。这个事件只会触发一次。此时插件已经成功安装并已渲染到页面。

##### Callback 参数：

- 无

##### 例子：

```javascript
myPlugin.on('ready', function() {
	// do something...
});
```


## remove

当插件即将卸载前触发。这个事件只会触发一次。

需要注意的是，如果在 vConsole ready 之前就卸载插件，那么此事件会在 `init` 之前就被调用。

##### Callback 参数：

- 无

##### 例子：

```javascript
myPlugin.on('remove', function() {
	// do something...
});
```


## show

当插件的 tab 被显示时触发。只有绑定了 `renderTab` 事件的插件才会收到此事件。

##### Callback 参数：

- 无

##### 例子：

```javascript
myPlugin.on('show', function() {
	// do something
});
```


## hide

当插件的 tab 被隐藏时触发。只有绑定了 `renderTab` 事件的插件才会收到此事件。

##### Callback 参数：

- 无

##### 例子：

```javascript
myPlugin.on('hide', function() {
	// do something
});
```


## showConsole

当 vConsole 被显示时触发。

##### Callback 参数：

- 无

##### 例子:

```javascript
myPlugin.on('showConsole', function() {
	// do something
});
```


## hideConsole

当 vConsole 被隐藏时触发。

##### Callback 参数：

- 无

##### 例子:

```javascript
myPlugin.on('hideConsole', function() {
	// do something
});
```


## updateOption

当 `vConsole.setOption()` 被调用时触发

##### Callback 参数：

- none

##### 例子:

```javascript
myPlugin.on('updateOption', function() {
	// do something
});
```


[返回索引](./a_doc_index_CN.md)

---

### Doc Plugin Getting Started (`doc/plugin_getting_started.md`)

Plugin: Getting Started
==============================

A plugin allows you to:

- add a new panel.
- add one or more top buttons (topBar) or bottom buttons (tool).

You can customize the functions of the panel and buttons.


## Quick Start

Two lines to create a vConsole plugin:

```javascript
var myPlugin = new VConsole.VConsolePlugin('my_plugin', 'My Plugin');
vc.addPlugin(myPlugin);
```

The above plugin has no function. See [Building a Plugin](./plugin_building_a_plugin.md) for more details.


[Back to Index](./a_doc_index.md)

---

### Doc Plugin Getting Started CN (`doc/plugin_getting_started_CN.md`)

插件：入门
==============================

通过插件，你可以：

- 添加一个新的面板。
- 在面板内添加一个或多个顶部按钮（topBar）或底部按钮（tool）。

在面板和按钮中，可添加自定义功能，以满足个性化开发的需要。


## 快速上手

两行创建一个 vConsole 插件：

```javascript
var myPlugin = new VConsole.VConsolePlugin('my_plugin', 'My Plugin');
vc.addPlugin(myPlugin);
```

当然，上面的插件并无任何功能。请继续阅读[编写插件](./plugin_building_a_plugin_CN.md)来了解细节。


[返回索引](./a_doc_index_CN.md)

---

### Doc Plugin Properties Methods (`doc/plugin_properties_methods.md`)

Buitin Plugin: Properties & Methods
==============================

Some built-in plugins will export some public methods for special needs, E.g: 

```javascript
vConsole.log.info()
```

If a plugin is not added, its instance and methods will be `undefined`, E.g:

```javascript
vConsole = new VConsole({ defaultPlugins: ['system'] }); // network plugin is not added
vConsole.network.clear(); // Error: network is undefined
```

---


## Log Panel

---

### vConsole.log.log()

The same as `console.log()` series method. All available methods:

```javascript
vConsole.log.log(...)
vConsole.log.info(...)
vConsole.log.debug(...)
vConsole.log.warn(...)
vConsole.log.error(...)
```

By calling this method, logs will only be output to vConsole Log panel instead of browser console.


---


### vConsole.log.clear()

Remove all logs of Log panel. Similar to `console.clear()`.

#### Parameters

None.

#### Return value

`void`


---


## System Panel

---

### vConsole.system.log() | info() | debug() | warn() | error()

The same as `vConsole.log.log()`, but the logs will be output to System panel.

---

### vConsole.system.clear()

Remove all logs of System panel.

#### Parameters

None.

#### Return value

`void`


---


## Network Panel

---

### vConsole.network.add()

Add a custom request to Network panel.

```javascript
vConsole.network.add(item: VConsoleNetworkRequestItem): VConsoleNetworkRequestItemProxy
```

#### Parameters

- `item: VConsoleNetworkRequestItem`: The custom request object.

```javascript
interface VConsoleNetworkRequestItem {
  // HTTP method
  method: '' | 'GET' | 'POST' | 'PUT' | 'DELETE' | 'HEAD' | 'CONNECT' | 'OPTIONS' | 'TRACE' | 'PATCH';
  // Full URL, E.g: https://www.abc.com/foo?a=b
  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 fetch's 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;
}
```


#### Return value

`VConsoleNetworkRequestItemProxy`

Once a custom request is added, a new object pointing to this request will be returned.

The properties of the return object is extended by `VConsoleNetworkRequestItem`.

```javascript
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;
}
```

---


### vConsole.network.update()

Update a custom request.

```javascript
vConsole.network.update(id: string, item: VConsoleNetworkRequestItem | VConsoleNetworkRequestItemProxy)
```

#### Parameters

- `id: string`: The internal id of the custom request. Can get it in the return value of `vConsole.network.add()`.
- `item: VConsoleNetworkRequestItem | VConsoleNetworkRequestItemProxy`: The custom request object.


#### Return value

`void`


**Notice:**

Modify the properties of `VConsoleNetworkRequestItemProxy.response` will not work.  
If you want to update `response`, you must re-assign the entire object.

```javascript
const item = vConsole.network.add({
  response: { foo: 'bar' },
  ... // other request properties
});

item.response.foo = 'newbar'; // will not work, response will not be changed
item.response = { foo: 'newbar' }; // it works
vConsole.network.update(item.id, item);
```

---


### vConsole.network.clear()

Remove all requests from Network panel.


#### Parameters

None.

#### Return value

`void`

---

### Doc Plugin Properties Methods CN (`doc/plugin_properties_methods_CN.md`)

内置插件：属性及方法
==============================

一些内置插件会对外暴露一些公共方法，以便特殊用途。例如：

```javascript
vConsole.log.info()
```

如果未加载插件，那么其实例对象及方法都会是 `undefined`，使用前需要注意：

```javascript
vConsole = new VConsole({ defaultPlugins: ['system'] }); // 未加载 network 插件
vConsole.network.clear(); // Error: network is undefined
```

---


## Log 面板

---

### vConsole.log.log()

如同 `console.log()` 系列方法，可用的有：

```javascript
vConsole.log.log(...)
vConsole.log.info(...)
vConsole.log.debug(...)
vConsole.log.warn(...)
vConsole.log.error(...)
```

与直接调用 `console.log()` 不同，日志仅会输出到 Log 面板，而不会输出到原始的浏览器 console 里。


---


### vConsole.log.clear()

清空 Log 面板的所有日志，类似 `console.clear()`。

#### 参数

无。

#### 返回值

`void`


---


## System 面板

---

### vConsole.system.log() | info() | debug() | warn() | error()

与 `vConsole.log.log()` 一致，只不过日志会输出到 System 面板。

---

### vConsole.system.clear()

清空 System 面板的所有日志。

#### 参数

无。

#### 返回值

`void`


---


## Network 面板

---

### vConsole.network.add()

输出一个自定义 request 请求到 Network 面板。

```javascript
vConsole.network.add(item: VConsoleNetworkRequestItem): VConsoleNetworkRequestItemProxy
```

#### 参数

- `item: VConsoleNetworkRequestItem`: 自定义的 Request 对象。

```javascript
interface VConsoleNetworkRequestItem {
  // HTTP method
  method: '' | 'GET' | 'POST' | 'PUT' | 'DELETE' | 'HEAD' | 'CONNECT' | 'OPTIONS' | 'TRACE' | 'PATCH';
  // 完整的 URL，如： https://www.abc.com/foo?a=b
  url: string;
  // HTTP 状态码，如： 200
  status: number | string;
  // XMLHttpRequest.readyState
  readyState?: XMLHttpRequest['readyState'];
  // Response header， KV 键值对
  header: { [key: string]: string };
  // XMLHttpRequest.responseType
  responseType?: XMLHttpRequest['responseType'];
  // 'xhr': XMLHttpRequest, 'custom': 自定义请求
  requestType: 'xhr' | 'fetch' | 'ping' | 'custom';
  // 对应 `XMLHttpRequest.setRequestHeader()` 或 fetch 的 headers
  requestHeader?: HeadersInit;
  // 回包的内容
  response: any;
  // 时间戳
  startTime: number;
  // 时间戳
  endTime: number;
  // Query string parameters，KV 键值对或 JSON 字符串
  getData?: { [key: string]: string } | null;
  // Request payload，KV 键值对或 JSON 字符串
  postData?: { [key: string]: string } | string | null;
}
```


#### 返回值

`VConsoleNetworkRequestItemProxy`

调用 `add()` 方法后，会返回一个新的对象，其内容继承于刚刚传入的 `VConsoleNetworkRequestItem` 对象，并且会增改部分属性值。

```javascript
interface VConsoleNetworkRequestItemProxy extends VConsoleNetworkRequestItem {
  // 内部 id，用于后续 update() 方法
  id: string;
  // 原始 response 会被尝试转成 JSON 字符串，若不成功则保持为原始值
  response: string | any;
  // 耗时，等于 endTime - startTime
  costTime?: number;
}
```

---


### vConsole.network.update()

更新一个自定义请求。

```javascript
vConsole.network.update(id: string, item: VConsoleNetworkRequestItem | VConsoleNetworkRequestItemProxy)
```

#### 参数

- `id: string`: 内部 id，可通过 `vConsole.network.add()` 的返回值获取。
- `item: VConsoleNetworkRequestItem | VConsoleNetworkRequestItemProxy`: 自定义的 Request 对象。


#### 返回值

`void`


**注意：**

直接修改 `VConsoleNetworkRequestItemProxy.response` 的属性值将不会奏效。  
如果你想更新 `response` 的内容，需要重新赋值整个对象。

```javascript
const item = vConsole.network.add({
  response: { foo: 'bar' },
  ... // 其他字段
});

item.response.foo = 'newbar'; // 不生效，response 不会有变化
item.response = { foo: 'newbar' }; // 有效
vConsole.network.update(item.id, item);
```

---


### vConsole.network.clear()

清空 Network 面板的所有记录。


#### 参数

无。

#### 返回值

`void`

---

### Doc Public Properties Methods (`doc/public_properties_methods.md`)

Public Properties & Methods
==============================

Some useful vConsole properties and methods are available for plugin development.

---
## Static Properties

---

### VConsole.instance

Get the current vConsole instance, which is a singleton instance. Returns `undefined` if it has not been instantiated.

---

### VConsole.VConsolePlugin

The prototype of custom plugin. See [Plugin: Getting Started](./plugin_getting_started.md) for details.

---

## Instance Properties

---

### vConsole.version

The current version of vConsole.

- Readonly
- Type: string

Example:

```javascript
vConsole.version // => "3.11.0"
```

---

### vConsole.option

A configuration object.

- Writable
- Type: `VConsoleOptions`

TypeScript users can import the type directly:

```typescript
import type { VConsoleOptions } from 'vconsole';
```

Available sub-types: `VConsoleLogOptions`, `VConsoleNetworkOptions`, `VConsoleStorageOptions`, `VConsoleAvailableStorage`.

Key                   | Type     | Optional | Default value                               | Description
--------------------- | -------- | -------- | ------------------------------------------- | -------------------
defaultPlugins        | Array(String) | true     | ['system', 'network', 'element', 'storage'] | Listed built-in plugins will be inited and loaded into vConsole. 
pluginOrder           | Array(String) | true | [] | Plugin panels will be sorted as this list. Plugin not listed will be put last.
onReady               | Function | true     |                                             | Trigger after vConsole is inited and default plugins is loaded.
disableLogScrolling   | Boolean  | true     |                                             | If `false`, panel will not scroll to bottom while printing new logs.
theme                 | String   | true     | 'light'                                     | Theme mode, 'light' | 'dark'.
target                | String, HTMLElement | true | `document.documentElement`           | An HTMLElement or CSS selector string to render to.
log.maxLogNumber      | Number   | true     | 1000                                        | Overflow logs will be removed from log panels.
log.showTimestamps    | Boolean  | true     | false                                       | Display timestamps of logs.
network.maxNetworkNumber | Number | true    | 1000                                        | Overflow requests will be removed from Netowrk panel.
network.ignoreUrlRegExp | RegExp | true     |                                              | Skip the requests which url match the RegExp.
storage.defaultStorages  | Array  | true    | ['cookies', 'localStorage', 'sessionStorage'] | Listed storage(s) will be available in Storage panel.

Example:

```javascript
// get
vConsole.option // => {...}
// set single key only
vConsole.setOption('log.maxLogNumber', 5000);
// overwrite 'log' object
vConsole.setOption({ log: { maxLogNumber: 5000 } });
```

---

## Methods

---

### vConsole.setOption(keyOrObj[, value])

Update `vConsole.option`.

##### Parameters:
- (required) keyOrObj: The key of option, or a key-value object.
- (optional) value: The value of an option.

##### Return:
- None

##### Example:

```javascript
vConsole.setOption('maxLogNumber', 5000);
// or:
vConsole.setOption({maxLogNumber: 5000});
```

---

### vConsole.setSwitchPosition(x, y)

Update the position of switch button.

##### Parameters:
- (required) x: X coordinate, the origin of the coordinate is at the bottom right corner of the screen.
- (required) y: Y coordinate, the origin of the coordinate is at the bottom right corner of the screen.

##### Return:
- None

##### Example:

```javascript
vConsole.setSwitchPosition(20, 20);
```

---

### vConsole.destroy()

Destroy an vConsole instance object and remove vConsole panel from document.

##### Parameters:
- None

##### Return:
- None

##### Example:

```javascript
var vConsole = new VConsole();
// ... do something
vConsole.destroy();
```

---

### vConsole.addPlugin(plugin)

Add a new plugin to vConsole. Duplicate plugin will be ignored.

##### Parameters:
- (required) plugin: An VConsolePlugin object.

##### Return:
- Boolean: `true` for success, `false` for failure.

##### Example:

```javascript
var myPlugin = new VConsolePlugin('my_plugin', 'My Plugin');
vConsole.addPlugin(myPlugin);
```

---

### vConsole.removePlugin(pluginID)

Remove an existing plugin.

##### Parameters:
- (required) pluginID: A string, plugin's id.

##### Return:
- Boolean: `true` for success, `false` for failure.

##### Example:

```javascript
vConsole.removePlugin('my_plugin');
```

---

### vConsole.showPlugin(pluginID)

Activating a panel according to its plugin id.

Plugin event `hide` will be triggered for previous actived panel, and `show` for current actived panel.

##### Parameters:
- (required) pluginID: A string, panel's plugin id.

##### Return:
- None

##### Example:

```javascript
vConsole.showPlugin("system"); // show System panel
```

---

### vConsole.show()

Show vConsole panel. This method will trigger plugin event `showConsole`.

##### Parameters:
- None

##### Return:
- None

##### Example:

```javascript
vConsole.show();
```

---

### vConsole.hide()

Hide vConsole panel. This method will trigger plugin event `hideConsole`.

##### Parameters:
- None

##### Return:
- None

##### Example:

```javascript
vConsole.hide();
```

---

### vConsole.showSwitch()

Show vConsole switch button.

##### Parameters:
- None

##### Return:
- None

##### Example:

```javascript
vConsole.showSwitch();
```

---

### vConsole.hideSwitch()

Hide vConsole switch button. 

After the button is hidden, the user will not be able to call vConsole manually. The button or panel must be shown programmably via `vConsole.showSwitch()` or `vConsole.show()`.

##### Parameters:
- None

##### Return:
- None

##### Example:

```javascript
vConsole.hideSwitch();
```

---

[Back to Index](./a_doc_index.md)

---

### Doc Public Properties Methods CN (`doc/public_properties_methods_CN.md`)

公共属性及方法
==============================

vConsole 提供一些公共属性字段、函数方法，以便开发插件。

## 静态属性

---

### VConsole.instance

获取当前已实例化后的 vConsole 对象，是一个单例对象。如果没有实例化过，将返回 `undefined`。

---

### VConsole.VConsolePlugin

自定义插件的原型对象。具体用法见 [插件：入门](./plugin_getting_started_CN.md)。

---

## 实例属性

---

### vConsole.version

当前 vConsole 的版本号。

- 只读
- 类型：string

例子：

```javascript
vConsole.version // => "3.11.0"
```

---

### vConsole.option

配置项。

- 可写
- 类型：`VConsoleOptions`

TypeScript 用户可直接导入类型：

```typescript
import type { VConsoleOptions } from 'vconsole';
```

相关子类型：`VConsoleLogOptions`、`VConsoleNetworkOptions`、`VConsoleStorageOptions`、`VConsoleAvailableStorage`。

键名                  | 类型      | 可选     | 默认值                                       | 描述
--------------------- | -------- | -------- | ------------------------------------------- | -------------------
defaultPlugins        | Array(String) | true     | ['system', 'network', 'element', 'storage'] | 需要自动初始化并加载的内置插件。 
pluginOrder           | Array(String) | true | [] | 插件面板会按此列表进行排序，未列出的插件将排在最后。
onReady               | Function | true     |                                             | 回调方法，当 vConsole 完成初始化并加载完内置插件后触发。
disableLogScrolling   | Boolean  | true     |                                             | 若为 `false`，有新日志时面板将不会自动滚动到底部。
theme                 | String   | true     | 'light'                                     | 主题颜色，可选值为 'light' | 'dark'。
target                | String, HTMLElement | true | `document.documentElement`           | 挂载到的节点，可为 HTMLElement 或 CSS selector。
log.maxLogNumber      | Number   | true     | 1000                                        | 超出数量上限的日志会被自动清除。
log.showTimestamps    | Boolean  | true     | false                                       | 显示日志的输出时间
log.maxNetworkNumber  | Number   | true     | 1000                                        | 超出数量上限的请求记录会被自动清除。
network.ignoreUrlRegExp | RegExp | true     |                                             | 不展示 URL 匹配正则表达式的请求。
storage.defaultStorages  | Array  | true    | ['cookies', 'localStorage', 'sessionStorage'] | 在 Storage 面板中要加载的 storage 类型。

例子：

```javascript
// 获取：
vConsole.option // => {...}
// 设指定键值：
vConsole.setOption('log.maxLogNumber', 5000);
// 覆盖整个对象：
vConsole.setOption({ log: { maxLogNumber: 5000 } });
```


---

## 方法

---

### vConsole.setOption(keyOrObj[, value])

更新 `vConsole.option` 配置项。

##### 参数：
- (required) keyOrObj: 配置项的 key 值，或直接传入 key-value 格式的 object 对象。
- (optional) value: 配置项的 value 值。

##### 返回：
- 无

##### 例子：

```javascript
vConsole.setOption('maxLogNumber', 5000);
// 或者：
vConsole.setOption({maxLogNumber: 5000});
```

---

### vConsole.setSwitchPosition(x, y)

设置开关按钮的位置。

##### 参数：
- (required) x: X 坐标，坐标原点位于屏幕右下角。
- (required) y: Y 坐标，坐标原点位于屏幕右下角。

##### 返回：
- 无

##### 例子：

```javascript
vConsole.setSwitchPosition(20, 20);
```

---

### vConsole.destroy()

析构一个 vConsole 对象实例，并将 vConsole 面板从页面中移除。

##### 参数：
- 无

##### 返回：
- 无

##### 例子：

```javascript
var vConsole = new VConsole();
// ... do something
vConsole.destroy();
```

---

### vConsole.addPlugin(plugin)

添加一个新插件。重名的插件会被忽略。

##### 参数：
- (required) plugin: 一个 VConsolePlugin 对象。

##### 返回：
- Boolean: 成功为 `true`，失败为 `false`。

##### 例子：

```javascript
var myPlugin = new VConsolePlugin('my_plugin', 'My Plugin');
vConsole.addPlugin(myPlugin);
```

---

### vConsole.removePlugin(pluginID)

卸载一个插件。

##### 参数：
- (required) pluginID: 插件的 plugin id。

##### 返回：
- Boolean: 成功为 `true`，失败为 `false`。

##### 例子：

```javascript
vConsole.removePlugin('my_plugin');
```

---

### vConsole.showPlugin(pluginID)

根据 plugin id 激活显示一个面板。

此方法会触发先前激活态面板的 `hide` 事件，并触发当前激活态面板的 `show` 事件。

##### 参数：
- (required) pluginID: 字符串，面板的 plugin id。

##### 返回：
- 无

##### 例子：

```javascript
vConsole.showPlugin("system"); // 显示 System 面板
```

---

### vConsole.show()

显示 vConsole 主面板。这个方法会触发插件事件 `showConsole`。

##### 参数：
- 无

##### 返回：
- 无

##### 例子：

```javascript
vConsole.show();
```

---

### vConsole.hide()

隐藏 vConsole 主面板。这个方法会触发插件事件 `hideConsole`。

##### 参数：
- 无

##### 返回：
- 无

##### 例子：

```javascript
vConsole.hide();
```

---

### vConsole.showSwitch()

显示 vConsole 的开关按钮。

##### 参数：
- 无

##### 返回：
- 无

##### 例子：

```javascript
vConsole.showSwitch();
```

---

### vConsole.hideSwitch()

隐藏 vConsole 的开关按钮

隐藏后，用户将无法手动唤起 vConsole 面板。因此按钮或面板必须通过 `vConsole.showSwitch()` 或 `vConsole.show()` 来展示出来。

##### 参数：
- 无

##### 返回：
- 无

##### 例子：

```javascript
vConsole.hideSwitch();
```

---

[返回索引](./a_doc_index_CN.md)

---

### Doc Tutorial (`doc/tutorial.md`)

English | [简体中文](./tutorial_CN.md)

Tutorial
===

## Getting Started


#### Install using npm (Recommanded)

```bash
$ npm install vconsole
```

```javascript
import VConsole from 'vconsole';

const vConsole = new VConsole();
// or init with options
const vConsole = new VConsole({ theme: 'dark' });

// call `console` methods as usual
console.log('Hello world');

// remove it when you finish debugging
vConsole.destroy();
```

If you are using TypeScript, you can import the option types directly:

```typescript
import VConsole from 'vconsole';
import type { VConsoleOptions } from 'vconsole';

const options: VConsoleOptions = { theme: 'dark' };
const vConsole = new VConsole(options);
```

> Notice that `VConsole` is the prototype of vConsole.  
> So vConsole panel will not be inserted into your page until you `new` it manually.

Otherwise, you can use CDN to import vConsole:

```html
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
<script>
  // VConsole will be exported to `window.VConsole` by default.
  var vConsole = new window.VConsole();
</script>
```

Available CDN:

- https://unpkg.com/vconsole@latest/dist/vconsole.min.js
- https://cdn.jsdelivr.net/npm/vconsole@latest/dist/vconsole.min.js

---

## Usage

### Initialization & Configuaration

After imported, vConsole should be inited manually:

```javascript
var vConsole = new VConsole(option);
```

`option` is an optional object.

See [Public Properties & Methods](./public_properties_methods.md) for definition.

Use `setOption()` to update `option`:

```javascript
// set single key only
vConsole.setOption('log.maxLogNumber', 5000);
// overwrite 'log' object
vConsole.setOption({ log: { maxLogNumber: 5000 } });
```

---


### Output logs

Use the methods of `console` to print logs, just like what you do at desktop browsers:

```javascript
console.log('Hello World');
```

When vConsole is not loaded, logs will be printed to browser console. After importing vConsole, logs will be printed to both vConsole panel and browser console.

If you want to print logs to vConsole panel only, try [Log plugin methods](./plugin_properties_methods.md):

```javascript
vConsole.log.log('Hello world');
```

---

### Log methods

5 types of log methods are supported, with different styles:

```javascript
console.log('foo');   // black word, white bakcground
console.info('bar');  // purple word, white background
console.debug('oh');  // orange word, white background
console.warn('foo');  // orange word, yellow background
console.error('bar'); // red word, pink background
```

---

### Other methods

Supported `console` methods:

```javascript
console.clear();        // Clear all logs
console.time('foo');    // start a timer named "foo"
console.timeEnd('foo'); // stop "foo" timer and print the elapsed time
```

---


### Styling log output

Use `%c` to add style to logs:

```javascript
console.log('%c blue %c red', 'color:blue', 'color:red'); // blue red
console.log('%c FOO', 'font-weight:bold', 'bar'); // FOO bar
console.log('%c Foo %c bar', 'color:red'); // Foo %c bar
```

> Note that only the first parameter support `%c` format, and the `%c` must be followed by a space. The following parameter(s) will be used as HTML style to fill `%c`, and the remain `%c` or parameters will be shown as normal string.

---

### Using string substitutions

Use `%s, %d, %o` to output a log with formatting. The pattern must be followed by a space.

- `%s`: Output as a string. Non-string objects will be converted into strings.
- `%d`: Output as a number.
- `%o`: Output as an object. You can clickthe object name to open more information about it.

```javascript
console.log('Hi %s, Im %s', 'Foo', 'Bar'); // Hi Foo, Im Bar
console.log('I had %d cakes', 3); // I had 3 cakes
console.log('The %o is large', obj); // The [[obj]] is large
```

---

### Special format

Use `[system]` as the first parameter to output logs to System panel:

```javascript
console.log('[system]', 'foo'); // 'foo' will be printed to System panel
console.log('[system] bar'); // this log will show in Log tab instead of System panel
```

---

## Built-in Plugins

### Network

All `XMLHttpRequest | fetch | sendBeacon | WebSocket` requests will be logged in Network panel by default.

Static resources loaded by the browser (images, scripts, stylesheets, fonts, etc.) are also captured via `PerformanceObserver`. These entries show the URL, resource type, HTTP status, timing, and size; response body is not available for static resources. When a resource is served from cache, the detail view shows `From Cache: true`.

WebSocket connections appear in the Network panel with method `WS`. Expanding a connection shows its status (`Connecting`, `Connected`, `Closed`, etc.) and a **Messages** section listing every sent (↑) and received (↓) message in chronological order.

To prevent logging, add `_noVConsole = true` to XHR object:

```javascript
var xhr = new XMLHttpRequest();
xhr._noVConsole = true; // now this request would not be logged in panel
xhr.open('GET', 'http://example.com/');
xhr.send();
```

If you want to print custom request logs, try [Network plugin methods](./plugin_properties_methods.md):

```javascript
vConsole.network.add(...);
```


[Goto: Documentation Index](./a_doc_index.md)

---

### Doc Tutorial CN (`doc/tutorial_CN.md`)

[English](./tutorial.md) | 简体中文

使用教程
===

## 上手

#### 使用 NPM 安装（推荐）

```bash
$ npm install vconsole
```

```javascript
import VConsole from 'vconsole';

const vConsole = new VConsole();
// 或者使用配置参数进行初始化
const vConsole = new VConsole({ theme: 'dark' });

// 调用 console 方法输出日志
console.log('Hello world');

// 完成调试后，可销毁 vConsole
vConsole.destroy();
```

如果你使用 TypeScript，可以直接导入配置项类型：

```typescript
import VConsole from 'vconsole';
import type { VConsoleOptions } from 'vconsole';

const options: VConsoleOptions = { theme: 'dark' };
const vConsole = new VConsole(options);
```

> 请注意，`VConsole` 只是 vConsole 的原型，而非一个已实例化的对象。  
> 所以在手动 `new` 实例化之前，vConsole 不会被插入到网页中。

或者，你可以用 CDN 来引入 vConsole：

```html
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
<script>
  // VConsole 会自动挂载到 `window.VConsole`
  var vConsole = new window.VConsole();
</script>
```

可用的 CDN：

- https://unpkg.com/vconsole@latest/dist/vconsole.min.js
- https://cdn.jsdelivr.net/npm/vconsole@latest/dist/vconsole.min.js


---

## 使用方法

### 初始化 & 配置

引入后, 需要手动初始化 vConsole：

```javascript
var vConsole = new VConsole(option);
```

`option` 是一个选填的 object 对象，具体配置定义请参阅 [公共属性及方法](./public_properties_methods_CN.md)。

使用 `setOption()` 来更新 `option`：

```javascript
// 设指定键值：
vConsole.setOption('log.maxLogNumber', 5000);
// 覆盖整个对象：
vConsole.setOption({ log: { maxLogNumber: 5000 } });
```

---

### 打印日志

与 PC 端打印 log 一致，可直接使用 `console.log()` 等方法直接打印日志：

```javascript
console.log('Hello World');
```

未加载 vConsole 模块时，`console.log()` 会直接打印到原生控制台中；加载 vConsole 后，日志会打印到页面前端+原生控制台。

如果你希望日志仅输出到 vConsole 中，可使用[插件方法](./plugin_properties_methods_CN.md)：

```javascript
vConsole.log.log('Hello world');
```

---

### 日志类型

支持 5 种不同类型的日志，会以不同的颜色输出到前端面板：

```javascript
console.log('foo');   // 白底黑字
console.info('bar');  // 白底紫字
console.debug('oh');  // 白底黄字
console.warn('foo');  // 黄底黄字
console.error('bar'); // 红底红字
```

---

### 其他方法

支持以下 `console` 方法：

```javascript
console.clear();        // 清空所有日志
console.time('foo');    // 启动名为 foo 的计时器
console.timeEnd('foo'); // 停止 foo 计时器并输出经过的时间
```

---

### 样式

可使用 `%c` 来添加样式：

```javascript
console.log('%c blue %c red', 'color:blue', 'color:red'); // blue red
console.log('%c FOO', 'font-weight:bold', 'bar'); // FOO bar
console.log('%c Foo %c bar', 'color:red'); // Foo %c bar
```

> 只有第一个参数支持 `%c` 格式，且 `%c` 后必须带空格。一旦出现 `%c` 格式，后续的字符串参数将作为 HTML style 样式来替换 `%c`；未被替换的 `%c`、剩余的参数，将作为默认日志照常输出。


---


### 使用字符串替换

可使用 `%s, %d, %o` 来格式化输出，关键字后必须带空格。

- `%s`：输出为字符串。非字符串对象会被转换成字符串。
- `%d`：输出为数字。
- `%o`：输出为对象。可以点击展开对象详情。

```javascript
console.log('Hi %s, Im %s', 'Foo', 'Bar'); // Hi Foo, Im Bar
console.log('I had %d cakes', 3); // I had 3 cakes
console.log('The %o is large', obj); // The [[obj]] is large
```

---

### 特殊格式

支持使用 `[system]` 作为第一个参数，来将 log 输出到 System 面板：

```javascript
console.log('[system]', 'foo'); // 'foo' 会输出到 System 面板
console.log('[system] bar'); // 这行日志会输出到 Log 面板而非 System 面板
```

若编写自定义 log 面板插件，亦可通过上述格式将 log 输出到自定义面板：

```javascript
console.log('[myplugin]', 'bar'); // 'myplugin' 为自定义面板插件的 id
```

---

## 内置插件

### Network 网络请求

所有 `XMLHttpRequest | fetch | sendBeacon | WebSocket` 请求都会被显示到 Network 面板中。

浏览器加载的静态资源（图片、脚本、样式表、字体等）也会通过 `PerformanceObserver` 捕获，可在面板中查看其 URL、资源类型、HTTP 状态码、耗时和大小；静态资源的响应体无法获取。若资源命中缓存，详情视图中会显示 `From Cache: true`。

WebSocket 连接会以 `WS` 方法显示在 Network 面板中。展开后可查看连接状态（`Connecting`、`Connected`、`Closed` 等）及 **Messages** 消息列表，按时间顺序展示所有已发送（↑）和已接收（↓）的消息。

若不希望一个请求显示在面板中，可添加属性 `_noVConsole = true` 到 XHR 对象中：

```javascript
var xhr = new XMLHttpRequest();
xhr._noVConsole = true; // 不会显示到 tab 中
xhr.open('GET', 'http://example.com/');
xhr.send();
```

如果你想展示自定义的 request 请求，可尝试 [Network 插件方法](./plugin_properties_methods_CN.md)：

```javascript
vConsole.network.add(...);
```


[前往：文档索引](./a_doc_index_CN.md)

---

--- METRICS ---
- Files Extracted: 15
- Estimated Token Budget: ~11783 tokens
- Canonical Reference: https://codewiki.google/github.com/Tencent/vConsole
