我们在使用webpack打包的时候,一般会将代码压缩混淆。
好处是可以减少代码体积,但坏处是如果打包后报错(比如在测试环境),通过点击console的堆栈跳到代码处,会发现一堆代码无换行杂糅一起,基本无法调试。
解决办法chrome浏览器已经提供了,以阿里巴巴的矢量图标库为例。
会发现中间区域的代码明显是压缩混淆之后的。
格式化代码很简单,如图箭头指向的地方,点一下:
然后原本的js文件被一个文件后加了:formatted
的文件所替代,代码行数从23行变成了600多行如下图:
这个文件替代了原文件。
点击console的报错,或者在这里打断点,都是可以正常生效的。
建议自己试试,试完后理解起来很简单。
控制台输入:
debug(函数名)
效果:在执行某个函数的时候,自动触发断点。
但这个其实不实用,原因有几点:
示例代码:
<script>
function test () {
console.log('test')
let foo = function () {
console.log('foo')
}
foo()
}
test()
script>
<button onclick="test()">点击执行testbutton>
debug(test)
,再刷新页面,调试不会生效;debug(test)
,点击按钮,会触发调试;debug(foo)
,会报错foo is not defined
;<script>
function test () {
this.foo = function foo () {
console.log('foo')
}
this.foo()
}
let bar = new test()
script>
<button onclick="test()">点击执行testbutton>
输入debug(bar.foo)
,然后点击按钮,会触发断点。
所以还是推荐打debugger
来进行指定代码的调试。
简单来说,就是指调试的时候,如果需要进入某个js文件,那么不再进入,而是Sources
面板保持在在进入之前的位置和离开该文件后的位置。
举个简单的例子,当我们调试需要调用jQuery的代码时,由于jQuery代码一般是压缩混淆后的最小化代码,阅读困难,所以进入其代码内往往是没有意义的。
那么我们就可以通过这个办法让调试器在执行jQuery源码的时候,面板不进入(当然,实际还是在执行的),停留在进入之前的js文件。
步骤说明:
0、原文的方法,在我实测的时候,不可行,如果有人可以重现原文方法,请联系我的QQ:20004604,我会对本文进行订正;
0.5、建立2个文件,一个html(名字随便起),一个js文件(我这里随便起了一个2.js
的名字);
1、打开Source面板,右键js文件,复制文件链接(如下图):
2、打开settings面板,如图:
3、在settings面板内,如下操作:
4、然后将之前复制的链接粘贴进去,点击【add】按钮:
5、两个文件的内容如下:
// html文件
<html lang="en">
<head>
<script src="2.js">script>
head>
<body>
<script>
function bar () {
console.log('bar')
}
foo()
script>
<button onclick="foo()">点击执行foobutton>
body>
html>
// 2.js
function foo () {
console.log('foo')
debugger
bar()
}
会发现2.js
中的debugger是无效的。但是如果给2.js
文件打断点,执行foo()
或者点击按钮执行foo()
时,断点会停留在html文件中,不会切换到js文件。
示例:
console.log('%c%s', 'color:red', '红色字体')
这个在Python等语言里有,如果没接触过类似语法可能比较难理解。建议大家先复制以上代码到控制台看看效果。
简单来说,有点类似str.replace()
的替换。
%c
,被认为是样式描述符,如果输入color:red
,那么console的结果会被变为红色;%s
,被认为是字符串,因此显示的文字是红色字体
;console.log
一共有三个参数,第一个是显示内容,有两个%
运算符,第二个参数会被匹配到第一个%
运算符,第三个参数会被匹配到第二个%
运算符;再举几个例子:
console.log('第一个字符串:%s,第二个字符串%s', 'foo', 'bar')
// 第一个字符串:foo,第二个字符串bar
console.log('第一个字符串:%s,第二个字符串%s', 'foo')
// 第一个字符串:foo,第二个字符串%s
console.log('第一个字符串:%s,第二个字符串%s', 'foo', 'bar', 'baz')
// 第一个字符串:foo,第二个字符串bar baz
%
运算符可以直接和普通字符串拼接;%
运算符会被认为是普通字符串(即%s
);console.log('bar', 'baz')
这样的原因;
%
运算符不完全解释;
运算符 | 匹配要求 | 效果 | 和要求不匹配时效果 |
%c | 对应css样式 | 用css样式修饰log(部分css无效,比如height和动画) | 错误的样式不生效,不影响其他正常的 |
%s | 字符串 | 将字符串替换到该位置 | 正常显示 |
%d | 数字(必须number类型) | 格式化为整数显示 | 非number类型则NaN(包括’123’这样的字符串) |
%f | 浮点数(必须number类型) | 可以显示浮点数(但类似%1f只显示一位小数的设置无效) | 非number类型则NaN |
示例代码:
console.log('%c效果展示', 'font-size:100px;color:red;border:10px solid green;border-radius:30px;')
console.log('%s%s%s', '---', '效果展示', '---')
console.log('整数:%d', 123.45)
console.log('浮点数:%f', 123.45)
这个和【断点某函数】存在同样的问题,你必须首先在控制台拿到该函数,才能实现,如果拿不到,或者很复杂的话,那么就特别不实用了。
示例代码(将这个直接输入到下面):
function foo (a, b, c) {
console.log(arguments)
}
monitor(foo)
foo(1, 2)
效果如图:
jQuery的美元符选择器很好用,但如果没引用jQuery的话,做起来就很麻烦。
但浏览器的控制台自带类似jQuery的选择器语法,可以拿取DOM。
(css−selector)//返回单个DOM元素 $(css-selector) // 返回数组
示例代码:
// html文件
<html lang="en">
<body>
<div id="foo">div>
<div class="bar">div>
body>
html>
// 控制台输入
$("#foo")
$$("#foo")
$(".bar")
$$(".bar")
效果如下图:
注意,可以理解为document.querySelector()
和document.querySelectorAll()
,但是返回数组的那个不一样。
因为$$()
返回的是[object Array]
,而document.querySelectorAll()
返回的是[object NodeList]
。
不过这个好像也没什么意义喔。
略略略,chrome貌似不行。
前端很多时候就是玩DOM,所以有时候我们需要关心DOM什么时候被改变(移除),或者修改。
先上HTML代码:
<html lang="en">
<body>
<script>
function remove () {
document.querySelector('.bar').remove()
console.log('remove')
}
script>
<button id="foo" onclick="remove()">移除barbutton>
<div class="bar">bardiv>
body>
html>
然后如图做:
这个的效果就是当DOM被移除时,自动断点,且断点位置是DOM移除时的那一行代码(移除前最后一步)。
需要控制台保持在Elements
标签下才可触发断点!
点击按钮移除,会发现自动触发断点(注意右边,bar这个HTML元素还在):
在Break on...
的三个选项中:
1、第一个是DOM树改变,如下代码,当#bar
添加了一个新的子元素(包括孙元素)时,或者子元素被移除时,就会触发断点:
<html lang="en">
<body>
<script>
function add () {
let DOM = document.createElement('a')
DOM.innerHTML = '123'
document.querySelector('#baz').appendChild(DOM)
}
script>
<button id="foo" onclick="add()">添加一个孙标签button>
<div id="bar">
<div id="baz">div>
div>
body>
html>
注意,当前DOM被移除时不会触发这一个事件
2、第二个是:当DOM属性更改,自动触发断点。
例如添加了一个class呀,之类之类的,都可以触发,代码如下:
<html lang="en">
<body>
<script>
function add () {
document.querySelector('#bar').classList.add('foo')
}
script>
<button id="foo" onclick="add()">添加一个classbutton>
<div id="bar">div>
body>
html>
先打断点,然后点击按钮添加一个新的class类,就会触发断点效果了。