美文网首页
Nodejs 调试代码二

Nodejs 调试代码二

作者: dkvirus | 来源:发表于2019-10-16 13:40 被阅读0次

前文介绍了 Nodejs 调试代码的原理,本文讲解几个调试案例加深下理解,使用的是 Vscode 调试器客户端。

调试 Express 代码

初始化 express 工程。

$ mkdir express-demo
$ cd express-demo
$ npm init -y
$ npm install express

创建 index.js 文件,内容如下:

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

app.get('/', (req, res) => {
    const a = 1
    const b = 2
    const c = a + b
    res.end(`a + b = ${c}`)
})

app.listen('3000', function () {
    console.log('服务器已启动,端口', 3000)
})

方法一:request: launch

参考前文 Vscode 调试,添加配置文件如下:

// .vscode/launch.json
{
    "type": "node",
    "request": "launch",
    "name": "Express launch",
    "program": "${workspaceFolder}/index.js"
}

express 项目有个入口文件 index.js,平时启动服务需要输入 $ node index.js,调试的时候使用内置的调试器程序启动 index.js。

request: "launch" 表示使用调试器程序启动 index.js 文件。

方法二:request: attach

正常启动 Express 服务。

图1

此时突然想调试某个接口,如果使用 launch 方式,需要 Ctrl + C 停掉当前服务,然后用调试器程序重新执行 index.js。但是现在不想重启服务,又要对代码进行调试,可以使用 attach 方式。

添加调试配置文件如下。

// .vscode/launch.json
{
    "type": "node",
    "request": "attach",
    "name": "Express attach",
    "processId": "${command:PickProcess}",
    "port": 9229
}
  • request: "attach" 表示 Nodejs 程序已经在运行着,待会启动调试器程序,去关联这个已经运行的 Nodejs 程序;
  • processId: "${command:PickProcess}" 进程ID,后面花括弧里的东东不用管,意思当你点击 Vscode 调试面板绿色箭头(下图红字1)时会弹出一个下拉框让你选择:调试器程序关联哪一个正在运行的 Nodejs 程序(下图红字2)。
图2

我的机器上起了好几个 Nodejs 程序,跑 express-demo 的是第二个 Nodejs 程序,点击之后再看看终端,会打印一些新的消息,其中 Debugger attached 表示调试器程序已经和正在运行的 Nodejs 程序关联起来了。

图3

此时在 Vscode 中的源码里打个断点,在浏览器中访问 localhost:3000 可以看到进入断点了。

图4

调试 nodemon 代码

还是👆上面 Express 的例子,你会发现改动代码不会立即生效,需要重启服务才行。
第三方包 nodemon 可以监听文件变化,自动重启服务。(supervisor 包作用相同)

全局安装 nodemon:

$ npm install nodemon -g

修改 package.json 的 scripts 属性

"scripts": {
    "dev": "nodemon index.js"
}

此时执行 npm run dev 即可启动服务,修改 index.js 代码,会发现服务自动重启。

对于 Nodemon 启动的 Express 如何调试呢?

Vscode 打开调试配置,点击 Add Configuration(红字1),选择 Nodemon Setup(红字2)。

图5

Vscode 会自动生成一份调试配置文件。(program 属性默认入口文件为 app.js,这里改成我们的 index.js)

{
    "type": "node",
    "request": "launch",
    "name": "nodemon",
    "program": "${workspaceFolder}/index.js",
    "runtimeExecutable": "nodemon",
    "restart": true,
    "console": "integratedTerminal",
    "internalConsoleOptions": "neverOpen"
}

上面配置文件中前四个属性都有介绍过,这里主要介绍后四个属性的含义。

runtimeExecutable

使用哪个命令运行脚本,这里是 nodemon,启动调试器相当于执行 nodemon index.js。如果没有写 runtimeExecutable 这个属性,它的默认值为 "node"。

这里的 nodemon 需要全局安装,这样在环境变量 PATH 中才能找到该命令。

restart

加上这个配置,修改代码,调试器才会重启。

console

启动调试器后,会打印一些信息,如:调试器服务端监听哪个端口,调试器客户端是否连接上等。

console 配置有三个值,分别设置在什么地方打印这些信息:

  • integratedTerminal:Vscode 集成终端中打印信息,下图 Terminal 选项窗;
  • internalConsole:Vscode 里的调试控制台中打印信息,下图 Debug Console 选项窗;(改成这个吧~)
  • externalTerminal:打开系统自带的终端打印信息;
图6

internalConsoleOptions

