Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node CLI 开发调试技巧总结 #2

Open
younth opened this issue Mar 24, 2018 · 5 comments
Open

Node CLI 开发调试技巧总结 #2

younth opened this issue Mar 24, 2018 · 5 comments

Comments

@younth
Copy link
Owner

younth commented Mar 24, 2018

最近这段时间一直在折腾各种Node CLI,把个人的一些开发,调试技巧分享给大家~

一般情况下,一套CLI工具集合,包括CLI运行核心模块及各种插件体系。拿 webpack 来说,其由核心模块 webpack 及各种 loader plugin 组成其强大的构建生态体系。

单一NPM包的调试

npm link 到本地进行开发调试

  • 先进入模块目录执行 npm link
  • 再去项目目录通过包名来 link npm link my-plugin
  • 删除link: npm unlink my-plugin

npm link 的原理其实就是建立软连接,省去了自己建立软链的麻烦了

单一的npm包,调试方法比较多,vscode node-debug 或者 chrome devtool 调试node 都可以。如果是vscode ,launch.json 里面可以配置 env 与 args 也比较方便。单一模块开发推荐这种方式。

{
    "type": "node",
    "request": "launch",
    "name": "Launch Program",
    "program": "${workspaceRoot}/bin/node-cli.js",
    "args": [
        "-v"
    ],
    "env": {
        "PLUGIN_CORE_PATH": "/Users/younth/node/node-cli"
    }
}

入口CLI的开发调试

入口cli模块一般是在 package.json 里面申明的:

"bin": {
    "webpack": "./bin/webpack.js"
}

bin 字段主要用于npm i -g时候可以将脚本添加到可执行路径中,之后可以在命令行中直接执行。例如npm i -g webpack后就可以全局使用webpack命令。

同样的我们在 CLI 的项目目录下执行 npm link 将 webpack 放入全局,这样后面我们就可以在命令行中直接使用了。对于CLI模块的调试仍然可以使用单一模块调试方法。

但是当 webpack 再去调用 loader 或者 plugin 的时候,我们想完整的调试整个过程,就不太方便了。尝试过用 node --debug 去启动 CLI 下面的 bin/webpack ,然后在调试具体执行模块,感觉开发起来很别扭,体验不好。而且如果是模块是通过child\_process.spawn 执行的,那真就没啥办法了。最终选择了以日志的形式进行开发调试。

说起日志,最简单的就是 console.log 调试了,但问题也很明显:

  • 模块本身需要输出一些信息,需要做到debug信息在正常启动模式下是不显示的
  • 涉及模块越来越多的时候,console 输出的信息会多而乱。这样增加了调试的复杂度,迫切需要 进行分模块块打印日志调试

我们引入了 debug 模块。使用也非常方便,通常我们只需要给每个模块指定特定的__命名空间__即可:

// app.js
var debug = require('debug')('app');

// 运行 DEBUG=app node app.js
// 输出:app hello
debug('hello');
debug('this is %s', string);
debug('this is %o', obj);

使用的时候,可以传参,自定义格式:

  • %s: string
  • %o: object

debug 同时支持命名空间:

  • DEBUG=app,api:表示同时打印出命名空间为app、api的调试日志。
  • DEBUG=a\*:支持通配符,所有命名空间为a开头的调试日志都打印出来。

关于守护程序(daemon)模块的调试

在开发Node Cli的过程中,我们经常需要执行一些 后台程序 , 比如 检测CLI及模块的版本更新情况,其本质就是利用 child\_process.spawn 以守护进程的方式执行一个js文件。我们可以通过设定 spawnstdout 参数来将输出指向某个文件。

const fs = require('fs-extra');
let stdout = fs.openSync(path.join(__dirname, 'check_out.log'), 'w')
let stderr = fs.openSync(path.join(__dirname, 'check_error.log'), 'w')
const p = child_process.spawn(
  'node', ['check.js', 'a', 'b'],
  {
    'stdio': ['ignore', stdout, stderr],
    'detached': true   // 让子进程能在父进程退出后继续运行
  }
);

如上述代码所示,在 check.js 里面进行 console.log 或者 debug 的,将会在 check\_out.log 里面看到结果。

正式环境的日志显示

以上都是开发时候的调试,在发布之后,有时候我们也需要一些信息输出给用户。我们经常用 --verbose 查看详细的运行情况。对于正式环境的错误提示,信息输出等,我们把日志级别分为:

  • verbose:详细日志,一般是通过 --verbose 参数查看
  • info:日常的输出
  • warn:警告日志
  • error:错误日志
  • debug:  这里不需要了,因为debug已经单独拿出来用 debug模块进行输出

可以考虑用原生util模块,这里推荐使用 npmlog ,功能也比较完善。

// additional stuff ---------------------------+
// message ----------+                         |
// prefix ----+      |                         |
// level -+   |      |                         |
//        v   v      v                         v
    log.info('[core]', 'node version is : %j', nodeVersion)

其他小技巧

有时候我们也想让自己的CLI输出各种酷炫的效果,这里也把自己使用的模块分享给大家:

最近也在梳理前端工程化的全链路开发的解决方案,看了业界很多工具,慢慢融化贯通后再尝试分享。

@younth younth changed the title NodeCLI 开发调试技巧总结 Node CLI 开发调试技巧总结 Mar 24, 2018
@cike8899
Copy link

vscode debug是需要F5启动的,但是往往cli程序是在命令行里输入并带有参数的,比如:webpack --env.platform=web,请问在vscode里打断点能拿到后面的命令行参数吗?

@younth
Copy link
Owner Author

younth commented Mar 29, 2018

@cike8899 这个问题是调试中比较常见的,终端直接输入cli命令,且带参数,这时候用vscode调试是不方便的。目前我都是用 debug 输出日志调试。如果一定要断点调试,不能直接终端执行 webpack 需要用 node --debug ./bin/webpack 这种形式启动webpack

@wython
Copy link

wython commented Dec 1, 2020

可以

@Been101
Copy link

Been101 commented Feb 19, 2021

适用 vscode 断点调试时, 有时有交互的输入, 这种情况下,断点是进不去的,这怎么解决。
例如 创建项目的 cli, 会让你输入项目相关的数据(项目名, 描述之类的)

@Been101
Copy link

Been101 commented Feb 19, 2021

适用 vscode 断点调试时, 有时有交互的输入, 这种情况下,断点是进不去的,这怎么解决。
例如 创建项目的 cli, 会让你输入项目相关的数据(项目名, 描述之类的)

找到方法了, 添加 console 配置可以解决

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants