Nodejs debug调试

ㅤㅤㅤ
ㅤㅤㅤ
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ(有些梦想,纵使永远也没办法实现,纵使光是连说出来都很奢侈。但如果没有说出来温暖自己一下,就无法获得前进的动力。——九把刀)
ㅤㅤㅤ
ㅤㅤㅤ
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ在这里插入图片描述

什么是debug

  • 名字的由来

一位名叫葛丽丝·霍波(Grace Hopper)的美国海军准将及计算机科学家,同时也是世界最早的一批程序设计师之一。有一天,她在调试设备时出现故障,拆开继电器后,发现有只飞蛾被夹扁在触点中间,从而“卡”住了机器的运行。于是,霍波诙谐的把程序故障统称为“臭虫(BUG)”,把排除程序故障叫DEBUG

  • debug的本质

Debug是一种程序,一种调试工具,说白了就是供程序员检查修改问题的工具

为什么需要debug

  • 调试是定位软件瑕疵的最直接和最有效的方法 。没有哪个程序员能一下子写出没有错误的代码.而使用以调试器为主的调试工具进行调试是定位瑕疵的最直接方法 , 可以从问题的症状入手, 正向跟踪或者反向追溯。对于大多数瑕疵 , 使用合适的调试方法可 以大大提高定位到问题根源的效率 。今天的软件环境在不断向着大型化 、 并行化、 复杂 化 方向发展 , 定位瑕疵的难度也在随之不断提高。 完全靠读源代码来寻找 b u g 的方法已经很难适应今天的软件发展形势 。 另外 , 枚举和排除法通常也会因系统中的软硬件模块数量太多而难以实施 , 有时候 , 花了几天时间来做替换仍然找不 到怀疑对象
  • 调试可以帮助程序员提高编写代码的能力。 因为调试可以让程序员彻底了解程 序的实际执行过程 , 检查与自己设计时的预想是否一致 , 如果不一致 , 那么很可能预示 着有问题存在 , 应该引起重视 。 另外 , 调试过程可以让程序员更好的认识到提高代码可调试性和代码质量的重要性 。 从此 , 自觉的改进编码方式 , 合理添加用来支持调试的代码 。编码和调试是程序员日常工作中的两个最主要任务 , 这两个任务是相辅相成的 , 编写具有可调试性的高质量代码 , 可以明显提高调试效率 , 节约调试时间。 另 一方面 , 调试可以让程序员真切感受程序的实际执行过程 , 反思编码和设计中的问题 , 加深对软件和系统的理解 , 提高对代码的感知力和控制力
  • 调试工具是学习计算机系统和其它软硬件知识的好帮手 。通过软件调试技术的强大观察能力和断点、 栈回溯 、 跟踪等功能可以快速的了解一个软件和系统的模块 、 架构 、和工作流程 , 因此是学习其它软硬件技术的一个快速而有效的方法

Nodejs的debug

  1. debugger关键字 调试器

使用node启动时带上 inspect参数运行,我们可以看到一些提示符,证明调试器已经启动成功

在这里插入图片描述

如果我们将debugger关键字放入代码中,则会在该代码中的该位置启用一个断点

global.x = 5;
setTimeout(() => {
  debugger;
  console.log('world');
}, 1000);
console.log('hello');
命令名称 命令描述 命令快捷键
cont 继续执行 c
next 单步执行下一行 n
step 单步进入 s
out 单步退出 o
backtrace 打印当前执行框架的回溯 bt
pause 暂停运行中的代码(累死开发者工具中的暂停按钮)
repl 打开调试器的repl以在调试脚本的上下文中进行评估
list(5) 列出具有5行上下文的脚本源代码(前后5行)
watch(expr) 将表达式添加到监视列表
unwatch(expr) 从监视列表中删除表达式
watchers 列出所有观察者及其值(在每个断点处自动列出)
exec expr 在调试脚本的上下文中执行表达式

在这里插入图片描述
2. Chrom Dev Tools 调试器

  • V8 Inspector集成允许将Chrome DevTools附加到Node.js实例以进行调试和分析,它使用Chrom DevTools 协议
  • –inspect启动Node.js应用程序时可以通过传递标志来启用V8检查器。也可以为自定义端口提供该标志,例如,–inspect=9222将接受端口9222上的DevTools连接

以简易的nodejs http服务为例 debugger.js

const http = require('http');

http.createServer((req, res) => {
  const str = 'Dev Tools Nodejs'
  res.end(str);
}).listen(3000);

然后我们使用node --inspect debugger.js,如果需要在应用程序的第一行就终端,则使用–inspect-brk即可

在这里插入图片描述

由于我们监听了3000端口号,故我们在浏览器使用localhost:3000访问,并打开chrom开发者界面,可以看到

在这里插入图片描述

我们点击它,可以看到如下的Chrom Dev Tools界面

在这里插入图片描述

我们再重新访问,可以看到

在这里插入图片描述

对于前端开发者来说,可能更倾向于使用浏览器来进行调试
但对于大多数开发者来说,编写JS类代码,更多的是使用vscode
更多Chrom Dev Tools 相关技巧可以查看https://chromedevtools.github.io/devtools-protocol/

  1. vscode 调试器 ㅤversion 1.4.5

在下面的演示中,使用了VS Code中文插件
https://marketplace.visualstudio.com/items?itemName=MS-CEINTL.vscode-language-pack-zh-hans

Visual Studio Code的主要功能之一是其强大的调试支持。VS Code的内置调试器有助于加速您的编辑,编译和调试循环,引用以下官方的图

在这里插入图片描述

  • 启动配置

可以使用快捷键F5或者在.vscode下创建lauch.json文件
 
并且VS Code将尝试自动检测您的调试环境,但是如果失败,则必须手动选择它,在这里我们选择生成nodejs配置文件

在这里插入图片描述

以node express为例

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  const example = 'hello express ~~'
  res.end(example);
});

app.listen('3000', () => {
  console.info('connect to 3000 success ~');
});

vscode launch.json变量配置表说明

字段名称 字段描述
type 用于此启动配置的调试器的类型。每安装调试扩展引入一个类型:node用于内置节点调试器
request 此启动配置的请求类型。当前,launch并且attach受支持
name 在调试启动配置下拉列表中显示的易于阅读的名称
presentation 使用order,group和hidden在属性
presentation 可以排序,在调试配置下拉菜单,并在调试组,和隐藏的构造和化合物快速挑选对象
preLaunchTask 要在调试会话开始之前启动任务,请将此属性设置为task.json(在工作区的.vscode文件夹中)指定的任务的名称。或者,可以将其设置${defaultBuildTask}为使用默认的构建任务
postDebugTask 在调试会话结束时启动任务,请将此属性设置为task.json(在工作区的.vscode文件夹中)指定的任务名称
internalConsoleOptions 此属性控制调试会话期间“调试控制台”面板的可见性
debugServer 仅适用于调试扩展作者:此属性允许您连接到指定的端口,而不必启动调试适配器
serverReadyAction 如果要调试的程序在调试控制台或集成终端上输出特定消息时,要在Web浏览器中打开URL
program 启动调试器时要运行的可执行文件或文件
args 参数传递给程序进行调试
env 环境变量(该值null可用于“取消定义”变量)
cwd 当前工作目录,用于查找依赖关系和其他文件
port 连接到正在运行的进程时的端口
stopOnEntry 程序启动时立即中断
console 什么样的控制台来使用,例如internalConsole,integratedTerminal或externalTerminal

vscode会自动识别当前调试环境,自动生成launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "启动程序",
      "skipFiles": [
        "<node_internals>/**"
      ],
      "program": "${workspaceFolder}/app.js"
    }
  ]
}

然后我们使用该配置文件运行

在这里插入图片描述

vscode调试动作
在这里插入图片描述

  • 继续/暂停F5
  • 越过F10
  • 进入F11
  • 移出Shift + F11
  • 重新启动Ctrl + Shift + F5
  • 停止Shift + F5
  • 断点表达式
  1. 在程序代码中编辑debug断点

