最近这段时间一直在折腾各种 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/def.js",
- "args": [
- "-v"
- ],
- "env": {
- "DEF_CORE_PATH": "/Users/younth/node-cli/def/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: 表示同时打印出命名空间为 appapi 的调试日志
DEBUG=a\*: 支持通配符, 所有命名空间为 a 开头的调试日志都打印出来
关于守护程序 (daemon) 模块的调试
在开发 Node Cli 的过程中, 我们经常需要执行一些 后台程序 , 比如 检测 CLI 及模块的版本更新情况, 其本质就是利用
child\_process.spawn
以守护进程的方式执行一个 js 文件我们可以通过设定 spawn 的 stdout 参数来将输出指向某个文件
- 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 输出各种酷炫的效果, 这里也把自己使用的模块分享给大家:
CLI 各种颜色输出: colors chalk
CLI 输出表格: cli-table easy-table
CLI emoji 输出: node-emoji
持续更新...
最近也在梳理前端工程化的全链路开发的解决方案, 看了业界很多工具, 慢慢融化贯通后再尝试分享
来源: https://juejin.im/post/5ab612f6f265da237d02f669