【前端调试】如何优雅调试vue

3,469 阅读3分钟

调试是在任何软件的源代码中查找和修复错误或 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一下,重新刷新拿到编译编译之后的路径如下

1.jpg

可以看到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/*"
            }
        },
    ]
}

重新进行调试,发现可以定位到本地源码中的位置了

2.jpg

但如果路径后面的hash变了怎么办?那不是又要改配置?

这个路径是可以配置的,webpack配置中提供了下面的属性供开发者自定义生成sourcemap路径

默认是:

config: {
    output: {
        devtoolModuleFilenameTemplate: 'webpack://[namespace][resource-path]?[loaders]')
    }
}

把它修改为:

config: {
    output: {
        devtoolModuleFilenameTemplate: '前端调试://[resource-path]')
    }
}

// 或者

config.output.set('devtoolModuleFilenameTemplate', '前端调试://[resource-path]')

3.jpg 然后修改一下VsCode中的映射路径:

"sourceMapPathOverrides": {
	"前端调试://src/*": "${workspaceRoot}/src/*"
}

重新编译后进行调试,可以看到sourcemap的路径已经修改了我们自定义的

4.jpg 同时vsCode的断点生效,也会自动定位到本地源码位置

5.jpg 普通调试方式就介绍到这里,但还存在一些问题,比如我们调试的项目是需要登录权限的,需要手动登录;亦或者是在开发某些功能时,需要填写一大部分表单才去到我们需要调试的页面,太麻烦了,有没有办法取消前摇呢,直接去到指定页面触发调试?

答案是接下来要介绍的第二种方式,通过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

1.gif

是不是非常的方便?可以手动修改puppeteer逻辑满足指定场景。

登录逻辑启动一次就行了,之后都是挂起的状态,puppeteerattach始终保持连接状态,这时候可以调试任意代码,比如点击按钮,在导出函数中添加断点。

6.jpg

点击导出按钮

7.jpg

触发断点

9.jpg 以上就是Vue中调试本地源码的方法,不仅能快速定位问题,还能够通过调试堆栈看到Vue源码,学习工作两不误!

8.jpg

当然如果使用react,会更加简单,不用进行路径映射即可开启调试。