mrlmx / blogs

limingxin's blog
11 stars 0 forks source link

如何使用 VS Code 调试 Vue.js 项目? #3

Open mrlmx opened 2 years ago

mrlmx commented 2 years ago

Yellow Duck

简介

此教程会以一个全新的 Vue.js 项目作为模板进行配置,你可以跟随教程一步步操作,也可以按照教程将配置添加到已有的项目中。

仓库地址:https://github.com/mrlmx/debug-vuejs-project-with-vscode

创建项目

通过 vue 提供的 create-vue 脚手架,创建一个 vue3 项目。

npm init vue@latest

注意:通过上述命令,创建的是基于 vite 的项目,而不是基于 webpack 的项目。

然后在 VS Code 中打开创建后的项目:

code ./debug-vuejs-project-with-vscode
  1. 选择左侧菜单中的 Debug icon,打开调试菜单。
  2. 点击 create a launch.json file,创建一个新的配置文件。
  3. 选择 Web App(Edge),当然,你也可以选择 Web App(Chrome)

image.png

生成的 launch.json 文件大致长这样(不同版本的 VS Code 可能略有不同):

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "pwa-msedge",
            "request": "launch",
            "name": "Launch Edge against localhost",
            "url": "http://localhost:8080",
            "webRoot": "${workspaceFolder}"
        }
    ]
}

将生成的 launch.json 文件内容,替换为下方配置:

{
  "version": "0.2.0",
  "configurations": [
    {
      // 使用 Edge 浏览器调试
      "type": "msedge",
      // 使用 Chrome 浏览器调试
      // "type": "chrome",

      "request": "launch",
      "name": "vuejs: msedge",

      // 项目的访问地址(需要改成你项目开发环境对应的地址和端口号)
      "url": "http://localhost:5173",

      "webRoot": "${workspaceFolder}",
      "pathMapping": {
        "/_karma_webpack_": "${workspaceFolder}"
      },
      "sourceMapPathOverrides": {
        "webpack:/*": "${webRoot}/*",
        "/./*": "${webRoot}/*",
        "/src/*": "${webRoot}/*",
        "/*": "*",
        "/./~/*": "${webRoot}/node_modules/*"
      },

      // 设置进入 debug 环境之前需要执行的任务。
      // 此名称对应项目中 .vscode 目录下 tasks.json 文件中的 label 属性)
      "preLaunchTask": "vuejs: start"
    }
  ]
}

上面的配置中,有以下几点需要注意:

更多信息:

tasks.json

在项目的 .vscode 目录创建 tasks.json 文件,然后将下方内容粘贴进去:

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "vuejs: start",
      "type": "npm",
      // 需要执行的命令(对应于 package.json 中的 scripts 命令)
      "script": "dev",
      "isBackground": true
    }
  ]
}

上面的配置在执行时,运行的命令是:npm run dev,如果你的项目是其他的启动命令,那么修改为对应的 script 名称即可。

注意:type 的其他可选值是 shell 或者 process,可不要傻乎乎的改成 yarn

type:任务的类型。对于自定义任务,可以设置为 shellprocess

  • 如果设置为 shell,则该命令将被解释为 shell 命令(例如:bash、cmd 或 PowerShell)。
  • 如果设置为 process,则该命令将被解释为要执行的进程。

更多信息:

const other = reactive([ { name: "lmx", age: 18 }, { name: "foo", age: 20 }, { name: "bar", age: 12 }, ]); const count = ref(0);

const handlePlus = () => { console.log("plus before", count.value); count.value++; console.log("plus after", count.value); };

const handleMinus = () => { console.log("minus before", count.value); count.value--; console.log("minus after", count.value); };


在第 **13** 行和 第 **19** 行,分别打了 2 个断点(在对应行号左边,点击鼠标左键即可打断点):
![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/05d844d4fde141c082cfb64109307903~tplv-k3u1fbpfcp-zoom-1.image)
### 注意事项

需要注意的是:一定要在启动 Debug 前打好断点,否则你将无法匹配到断点。

启动之后,在源文件中添加新的断点是无效的,运行中的编译文件无法匹配到新的断点,除非修改源文件的代码触发编译,这样新生成的编译文件才会映射到新断点。

我猜测的原因是:因为 `*.vue` 这种 SFC 格式的文件,需要将`script`,`template`,`style`这 3 个模块拆分编译,实际运行的是编译后的 js 文件,而且每次文件修改或者重启项目之后,都会编译出新的文件。

如果不提前打断点,那么源文件和编译后的文件将不会关联上。

