自定义浏览器 console 输出 -- devtoolsFormatters

自定义浏览器 console 输出 – devtoolsFormatters

当我们使用 console.log(…) 输出一些信息的时候, 浏览器会按照一定的格式输出这些信息到控制台。
例如:
自定义浏览器 console 输出 -- devtoolsFormatters_第1张图片
我们可以看出浏览器对于不同的数据是做了不同的格式处理的,对于简单的字符串是直接输出 “xxx”,但是对于一些对象或数组类型,会先输出一个简单信息然后有一个展开的箭头可以查看详细的信息。
例如上图的 friend 会在第一行先展示 Array(1) 代表这是数组并且长度为 1,点击 friend 左边的箭头又可以查看数组的具体元素。

那么如果我们调用 console.log 的时候不希望浏览器安装这种格式去输出我们的信息,或者这样输出对我们开发调试查看问题不友好的时候,我们就可以使用 devtoolsFormatters 自定义我们自己的数据的输出了。

浏览器设置

在自定义 devtoolsFormatters 之前, 你需要先打开浏览器的 Enable custom formatters 设置。
打开 chrome 控制台, 右上角有个设置的图标点进去
在这里插入图片描述

在 Preferences 的 Console 中有一个 Enable custom formatters,勾选上就可以了
自定义浏览器 console 输出 -- devtoolsFormatters_第2张图片
那么现在就可以开始进入主题使用 devtoolsFormatters 自定义输出了

window.devtoolsFormatters

devtoolsFormatters 挂载在 window 对象上,如果你从未对其赋值,那么它的值是 undefined,期望的值是一个 formatter 数组,formatter 是一个包含 header,hasBody,body 三个函数的对象。

const formatter = {
  header(){...},
  hasBody(){...},
  body(){...},
}
if (window.devtoolsFormatters instanceof Array) {
  window.devtoolsFormatters.push(formatter);
} else {
  window.devtoolsFormatters = [formatter];
}

formatter

formatter 包含了 header,hasBody,body 三个函数,且三个函数都会接收 console.log 中传的数据,例如
console.log({ name: 'eno'; }); 那么三个函数都会接收到参数 {name: 'eno'}。hasBody 函数需要返回一个 bool 函数,而 header 和 body 函数返回一个 jsonMl 格式的数据,

jsonML
jsonML 就是使用 json 格式描述 dom(xml) 节点的一种方式,其格式为 [tag-name: string, attributes: object, element-list: string | jsonMl],不懂可以自行查阅相关资料。

header
header 用来格式化输出的第一行信息,比如我们第一个例子:console.log({ name: 'eno', friend: [{ name: 'zeng'}]}) 时候第一行会输出一个简单信息
{name: 'eno', friend: Array(1)},我们的 header 函数将会决定这一部分输出的内容是什么。如果输出的是 null,浏览器将会使用自己的方式格式化信息输出。

body
body 就是我们输出负责数据时展开的详细信息部分,formatter 的 body 函数会决定这一部分输出什么。body 函数和 header 是一样的,同样返回一个 jsonML 格式的数据。

hasBody
顾名思义就是有没有body,该函数需要返回一个 boolean 值,这将决定我们的输出中有没有箭头,就是点击展开查看 body 的那个箭头。如果返回的是 true,那么将会显示一个箭头,如果是 false 那么久没有。

请添加图片描述

举个栗子

写一个具体的示例来体现 devtoolsFormatters 用法会更加直接。

背景:假设我们有一个类叫 CustomerError 使我们自定义的一个报错类型,现在 console.log 对我们的报错输出不够理想,我们需要格式化输出更好的去调试代码。

CustomerError
首先先来个 CustomerError,用 message 记录报错信息,fileName 和 lineNumber 分别记录报错的文件和行号,重写一下 toString 方法;
顺便来一个 isCustomerError 的判断函数,判断一个数据是否是 CustomerError 的数据

class CustomerError {
  constructor(message, fileName, lineNumber) {
    this.message = message;
    if (fileName && lineNumber) {
      this.target = {
        fileName,
        lineNumber,
      }
    }
  }
  
  toString() {
    return `CustomerError: ${this.message}`;
  }
}

const isCustomerError = (val) => val instanceof CustomerError;

formatter
接下来就是 formatter,我们判断数据是否是我们的 CustomerError,如果不是交个浏览器模式处理即可。如果是则返回一个 jsonML 的数据。

const formatter = {
  header(obj) {
    if (!isCustomerError(obj)) return null;
    const style = 'color:red;' // 使用 style 可以设置输出的样式,例如颜色,字体等,这里用红色输出 header 部分
    return [
      'div',
      { style },
      obj.toString(),
    ]
  },
  hasBody(obj) {
    return isCustomerError(obj);
  },
  body(obj) {
    if (!isCustomerError(obj)) return null;
    const style = 'text-indent: 2em;';
    const jsonMl = [
      'div',
      { style },
      [
        'div',
        {},
        [
          'div',
          {},
          `message: "${obj.message}"`,
        ],
      ],
    ];
    if (obj.target) {
      jsonMl.push([
        'div',
        {},
        [
          'div',
          {},
          `target: "${obj.target.fileName}:${obj.target.lineNumber}"`,
        ],
      ]);
    }
    return jsonMl;
  }
}

测试一下
声明一个 CustomerError 实例,然后 console.log 一下看看控制台会发生什么

const customerError = new CustomerError('This is my customer error!', 'index.html', 93);
console.log(customerError);

执行结果:
请添加图片描述

关于返回的 jsonML

tag-name

jsonML 的第一个元素是 tag-name,目前仅试过返回 divspan 成功,尝试返回 pul 都失败了。
divspan 两者的却别就是换行,使用 div 的话内容独占一行,如果使用 span,可以让多个 jsonML 的内容在同一行显示。

attributes

jsonML 的第二个元素 attributes,目前仅使用 style,不清楚 devtoolsFormatters 还可以支持那些属性去格式输出,因为没有找到有官方文档对这个函数的说明。style 的话参考 css 的语法就可以了。

element-list

上面的例子可以看出,其实 jsonML 不一定是传入三个元素,同意也可以放回四个、五个甚至更多元素,只不过后面的元素都会被当做渲染内容就是 element-list

最后

以上就是对 devtoolsFormatters 的用法,如果进一步了解实战中的用法,也可以参考 vue 源码中的 initCustomFormatter 函数

你可能感兴趣的:(其他,javascript,前端,chrome,devtools)