IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 每天一个npm包 之 debug -> 正文阅读

[JavaScript知识库]每天一个npm包 之 debug

每天一个npm包 之 debug

介绍:

这是一个模仿 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')
}

// …elsewhere
const 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 namespace
const logSign = log.extend('sign');
const logLogin = log.extend('login');

log('hello'); // auth hello
logSign('hello'); //auth:sign hello
logLogin('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 false
2 true
3 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/debug
  • https://juejin.cn/post/6844903601395990541

社交信息 / Social Links:

(Welcome to pay attention, 欢迎关注)

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

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-24 11:20:57  更:2021-07-24 11:21:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/6 16:22:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码