1.前端工程化-使用自定义的console loader 增强控制台打印功能
2.领导被我的花式console.log吸引了!直接写入公司公共库!
3.Console 模块解读及简单实现
4.如何在浏览器中进行js调试?
5.放弃 console.log 吧!用 Debugger 你能读懂各种源码
6.JavaScript(JS) console.log() 不显示文件名和行号的问题的解决方法
前端工程化-使用自定义的console loader 增强控制台打印功能
在前端开发中,随着项目规模的扩大,对console.log的我要养鸡源码需求变得更加强大,期望能在控制台直接定位到详细且具体的代码位置,而无需频繁切换源码。为此,本文将介绍如何利用webpack进行自定义开发,增强console.log的功能。
首先,了解前端工程化工具如webpack的工作原理,它们通过编译原理和Babel编译器将ES6以上的代码转化为浏览器可识别的ES5代码。在这个过程中,我们需要对AST(抽象语法树)进行操作,以实现console功能增强。
必备的工具包括Babel-core,它提供了处理AST的接口。工作流程包括定义输入(ES5的JS代码)、转换(使用Babel的API),以及输出增强后的console.log信息。理想情况是,输出内容应存储在控制台,而非直接打印,以避免代码文件过长时的不便。
设计的Loader流程如下:首先,书写Loader并配置其在webpack中的位置,确保在Babel-loader之后运行。Loader的输入为Babel编译后的ES5代码。转换部分,利用Babel的visitor模式,针对console表达式和其内容进行特定的修改。最后,处理输出,确保输出的代码格式符合预期。
具体实现时,rpc protocolproxy源码编写如下核心代码片段,通过遍历AST,找到console表达式和其参数,然后进行替换和格式化。整体代码结构设计需要考虑Loader的执行顺序,确保在所有其他处理之前完成console增强。
总结来说,通过自定义Webpack的Console Loader,我们可以实现一种直观且高效的开发环境,使开发者在控制台直接获取到准确的代码位置,提升了调试效率。
领导被我的花式console.log吸引了!直接写入公司公共库!
这几天代码评审,领导无意中看到了我本地代码的控制台,被我花里胡哨的console打印内容吸引了!
老板看见后,说我这东西有意思,花里胡哨的,他喜欢!
但是随即又问我,这么花里胡哨的东西,上生产会影响性能吧?我自信的说:不会,代码内有判断的,只有开发环境会打印!
老板很满意,于是让我给其他前端同事分享一下,讲解下实现思路!最终,这个方法还被写入公司的公用utils库里,供大家使用!
console 是一个用于调试和记录信息的内置对象, 提供了多种方法,可以帮助开发者输出各种信息,进行调试和分析。
console.log()用于输出一般信息,slide down源码大家应该在熟悉不过了。
console.info() 输出信息,与 console.log 类似,但在某些浏览器中可能有不同的样式。
console.warn() 输出警告信息,通常会以**背景或带有警告图标的样式显示。
console.error() 输出错误信息,通常会以红色背景或带有错误图标的样式显示。
console.table() 以表格形式输出数据,适用于数组和对象。
通过上述介绍,我们可以看出,原生的文本信息、警告信息、错误信息、数组信息打印出来的效果都很普通,辨识度不高!现在我们通过console.log来实现一些花里花哨的样式!
console.log() 可以接受任何类型的参数,包括字符串、数字、布尔值、对象、数组、函数等。最厉害的是,它支持占位符!
常用的占位符:
格式化字符串:console.log("Hello, %cWorld", "color: blue;")
添加样式:console.log("%cHello, World", "color: blue;")
自定义样式的实现,其实主要是靠%c 占位符添加 CSS 样式实现的!
我们创建一个prettyLog方法,用于逻辑编写
上述代码定义了一个 prettyLog 函数,用于美化打印信息到控制台。通过自定义样式,输出信息以更易读和美观的格式呈现。
我们使用一下看看效果
info 方法用于输出信息级别的日志。它接受两个参数:textOrTitle 和 content。如果只提供一个参数,tourex 6 源码则视为内容并设置默认标题为 Info;如果提供两个参数,则第一个参数为标题,第二个参数为内容。最后调用 prettyPrint 方法进行输出。
仅在开发环境使用
我们可以通过import.meta.env.MODE 判断当前环境是否为生产环境,在生产环境,我们可以禁用信息打印!
完整代码
作者:石小石Orz 链接: juejin.cn/post/...
推荐学习教程: 阿里大牛分钟精讲React全家桶让你从入门到精通(基础+进阶+实战+源码)
注:前端面试资料分享,八股文及场景题
有想要的朋友 —点此就可以了—(无偿分享)
Console 模块解读及简单实现
Console模块解读及简单实现
Console模块提供了简单的调试功能,适用于测试调试场景,功能类似于浏览器中的console,但在Node.js中,关于其同步与异步特性有所疑问。
本文通过参考官方源码,实现了一个简化版的Console模块,旨在介绍基本使用方法和常见问题,以供学习参考。
作者:五月君,Nodejs开发者,后技术爱好者,公众号「Nodejs技术栈」,开源项目请见/article/...
来源:慕课网
本文首发于慕课网,转载时请注明出处,感谢合作。
如何在浏览器中进行js调试?
如何在浏览器中进行js调试?
在生产环境中遇到线上bug无法复现时,需要在浏览器中进行js调试。在测试环境调试代码不靠谱,因此需要快速找出问题原因,避免直接改动线上代码。生产环境代码通常关闭了source map和经过混淆,接下来介绍如何在这些情况下进行调试。
一种方法是通过console找到源代码打断点。在浏览器控制台的console面板,找到由bug导致的报错信息或日志,点击文件名称跳转到源码位置,直接在代码中设置断点进行调试。ugui 源码分析
若点击文件名后出现错误,可以调整浏览器控制台设置,取消勾选“Enable JavaScript source maps”,重新点击文件名即可。此方法简便易行,但无法处理没有报错信息或难以在代码中插入log的情况。
另一种方法是利用network面板的Initiator找到源代码。将鼠标移至请求的Initiator,查看调用链中的方法和函数,找到离bug最近的接口请求,从而定位到所需方法或函数。混淆代码中函数和变量名称改变,但对象中的方法和属性名称保持不变。通过识别调用栈中的对象方法名称,可以快速定位源代码。
以一个例子说明,假设有一个service/common.js文件被业务组件调用。在Initiator调用栈中找到对应的getMessageList方法,并确定initData调用了该方法。在调用栈中,getMessageList方法之上即为源代码位置,点击文件名称即可跳转。
如果源代码被压缩,点击左下角的花括号恢复代码格式,对比混淆前后的代码,通常差异不大,便于进行调试。
另一种情况是bug位置没有接口请求。通过Initiator找到对应的源代码js文件,搜索已知的属性和方法名称,因为这些名称在混淆过程中不会改变,同样能定位到源代码。
总结:本文介绍了两种在线上进行js调试的方法。通过console找到源代码打断点或利用network面板的Initiator,快速定位和解决线上bug。希望本文能帮助您更有效地进行浏览器中的js调试。
放弃 console.log 吧!用 Debugger 你能读懂各种源码
很多同学不清楚为什么要使用debugger进行调试,难道console.log不行吗?
即使学会了使用debugger,还是有很多代码看不懂,如何调试复杂的源码呢?
这篇文章将为你讲解为什么要使用这些调试工具:console.log vs Debugger。
相信绝大多数同学都会使用console.log进行调试,将想查看的变量值打印在控制台。
这种方法可以满足基本需求,但遇到对象打印时就无法胜任了。
比如,我想查看webpack源码中的compilation对象的值,我尝试打印了一下:
但你会发现,当对象的值也是对象时,它不会展开,而是打印一个[Object] [Array]这样的字符串。
更严重的是,打印的内容过长会超过缓冲区的大小,在terminal中显示不全:
而使用debugger来运行,在这里设置一个断点查看,就没有这些问题了:
有些同学可能会说,那打印一个简单的值时使用console.log还是很方便的。
比如这样:
真的吗?
那还不如使用logpoint:
代码执行到这里就会打印:
而且没有污染代码,使用console.log的话,调试完成后这个console也不得不删除掉。
而logpoint不需要,它就是一个断点的设置,不在代码中。
当然,最重要的是debugger调试可以看到调用栈和作用域!
首先是调用栈,它就是代码的执行路线。
比如这个App的函数组件,你可以看到渲染这个函数组件会经历workLoop、beginWork、renderWithHooks等流程:
你可以点击调用栈的每一帧,查看都执行了什么逻辑,用到了什么数据。比如可以看到这个函数组件的fiber节点:
再就是作用域,点击每一个栈帧就可以看到每个函数的作用域中的变量:
使用debugger可以看到代码的执行路径,每一步的作用域信息。而你使用console.log呢?
只能看到那个变量的值而已。
得到的信息量差距不是一点半点,调试时间长了,别人会对代码的运行流程越来越清晰,而你使用console.log呢?还是老样子,因为你看不到代码执行路径。
所以,不管是调试库的源码还是业务代码,不管是调试Node.js还是网页,都推荐使用debugger打断点,别再用console.log了,即使想打印日志,也可以使用LogPoint。
而且在排查问题的时候,使用debugger的话可以加一个异常断点,代码跑到抛异常的地方就会断住:
可以看到调用栈来理清出错前都走了哪些代码,可以通过作用域来看到每一个变量的值。
有了这些,排查错误就变得轻松多了!
而你使用console.log呢?
什么也没有,只能自己猜。
Performance
前面说debugger调试可以看到一条代码的执行路径,但是代码的执行路径往往比较曲折。
比如那个React会对每个fiber节点做处理,每个节点都会调用beginWork。处理完之后又会处理下一个节点,再次调用beginWork:
就像你走了一条小路,然后回到大路之后又走了另一条小路,使用debugger只能看到当前这条小路的执行路径,看不到其他小路的路径:
这时候就可以结合Performance工具了,使用Performance工具看到代码执行的全貌,然后用debugger来深入每一条代码执行路径的细节。
SourceMap
sourcemap非常重要,因为我们执行的都是编译打包后的代码,基本是不可读的,调试这种代码也没有什么意义,而sourcemap就可以让我们直接调试最初的源码。
比如vue,关联了sourcemap之后,我们能直接调试ts源码:
nest.js也是:
不使用sourcemap的话,想搞懂源码,但你调试的是编译后的代码,怎么读懂呢?
读懂一行
前面说的debugger、Performance、SourceMap只是调试代码的工具,那会了调试工具,依然读不懂代码怎么办呢?
我觉得这是不可能的。
为什么这么说呢?
就拿react源码来说:
switch case能读懂吧。三目运算符能读懂吧。函数调用能读懂吧。
每一行代码都能读懂,而全部的代码不就是由这一行行代码组成的么?
加上我们可以单步执行来知道代码执行路径。
为啥每行代码都能读懂,连起来就读不懂了呢?
那应该是代码太多了,而你花的时间不够而已。
先要读懂一行,一个函数,读懂一个小功能的实现流程,慢慢积累,之后了解的越来越多之后,你能读懂的代码就会越多。
总结
这篇文章讲了为什么要使用调试工具,如何读懂复杂代码。
console.log的弊端太多了,大对象打印不全,会超过terminal缓冲区,对象属性不能展开等等,不建议大家使用。即使要打印也可以使用LogPoint。
使用debugger可以看到调用栈,也就是代码的执行路径,每个栈帧的作用域,可以知道代码从开始运行到现在都经历了什么,而console.log只能知道某个变量的值。
此外,报错的时候也可以通过异常断点来梳理代码执行路径来排查报错原因。
但debugger只能看到一条执行路径,可以使用Performance录制代码执行的全流程,然后再结合debugger来深入其中一条路径的执行细节。
此外,只有调试最初的源码才有意义,不然调试编译后的代码会少很多信息。可以通过SourceMap来关联到源码,不管是Vue、React的源码还是Nest.js、Babel等的源码。
会了调试之后,就能调试各种代码了,不存在看不懂的源码,因为每一行代码都是基础的语法,都是能看懂的,如果看不懂,只可能是代码太多了,你需要更多的耐心去读一行行代码、一个个函数、理清一个个功能的实现,慢慢积累就好了。
掌握基于debugger、Performance、SourceMap等调试代码之后,各种网页和Node.js代码都能调试,各种源码都能读懂!
JavaScript(JS) console.log() 不显示文件名和行号的问题的解决方法
在Chrome浏览器中,当你使用console.log()进行日志输出时,可能会遇到只有函数名或内存地址,如react_devtools_backend.js:,而缺失文件名和行号的情况。这种情况通常出现在开发者工具的默认设置中。为了解决这个问题,这里提供一种简单的解决方案。
首先,确保你已经在Chrome浏览器中启用了源映射功能。源映射允许浏览器将浏览器内的错误信息映射回实际的源代码。在开发者工具的设置中,进入“Sources”选项卡,找到并勾选“Map JavaScript sources”选项。这将启用源码的详细显示。
其次,检查你的console.log()是否在严格模式下执行。在严格模式下,console.log()可能会不显示行号。可以在代码前添加'`'(单引号)包裹,如`console.log()`,以防止严格模式的影响。
如果以上方法无效,你还可以尝试清理一下浏览器的缓存,或者检查是否有其他插件可能影响了console.log()的行为。如果问题依然存在,可能需要检查你的代码中是否有特殊的代码块或配置导致了这个问题,或者尝试更新到最新版本的Chrome浏览器。
通过上述步骤,你应该能够解决Chrome浏览器中console.log()不显示文件名和行号的问题,从而获得更清晰的错误定位信息。