美文网首页
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 调试代码二

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