调试是在任何软件的源代码中查找和修复错误或 bug 的过程。
如何使用VsCode优雅调试Vue项目
默认情况下,vue项目有以下几种调试方式:
- 意念调试,赌哪里存在问题?或者看代码找问题
console.log打印日志- 通过
Chrome devtools debugger进行调试 - 通过
VsCode debugger调试
不同调试方式的效率有所不同,从上往下效率依次提高。
由于Vue使用的是SFC模式,通过vue-loader编译为不同的文件,默认VsCode是无法进行调试的,需要对路径做映射处理,才能找到源码位置。
下面介绍两种调试技巧。
普通调试
创建一个launch.json调试配置,新增sourceMapPathOverrides配置,这是vsCode提供用于映射sourcemap路径的,意思是将编译之后的webpack路径映射为本地源码路径。
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "调试指定vue页面",
"url": "http://localhost:5000",
"sourceMapPathOverrides": {
// 路径映射
}
},
]
}
如何获取映射地址呢?
通过在源码中debugger一下,重新刷新拿到编译编译之后的路径如下
可以看到list.vue是webpack编译之后的路径webpack://old-admin-[name]/src/pages/recharge/balanceAdjust/list.vue?7560,后面还带有hash串,这个地址就是需要映射的地址,将其映射到本地源码src目录下,那不就可以进行本地调试了吗?
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "调试指定vue页面",
"url": "http://localhost:5000",
"sourceMapPathOverrides": {
// 路径映射
"webpack://old-admin-[name]/src/*?7560": "${workspaceRoot}/src/*"
}
},
]
}
重新进行调试,发现可以定位到本地源码中的位置了
但如果路径后面的hash变了怎么办?那不是又要改配置?
这个路径是可以配置的,webpack配置中提供了下面的属性供开发者自定义生成sourcemap路径
默认是:
config: {
output: {
devtoolModuleFilenameTemplate: 'webpack://[namespace][resource-path]?[loaders]')
}
}
把它修改为:
config: {
output: {
devtoolModuleFilenameTemplate: '前端调试://[resource-path]')
}
}
// 或者
config.output.set('devtoolModuleFilenameTemplate', '前端调试://[resource-path]')
然后修改一下
VsCode中的映射路径:
"sourceMapPathOverrides": {
"前端调试://src/*": "${workspaceRoot}/src/*"
}
重新编译后进行调试,可以看到sourcemap的路径已经修改了我们自定义的
同时
vsCode的断点生效,也会自动定位到本地源码位置
普通调试方式就介绍到这里,但还存在一些问题,比如我们调试的项目是需要
登录权限的,需要手动登录;亦或者是在开发某些功能时,需要填写一大部分表单才去到我们需要调试的页面,太麻烦了,有没有办法取消前摇呢,直接去到指定页面触发调试?
答案是接下来要介绍的第二种方式,通过puppeteer自动化完成前摇工作。
Puppeteer自动断点
Puppeteer是一个Node.js库,它提供了一个高级API来通过DevTools协议控制Chrome/Chromium,简单点说就是能够在网页上做的操作,Puppeteer都能够用脚本的方式来代替执行。
以web端为例,通过puppeteer完成自动登录并且进入指定页面触发断点,怎么做呢?
安装puppeteer,建议使用v16.xNode.js版本。
npm install puppeteer -D
新建puppeteer.js,通过puppeteer.launch启动浏览器,并且通过debuggingPort属性开启调试端口,后面可以通过VsCode attach模式来连接这个端口。
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: false,
defaultViewport: {
width: 0,
height: 0
},
debuggingPort: 9999
});
})();
接下来实现以下操作,自动填写账号密码,登录成功之后跳转到指定vue页面,触发mounted的断点
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: false,
defaultViewport: {
width: 0,
height: 0
},
debuggingPort: 9999
});
const inputMap = {
'login': (page) => login(page)
}
const page = await browser.newPage()
inputMap['login']?.(page)
})();
// 登录调试运营端页面
async function login(page) {
await page.goto('http://localhost:5000/login');
await page.waitForSelector('#login_username');
const $username = await page.$('#login_username');
await $username.type('xxxxx', {
delay: 100
});
const $password = await page.$('#login_password');
await $password.type('xxxxx', {
delay: 100
});
const $checkbox = await page.$('input[type="checkbox"]')
if ($checkbox) {
await $checkbox.click();
}
const $button = await page.$('button[type="submit"]');
await $button.click();
// 等待登录成功后再跳转
await page.waitForNavigation()
// 调试指定页面
page.goto('http://localhost:5000/micro-admin/main/recharge/balanceAdjust');
}
在VsCode中通过attach监听9999端口
{
"version": "0.2.0",
"configurations": [
// 绑定指定Chrome的端口进行断点调试
{
"name": "监听puppeteer",
"port": 9999,
"request": "attach",
"type": "chrome",
"sourceMapPathOverrides": {
"前端调试://src/*": "${workspaceRoot}/src/*"
}
}
}
启动调试,运行node puppeteer.js,看看效果~
注意
puppeteer不支持Node v12.x版本,我这里用的是v16.x
是不是非常的方便?可以手动修改puppeteer逻辑满足指定场景。
登录逻辑启动一次就行了,之后都是挂起的状态,puppeteer和attach始终保持连接状态,这时候可以调试任意代码,比如点击按钮,在导出函数中添加断点。
点击导出按钮
触发断点
以上就是
Vue中调试本地源码的方法,不仅能快速定位问题,还能够通过调试堆栈看到Vue源码,学习工作两不误!
当然如果使用react,会更加简单,不用进行路径映射即可开启调试。