internalConsole 即 Vscode 中的 Debug Console,在👆介绍 console 配置时已经介绍过了,internalConsoleOptions 设置是否自动打开 Debug Console 选项窗。

  • neverOpen:不会自动跳转到 Debug Console 选项窗,但是可以手动点击切换到 Debug Console 选项窗;
  • openOnSessionStart:即便当前在 Terminal 选项窗,当进行调试时,会自动跳转到 Debug Console 选项窗。
  • openOnFirstSessionStart:下同;

调试 Typescript 代码

上面👆Express 代码都是用原生 js 写的,如果用 Typescript 来写 Express 代码,如何调试呢?

调试之前,先要搭建 Typescript + Express 开发环境,参见 环境搭建

src 目录放 ts 写的代码;
dist 目录放编译后的 js 代码。

前面已经介绍过在 Vscode 中调试 js 代码,但是 ts 编译成的 js 代码丑陋无比,如下:

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var express_1 = __importDefault(require("express"));
var app = express_1.default();
app.get('/', function (req, res) {
    res.send('Hello Ts Express  dd ee ff');
});
app.listen(3000, function () {
    console.log('Server is running.');
});
//# sourceMappingURL=app.js.map

这导致我们想直接在 ts 文件上打断点,而非在 js 文件上打断点,如何做到这一点,是接下来的重点。

打开 Vscode 调试配置文件:

{
    "type": "node",
    "request": "launch",
    "name": "Launch Program",
    "program": "${workspaceFolder}/src/app.ts",
    "runtimeExecutable": "nodemon",
    "restart": true,
    "preLaunchTask": "tsc: build - tsconfig.json",
    "outFiles": ["${workspaceFolder}/dist/**/*.js"]
}

前面 6 个属性都介绍过,只有最后两个属性是陌生的。

preLaunchTask

在调试器启动入口文件之前执行这个任务,这里的任务是 tsc: build,即编译操作,将 src 目录下的 *.ts 文件编译成 *.js 文件;最终,调试器执行的还是 js 文件而非 ts 文件。

问题来了,调试器咋知道你编译后的 js 文件放在那里呢?下面👇属性 outFiles 告诉它的。

outFiles

该属性告诉调试器执行的 js 文件在哪个目录下,上面例子编译后的 js 文件都放在 dist 目录下。

既然调试器执行的是 js 代码,为什么我们可以在 ts 文件中打断点呢?

tsconfig.json 中有个配置项 sourceMap,当设置为 true 时,在 *.ts 文件编译成 *.js 文件时,会顺带生成 *.js.map 文件,这个文件将 *.ts 和 *.js 文件关联起来了,所以可以在 ts 文件打断点。

相关文章

  • Nodejs 调试代码二

    前文介绍了 Nodejs 调试代码的原理,本文讲解几个调试案例加深下理解,使用的是 Vscode 调试器客户端。 ...

  • vscode使用指南(代码调试)

    代码调试 vscode 原生支持nodejs的调试,其他语言需要安装拓展支持调试 代码调试界面 调试界面 调试配置...

  • 调试 nodejs 代码

    2016年,Node 决定将 Chrome 浏览器的”开发者工具”作为官方的调试工具,使得 Node 脚本也可以使...

  • NodeJS(二):NodeJS 调试

    1 通过命令行,打开谷歌控制台 上面代码,--inspect-brk 指定在第一行就设置断点。也就是说,一开始运行...

  • Nodejs 调试代码一

    很长一段时间,调试 Nodejs 代码都是通过在代码里写 console.log() 进行的。在 infoq 上看...

  • mongo-express 远程代码执行漏洞分析

    搭建调试环境,调试 CVE-2019-10758 漏洞,学习nodejs 沙箱绕过,以及nodejs 远程调试。目...

  • vscode 配置 nodejs 调试环境

    vscode 配置 nodejs 调试环境 解决 1 侧边栏 调试按钮 添加 nodejs 配置 launch.j...

  • vscode 单步调试 nodejs 代码

    纯nodejs的后台代码(即,不通过浏览器运行,仅跑在命令行上的nodejs程序),可以通过vscode的debu...

  • nodejs· 工具链 · webstorm调试代码

    一、增加webstorm的JavaScript Debug设置 1.输入Name名称 2.输入URL信息和项目的真...

  • node.js 调试

    这两天折腾出了一些nodejs的调试方法,做个记录 断点调试 nodejs官方指定的调试工具是chrome,在使用...

网友评论

      本文标题:Nodejs 调试代码二

      本文链接:https://www.haomeiwen.com/subject/umaymctx.html