它只是临时将表达式添加在代码中,达到开发者更方便的调试代码的目的
它由菱形”形状的图标表示,且有表达式的断点可以看到有一个双横杠在这里插入图片描述

在这里插入图片描述

就像常规断点一样,可以启用或禁用对数点,也可以通过条件和/或命中数进行控制

  1. 在debug控制面板中调试断点和堆栈

变量可以在“ 运行”视图的“ 变量”部分中检查,也可以将鼠标悬停在编辑器中的源上进行检查。变量值和表达式评估相对于“ 调用堆栈”部分中的选定堆栈帧

在这里插入图片描述

可以使用变量的上下文菜单中的“ 设置值”操作来修改变量值
相比较在代码中调试断点,在控制面板,我们可以更清晰的看到程序执行的堆栈信息

  1. 在输出控制台下进行调试

可以使用Debug Console REPL(Read-Eval-Print Loop)功能对表达式求值。要打开调试控制台,请使用“ 调试”窗格顶部的“ 调试控制台”操作,或使用“ 查看:调试控制台”命令(Ctrl + Shift + Y)。按下Enter键后,将对表达式求值,而Debug Console REPL将在您键入时显示建议。如果需要输入多行,请在各行之间使用Shift + Enter,然后使用Enter发送所有行以进行评估。调试控制台输入使用活动编辑器的模式,这意味着调试控制台输入支持语法着色,缩进,自动关闭引号和其他语言功能

在这里插入图片描述

vscode中的nodejs调试扩展

详情可以参见官网

https://code.visualstudio.com/docs/nodejs/nodejs-debugging

vscode调试 typescript

VS Code具有对TypeScript调试的内置支持。为了支持结合执行中的JavaScript代码调试TypeScript

  • 使用tsc编译执行
  1. 先安装typescript
npm install -g typescript
  1. 查看tsc版本
tsc --version
  1. 编写ts文件 app.ts
import * as express from 'express';
const app = express();

app.get('/', (req: any, res: { end: (arg0: string) => void; }) => {
  const example = 'hello express ~~'
  
  res.end(example);
});

app.listen('3000', () => {
  console.info('connect to 3000 success ~');
});

  1. 使用tsc将app.ts编译成js文件
tsc app.ts
  1. 由于已经编译成了js文件,此时我们可以使用node命令运行
"use strict";
exports.__esModule = true;
var express = require("express");
var app = express();
app.get('/', function (req, res) {
    var example = 'hello express ~~';
    res.end(example);
});
app.listen('3000', function () {
    console.info('connect to 3000 success ~');
});

node app.js

在这里插入图片描述

  • 指定tsc配置进行编译
  1. 创建tsconfig.json文件并进行简单的配置

该文件定义了TypeScript 项目设置,例如编译器选项和应包含的文件

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "outDir": "out"
  }
}
  • target 指定ECMAScript目标版本
  • module 指定模块代码生成类型
  • outDir 将输出结构重定向到目录
  1. 使用tsc命令自动编译当前文件下和子文件夹下的所有ts文件,如果没有被排查的话
tsc

在这里插入图片描述

更多typescript.json配置请查看官方了解

使用ts-node执行typescript文件

  • ts-node

提供typescript的及时编译,缩短开发阶段的开发时间

npm install -g ts-node

ts-node -v

  • 工作原理

ts-node的工作方式是注册打字稿编译器.tsx?和.jsx?(当allowJs == true)扩展。当node.js注册有一个扩展名(通过require.extensions)时,它将在内部使用该扩展名进行模块解析。当node.js未知扩展名时,它将以.js(JavaScript)处理该文件。
默认情况下,ts-node避免使用/node_modules/以下三种原因来编译文件:

  • 模块应始终以node.js的格式进行运行
  • 编译整个依赖关系树会使您的项目变慢
  • TypeScript和node.js(例如ES2015模块)之间的不同行为可能会导致项目正常运行,直到您决定从node.js本地支持功能

这意味着,如果您不注册扩展名,它将被编译为JavaScript。当ts-node与一起使用时allowJs,将使用TypeScript编译器来翻译JavaScript文件

  • 加载tsconfig.json

