logo
Published on

前端调试(一):调试入门

Authors

一、Chrome DevTools 原理

Chrome DevTools 采用客户端-服务端架构,核心组件包括:

  • Frontend:基于 Web 技术实现的调试界面(如 Elements、Console 面板)
  • Backend:集成在浏览器内核中的调试服务(Chromium/V8/Node.js)
  • CDP 协议:基于 JSON-RPC 的调试协议,支持双向通信(如发送Debugger.stepOver命令)
  • 信道:默认通过 WebSocket 传输协议数据
graph LR
  A[DevTools Frontend] -->|WebSocket| B[CDP 协议]
  B -->|IPC/Unix Socket| C[Browser Core]
  C -->|执行命令| D[页面运行时]

典型工作流程:

  1. 建立 WebSocket 连接(默认端口 9222)
  2. 前端发送 JSON 格式命令(如{"id":1,"method":"Page.navigate","params":{"url":"https://..."}}
  3. 浏览器内核执行命令并返回结果

二、VSCode Debugger

原理

在四要素基础上引入适配器层

graph TD
  A[VSCode UI] --> B[Debug Adapter Protocol]
  B --> C[Debug Adapter]
  C --> D[CDP/其他协议]
  D --> E[目标运行时]

关键特性:

  1. DAP 协议:通用调试协议,解耦 IDE 与具体语言调试器
  2. 适配器完成协议转换(如将 DAP 转换为 CDP)
  3. 支持多运行时调试(Node.js 通过--inspect启用 CDP 端点)
  4. 如果是别的调试工具只需要更改中间的适配层

配置项

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node", // 调试器类型(Node.js/Python等)
      "request": "launch", // 启动模式(launch: 直接运行 / attach: 附加到已运行进程)
      "port": 9229, // CDP 端口 attach时使用
      "url": "http://localhost:3000", // launch时开发服务器启动的URL
      "userDataDir": "${workspaceFolder}/.vscode/.debug", //用户数据一次只能被一个chrome实例访问,如果已经打开浏览器再开vscode调试就需要设置这个,为true代表临时,为false就是保持默认,VSCode保存调试信息的目录
      "name": "Launch Server", // 配置名称(显示在调试下拉菜单中)
      "program": "${workspaceFolder}/app.js", // 入口文件路径
      "args": ["--port", "3000"], // 传递给程序的命令行参数
      "cwd": "${workspaceFolder}", // 工作目录(${workspaceFolder}表示项目根目录)
      "runtimeExecutable": "canary", // 运行时环境(默认为 Node.js),可以指定其他浏览器,避免和常用浏览器冲突
      "runtimeArgs": ["--remote-debugging-port=9229"], // 启动chrome运行时参数(传递给运行时环境),--incognito无痕模式
      "env": {
        "NODE_ENV": "development", // 设置环境变量
        "DEBUG": "app:*"
      },
      "console": "integratedTerminal", // 使用VSCode内置终端(避免输入输出问题)
      "internalConsoleOptions": "neverOpen", // 不显示调试控制台
      "skipFiles": ["<node_internals>/**"], // 跳过调试第三方代码(如Node核心模块)
      "sourceMaps": true, // 启用源码映射(用于TypeScript等编译型语言)
      "preLaunchTask": "build", // 调试前执行的任务(需在tasks.json中定义)
      "outFiles": ["${workspaceFolder}/dist/**/*.js"], // 编译后文件位置(配合sourceMaps)
      "autoAttachChildProcesses": true, // 自动附加子进程(如用cluster启动的进程)
      "file": "${workspaceFolder}/src/index.ts", // launch时直接打开文件,vscode debugger提供静态服务器
      "pathMapping": {
        "/src": "${workspaceFolder}/src" // 路径映射(解决webpack打包后路径问题)
      },
      "sourceMapPathOverrides": {
        // 调试时编译后的代码要能通过sourcemap映射回源码
        "webpack:///./*": "${webRoot}/*" // 源码映射路径覆盖(解决webpack打包后路径问题)
      },
      "stopOnEntry": false // 启动时不自动断点
    }
  ]
}

三、调试实战

1.调试nodejs

可能需要搭配构建工具使用,也需要配置task.json预先执行命令

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "nodejs调试",
      "skipFiles": ["<node_internals>/**"], // 跳过调试第三方代码(如Node核心模块)
      "program": "${workspaceFolder}/index.js",
      "autoAttachChildProcesses": true,
      "preLaunchTask": "build"
    }
  ]
}

2.调试scripts

{
  "name": "scripts dev",
  "type": "node",
  "request": "launch",
  "runtimeExecutable": "npm",
  "runtimeArgs": ["run-script", "dev"],
  "skipFiles": ["<node_internals>/**"]
}