乐趣区

关于前端:如何使用-VS-Code-调试-Vuejs-项目

简介

此教程会以一个全新的 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
  • code 是 VS Code 自带的命令,如果你运行时提醒没有此命令,能够看这里设置一下。
  • debug-vuejs-project-with-vscode 是我的项目名称。

生成 sourcemap 文件

Vite

如果是通过 create-vue 创立的我的项目,则批改 vite.config.ts 配置文件,在开发环境生成 sourcemap 文件。

export default defineConfig({
  build: {sourcemap: true,},
  // other configs...
});

更多配置,请参考:https://vitejs.dev/config/build-options.html#build-sourcemap

Vue Cli

如果是通过 vue-cli 创立的我的项目,则批改 vue.config.js 配置文件,在开发环境生成 sourcemap 文件。

module.exports = {
  configureWebpack: {devtool: "source-map"}
  // other configs...
};

更多配置,请参考:https://cli.vuejs.org/guide/webpack.html

Webpack

如果是本人搭建的我的项目,则批改本人定义的 webpack 配置文件,在开发环境生成 sourcemap 文件。

module.exports = {
  devtool: "source-map",
  // other configs...
};

更多配置,请参考:https://webpack.js.org/configuration/devtool/#devtool

配置文件

launch.json

通过如下步骤,创立 launch.json 配置文件(如果你的我的项目中曾经存在该文件,则可跳过此步骤)

  1. 抉择左侧菜单中的 Debug icon,关上调试菜单。
  2. 点击 create a launch.json file,创立一个新的配置文件。
  3. 抉择 Web App(Edge),当然,你也能够抉择 Web App(Chrome)

生成的 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"
    }
  ]
}

下面的配置中,有以下几点须要留神:

  • type:VS Code 的 Debug 类型。

    • msedge 的意思是应用 Edge 浏览器进行调试。
    • chrome 的意思是应用 Chrome 浏览器进行调试。
  • url:浏览器启动时拜访的地址。

    • 须要改为你我的项目的开发环境地址,如果统一则无需批改。
  • preLaunchTask:设置进入 debug 环境之前须要执行的工作。

    • 此名称对应我的项目中 .vscode 目录下 tasks.json 文件中的 label 属性。
    • tasks.json 文件上面会创立。

更多信息:

  • 对于 launch.json 文件的更多配置,请参考:

    • https://code.visualstudio.com/docs/editor/debugging#_launchjson-attributes

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,则该命令将被解释为要执行的过程。

更多信息:

  • 对于 tasks.json 文件的更多配置,请参考:

    • https://code.visualstudio.com/docs/editor/tasks#_custom-tasks
    • https://code.visualstudio.com/docs/editor/tasks-appendix
  • 对于 VS Code tasks 性能,更多信息,请参考:

    • https://code.visualstudio.com/docs/editor/tasks

打断点

咱们将 src/views/AboutView.vue 文件的内容略微改一下,而后打两个断点。

<script lang="ts" setup>
import {reactive, ref} from "vue";

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);
};
</script>

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <div>
      <p>{{count}}</p>
      <button @click="handlePlus">plus</button>
      <button @click="handleMinus">minus</button>
      <hr style="margin: 20px 0" />
      <p v-for="item of other" :key="item.name">
        {{item.name}}: {{item.age}}
      </p>
    </div>
  </div>
</template>

在第 13 行和 第 19 行,别离打了 2 个断点(在对应行号右边,点击鼠标左键即可打断点):

注意事项

须要留神的是:肯定要在启动 Debug 前打好断点,否则你将无奈匹配到断点。

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

我猜想的起因是:因为 *.vue 这种 SFC 格局的文件,须要将 scripttemplatestyle 这 3 个模块拆分编译,理论运行的是编译后的 js 文件,而且每次文件批改或者重启我的项目之后,都会编译出新的文件。

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

弹窗提醒

另外,我发现:不论是否提前打了断点,在启动时都会提醒:

The task ‘xxx’ cannot be tracked. Make sure to have a problem matcher defined。

我搜了一下,临时没有找到特地完满的解决方案,这里提供两种糟糕的办法:

计划一:

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

计划二:

把 launch.json 文件中的 preLaunchTask 属性去掉,Debug 之前本人手动启动我的项目,反正配置 preLaunchTask 的目标就是主动帮你把我的项目启动起来,所谓本人入手饥寒交迫。

启动 Debug

通过上述配置之后,就能够通过 Debug 模式启动我的项目了,咱们来别离介绍一下「快捷键」和「手动启动」这 2 种启动形式。

快捷键:F5

如果你的我的项目只有 1 个 Debug 配置的话,能够间接通过 F5 快捷键启动 Debug 模式,十分的简略不便,举荐日常应用。

手动启动

如果你的我的项目有多个 Debug 配置,launch.json 文件的 configurations 数组有多个配置对象。

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

能够看到,点击「下拉菜单」之后,展现了 2 个配置选项:vuejs: msedgevuejs: chrome

示例中 launch.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 的环境配置好了,当初能够开始欢快的调试了。

一些问题

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

在开始说这些问题之前,咱们先看一下这张图:

  • 标注 1:是咱们的代码源文件。
  • 标注 2:是运行时命中断点后,VS Code 主动关上的编译后的文件。

    • 他的名字也有可能是:AboutView.vue?t=1661699383436
    • 有一个 t 参数,是一个毫秒工夫戳,应该是防止缓存的。
  • 标注 3:是第一个断点,行号是 13。
  • 标注 4:是第二个断点,行号是 19。

1. 必须先打断点

咱们能够看到,在运行过程中,其实断点命中是编译后的文件。

后面咱们提到,在运行 Debug 模式之后再去源文件中增加新断点,失常状况下是无奈匹配的。

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

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

此办法的弊病是:他是个一次性的断点。

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

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

此办法的弊病是:须要手动触发编译。

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

我每次触发从新编译的形式是,轻易在某个中央增加一行 console.log(""),而后每次间接批改打印的内容即可。

2. 断点地位不统一

源文件和编译后的文件断点的行号统一,然而对应的行号却是不同的代码,和咱们预期的断点地位不统一:

比照之后能够看出,@vue/compiler-sfc 主动将 <script setup> 语法糖转换为了 Composition API 格调代码,并且增加了一些辅助代码。

这就导致单纯的依据行号映射断点地位会有些问题,呈现了无奈预知的错位状况。

我目前的解决方案是,手动在对应的地位加上 debugger,确保可能肯定命中在我想要的地位上。

而后在命中断点后的编译文件中,加上其余想要的新断点。

3. 改变后会编译出新文件

后面曾经提到过,在每次批改完源文件后,都会编译出新的文件。这就导致之前在编译文件中的断点全副生效。

一顿调试之后,VS Code 中会有大量的有效断点标记,虽说不影响应用,然而看起来有拍板大。

我临时没有什么好的解决方案,所以只能在每次调试完结之后,点击「Remove All Breakpoints」按钮,移除所有断点。

以上就是我遇到的一些问题,如果你有好的解决方案,能够在评论区告知一下,比心 ❤️。

本文首发于:https://github.com/mrlmx/blogs/issues/3,如果喜爱,记得去点个赞哦~ 👍

参考

  • https://vuejs.org/guide/quick-start.html
  • https://github.com/Microsoft/VSCode-recipes/tree/master/vuejs-cli
退出移动版