使用ts-node时将会自动加载tsconfig.json。使用–skip-project跳过加载tsconfig.json。
相对于–dir使用与相同的搜索行为可以解决tsc。在–script-mode中,这是包含脚本的目录。否则,它是相对于解析的process.cwd(),与的行为相匹配tsc。
使用–project指定的路径tsconfig.json,将忽略–dir。

可以ts-node与tsconfig-paths一起使用,根据paths加载tsconfig.json模块

  1. 使用ts-node命令运行ts文件
ts-node app.ts

在这里插入图片描述
2. 使用ts-node调试ts文件

  • 配置tsconfig.json
{
  "compilerOptions": {
    "target": "es2017",
    "module": "commonjs",
    "outDir": "out"
  }
}
  • 配置launch.json
{
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Launch Program",
      "runtimeArgs": [
        "-r",
        "ts-node/register"
      ],
      "args": [
        "${workspaceFolder}/app.ts"
      ]
    }
  ]
}
  • 使用F5或者vscode调试面板启动

在这里插入图片描述


vscode调试egg.js

mkdir showcase && cd showcase
npm init egg --type=ts
npm i
npm run dev

在这里插入图片描述

  • 配置tsconfig.json(egg脚手架已自动生成)
{
  "compileOnSave": true,
  "compilerOptions": {
    "target": "es2017",
    "module": "commonjs",
    "strict": true,
    "noImplicitAny": false,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "charset": "utf8",
    "allowJs": false,
    "pretty": true,
    "noEmitOnError": false,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "allowUnreachableCode": false,
    "allowUnusedLabels": false,
    "strictPropertyInitialization": false,
    "noFallthroughCasesInSwitch": true,
    "skipLibCheck": true,
    "skipDefaultLibCheck": true,
    "inlineSourceMap": true,
    "importHelpers": true
  },
  "exclude": [
    "app/public",
    "app/views",
    "node_modules*"
  ]
}

  • 使用vscode调试eggjs的四种方式
  1. F1开启vscode的自动进程附加,然后在端输入npm run debug开启调试

在这里插入图片描述

  1. 使用egg官方推荐的launch.json配置启动debug调试
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Launch Egg",
      "type": "node",
      "request": "launch",
      "cwd": "${workspaceRoot}",
      "runtimeExecutable": "npm",
      "windows": { "runtimeExecutable": "npm.cmd" },
      "runtimeArgs": [ "run", "debug" ],
      "console": "integratedTerminal",
      "protocol": "auto",
      "restart": true,
      "port": 9229,
      "autoAttachChildProcesses": true
    }
  ]
}

在这里插入图片描述

  1. 使用vscode插件vscode-eggjs生成的launch.json启动debug调试

在这里插入图片描述

选择egg自动配置launch.json

在这里插入图片描述

生成的配置如下

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Egg Debug",
      "runtimeExecutable": "npm",
      "runtimeArgs": [
        "run",
        "debug",
        "--",
        "--inspect-brk"
      ],
      "console": "integratedTerminal",
      "restart": true,
      "protocol": "auto",
      "port": 9229,
      "autoAttachChildProcesses": true
    },
    {
      "type": "node",
      "request": "launch",
      "name": "Egg Test",
      "runtimeExecutable": "npm",
      "runtimeArgs": [
        "run",
        "test-local",
        "--",
        "--inspect-brk"
      ],
      "protocol": "auto",
      "port": 9229,
      "autoAttachChildProcesses": true
    },
    {
      "type": "node",
      "request": "attach",
      "name": "Egg Attach to remote",
      "localRoot": "${workspaceRoot}",
      "remoteRoot": "/usr/src/app",
      "address": "localhost",
      "protocol": "auto",
      "port": 9999
    }
  ]
}

使用F5或者debug控制面板启动

在这里插入图片描述

  1. 使用vscode的JavaScript Debugger插件启动

在这里插入图片描述

选择启动的npm脚本

在这里插入图片描述

  • 开启愉快的debug调试之旅~

在这里插入图片描述

关于vscode和egg调试多进程issue

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章