### 弹窗提示
另外,我发现:不管是否提前打了断点,在启动时都会提示:
> The task 'xxx' cannot be tracked. Make sure to have a problem matcher defined。

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fdb08579f993410fad0baad0a422b880~tplv-k3u1fbpfcp-zoom-1.image)
我搜了一下,暂时没有找到特别完美的解决方案,这里提供两种蹩脚的方法:

**方案一:**

如果你不在意这个提示的话,可以每次都点击一下「Debug Anyway」按钮,或者勾选一下「Remember my choice for this task」,以后每次运行的时候就不会提示了,所谓眼不见心不烦。

**方案二:**

把 launch.json 文件中的 `preLaunchTask` 属性去掉,Debug 之前自己手动启动项目,反正配置 `preLaunchTask` 的目的就是自动帮你把项目启动起来,所谓自己动手丰衣足食。
## 启动 Debug
经过上述配置之后,就可以通过 Debug 模式启动项目了,咱们来分别介绍一下「快捷键」和「手动启动」这 2 种启动方式。
### 快捷键:F5
如果你的项目只有 1 个 Debug 配置的话,可以直接通过 `F5` 快捷键启动 Debug 模式,非常的简单方便,推荐日常使用。

![image222.jpg](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/21ab905530844ec7902c39a2fc4044d7~tplv-k3u1fbpfcp-zoom-1.image)
### 手动启动
如果你的项目有多个 Debug 配置,launch.json 文件的 `configurations` 数组有多个配置对象。

这个时候 `F5` 快捷键启动的就是第一个配置,如果你想要启动其他 Debug 配置,就需要通过手动选择了。

可以看到,点击「下拉菜单」之后,展示了 2 个配置选项:`vuejs: msedge` 和 `vuejs: chrome`
![截屏2022-08-30 00.43.56(2).png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ce17fc8556574aa8b55d3eb05931e1e5~tplv-k3u1fbpfcp-zoom-1.image)
示例中 launch.json 配置文件的内容是这样的:
```json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "msedge",
      "request": "launch",
      "name": "vuejs: msedge",
      "url": "http://localhost:5173",
      "webRoot": "${workspaceFolder}",
      "pathMapping": {
        "/_karma_webpack_": "${workspaceFolder}"
      },
      "sourceMapPathOverrides": {
        "webpack:/*": "${webRoot}/*",
        "/./*": "${webRoot}/*",
        "/src/*": "${webRoot}/*",
        "/*": "*",
        "/./~/*": "${webRoot}/node_modules/*"
      },
      "preLaunchTask": "vuejs: start"
    },
    {
      "type": "chrome",
      "request": "launch",
      "name": "vuejs: chrome",
      "url": "http://localhost:5173",
      "webRoot": "${workspaceFolder}",
      "pathMapping": {
        "/_karma_webpack_": "${workspaceFolder}"
      },
      "sourceMapPathOverrides": {
        "webpack:/*": "${webRoot}/*",
        "/./*": "${webRoot}/*",
        "/src/*": "${webRoot}/*",
        "/*": "*",
        "/./~/*": "${webRoot}/node_modules/*"
      },
      "preLaunchTask": "vuejs: start"
    }
  ]
}

看到这里,你应该已经把 debug 的环境配置好了,现在可以开始愉快的调试了。

一些问题

在我写这篇文章的过程中,也发现了几个让我头痛的问题,这里顺带提一下。

在开始说这些问题之前,咱们先看一下这张图: iShot2022-09-12 11.51.16.png

前面我们提到,在运行 Debug 模式之后再去源文件中添加新断点,正常情况下是无法匹配的。

那如果我在调试过程中,想要添加新断点该怎么办呢?

方法 1: 直接在「编译后的文件」中打新断点。

此方法的弊端是:他是个一次性的断点。

因为新断点是针对这个编译文件的,如果源文件改动后,会重新编译出新的文件,那么这个断点将会失效,后续将不会被匹配到。

方法 2: 直接在「源文件」中打新断点。

此方法的弊端是:需要手动触发编译。

前面也提到过,在源文件中添加新断点之后,运行中的编译文件是无法感知到的,所以必须让源文件触发重新编译,生成新的编译文件,这样源文件的所有断点就会同步映射到新的编译文件中了。

我每次触发重新编译的方式是,随便在某个地方添加一行 console.log(""),然后每次直接修改打印的内容即可。

2. 断点位置不一致

源文件和编译后的文件断点的行号一致,但是对应的行号却是不同的代码,和我们预期的断点位置不一致: IMG_6354.JPEG 对比之后可以看出,@vue/compiler-sfc 自动将 Githubissues.

  • Githubissues is a development platform for aggregating issues.