每天一个npm包 之 debug

<!-- TOC -->

  • 每天一个npm包 之 debug

    • 介绍:
    • 毫秒之差
    • 通配符*
    • 环境变量
    • 格式化

      • 自定义格局
    • 对浏览器的反对
    • 对debug进行扩大
    • 动静设置
    • 查看调试指标是否已启用
    • 趣味源码浏览

      • 如何判断是浏览器环境还是nodeJs环境呢?
      • 浏览器环境 / nodeJs环境 底层的打印是应用什么实现的呢?
      • 每一条打印进去的log, 后边都会随着一个工夫,这个工夫是怎么计算出来的呢?
      • 格式化是怎么事实的呢? 格式化的扩大是怎么实现的呢?
    • 参考:
  • 社交信息 / Social Links:

<!-- /TOC -->

介绍:

这是一个模拟 Node.js 外围调试技术的小型 JavaScript 调试实用程序。 实用于 Node.js 和 Web 浏览器。

debug包 裸露一个函数; 你只须要将你模块的名字传递给这个函数,它就会返回一个将console.error进行了封装的调试语句给你应用。 这将容许您切换到模块的不同局部以及整个模块的调试输入。

毫秒之差

当咱们在踊跃开发应用程序,在认真设计咱们的代码时,查看一次 debug() 调用和下一次调用之间破费的工夫会很有用。

例如,假如您在申请资源之前调用了一次 debug(),并且申请实现之后也调用了一次,两次调用将显示调用之间破费了多少工夫。

通配符*

  • 符号被用作通配符应用。

例如,假如您的库中具备名为“connect:bodyParser”、“connect:compress”、“connect:session”的调试器,能够不必像 DEBUG=connect:bodyParser,connect:compress,connect:session 这样一个一个列出来。

您能够简略地执行 DEBUG=connect:*,或者应用此模块运行所有内容只需应用 DEBUG=*

环境变量

通过 Node.js 运行时,您能够设置一些环境变量来更改调试日志记录的行为:

变量名用处
DEBUG启用/禁用特定的调试命名空间。
DEBUG_HIDE_DATE暗藏调试输入中的日期(非 TTY)
DEBUG_COLORS是否在调试输入中应用色彩
DEBUG_DEPTH对象查看深度
DEBUG_SHOW_HIDDEN显示被查看对象的暗藏属性
留神:以 DEBUG_ 结尾的环境变量最终会被转换为一个可与 %o/%O 格式化程序一起应用的 Options 对象。 无关残缺列表,请参阅 util.inspect() 的 Node.js 文档。

格式化

Debug应用 printf-style 格局。 以下是官网反对的格式化程序:

格局含意
%O在多行上丑陋地打印一个对象
%o在一行上丑陋地打印一个对象
%s字符串
%d数字(整数和浮点数)
%jJSON。 如果参数蕴含循环援用,则替换为字符串 '[Circular]'
%%单个百分号 ('%'),这不会应用到参数或者变量

自定义格局

您能够通过扩大 debug.formatters 对象增加自定义格局。

例如,如果您想增加对应用 %h 将 Buffer 渲染为十六进制的反对,您能够写下如下代码:

const createDebug = require('debug')createDebug.formatters.h = (v) => {  return v.toString('hex')}// …elsewhereconst debug = createDebug('foo')debug('this is hex: %h', new Buffer('hello world'))//   foo this is hex: 68656c6c6f20776f726c6421 +0ms

对浏览器的反对

您能够应用 browserify 构建一个浏览器就绪脚本,或者如果您不想本人构建它,能够应用 browserify-as-a-service 构建。

debug的启用状态由以后的 localStorage 来决定。

思考上面代码的状况,其中您有 worker:a 和 worker:b,如果您心愿对两者进行调试。 您能够应用 localStorage.debug 启用此性能:

`localStorage.debug = 'worker:*'
`

而后刷新页面。

a = debug('worker:a');b = debug('worker:b');setInterval(function(){  a('doing some work');}, 1000);setInterval(function(){  b('doing some work');}, 1200);

对debug进行扩大

您能够简略地扩大调试器debugger

const log = require('debug')('auth');//creates new debug instance with extended namespaceconst logSign = log.extend('sign');const logLogin = log.extend('login');log('hello'); // auth hellologSign('hello'); //auth:sign hellologLogin('hello'); //auth:login hello

动静设置

您还能够通过调用 enable() 办法动静启用调试:

let debug = require('debug');console.log(1, debug.enabled('test'));debug.enable('test');console.log(2, debug.enabled('test'));debug.disable();console.log(3, debug.enabled('test'));

输入:

1 false2 true3 false

查看调试指标是否已启用

创立调试实例后,您能够通过查看 enabled 属性来确定它是否已启用:

const debug = require('debug')('http');if (debug.enabled) {  // do stuff...}

您还能够手动切换此属性以强制启用或禁用调试实例。

趣味源码浏览

如何判断是浏览器环境还是nodeJs环境呢?

if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) {    module.exports = require('./browser.js'); // 浏览器环境} else {    module.exports = require('./node.js'); // nodeJs环境}

解释:

检测Electron renderer/nwjs过程,因为它是节点,所以咱们应该视为浏览器。

浏览器环境 / nodeJs环境 底层的打印是应用什么实现的呢?

浏览器环境:

/** * Invokes `console.debug()` when available. * No-op when `console.debug` is not a "function". * If `console.debug` is not available, falls back * to `console.log`. * * @api public */exports.log = console.debug || console.log || (() => {});

nodeJs环境:

/** * Invokes `util.format()` with the specified arguments and writes to stderr. */function log(...args) {    return process.stderr.write(util.format(...args) + '\n');}

common.js:

    ···    ···    const logFn = self.log || createDebug.log;    logFn.apply(self, args);    ···    ···

每一条打印进去的log, 后边都会随着一个工夫,这个工夫是怎么计算出来的呢?

首先,咱们要晓得,调试器是通过 createDebug 函数 生成的进去的;

其次,createDebug 函数 执行的返回值是一个名为debug的函数(实际上,这个就是一个闭包了);

最初是,在这个debug函数中,通过变量prevTime变量curr, 在配合 Number(new Date()) 就能够算出这个工夫了。

实际上,这个工夫就是同一个调试器(或者说是调试语句,就是debug函数)调用的时间差,例子能够参考我的案例:index1.js

commonJs:

function setup {    // ....    function createDebug (namespace) {        let prevTime;        // ...                function debug(...args) {                        const self = debug;                        // Set `diff` timestamp            const curr = Number(new Date());            const ms = curr - (prevTime || curr);            self.diff = ms;            self.prev = prevTime;            self.curr = curr;            prevTime = curr;                    }        return debug    }    // ...    return createDebug;}module.exports = setup;

格式化是怎么事实的呢? 格式化的扩大是怎么实现的呢?

common.js:

    // ···    // ···    if (typeof args[0] !== 'string') {        // Anything else let's inspect with %O        args.unshift('%O');    }    // Apply any `formatters` transformations    let index = 0;    args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {        // If we encounter an escaped % then don't increase the array index        if (match === '%%') {            return '%';        }        index++;        const formatter = createDebug.formatters[format];        if (typeof formatter === 'function') {            const val = args[index];            match = formatter.call(self, val);            // Now we need to remove `args[index]` since it's inlined in the `format`            args.splice(index, 1);            index--;        }        return match;    });    // ···    // ···

browser.js:

const {formatters} = module.exports;/** * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. */formatters.j = function (v) {    try {        return JSON.stringify(v);    } catch (error) {        return '[UnexpectedJSONParseError]: ' + error.message;    }};

node.js:

const {formatters} = module.exports;/** * Map %o to `util.inspect()`, all on a single line. */formatters.o = function (v) {    this.inspectOpts.colors = this.useColors;    return util.inspect(v, this.inspectOpts)        .split('\n')        .map(str => str.trim())        .join(' ');};/** * Map %O to `util.inspect()`, allowing multiple lines if needed. */formatters.O = function (v) {    this.inspectOpts.colors = this.useColors;    return util.inspect(v, this.inspectOpts);

参考:

  • https://www.npmjs.com/package...
  • https://juejin.cn/post/684490...

社交信息 / Social Links:

(Welcome to pay attention, 欢送关注)

Github:@huangyangquang
微信公众号:前端学长Joshua