作者: Jim Wang 公众号: 巴博萨船长

摘要:在使用Hexo部署自己的博客时,常常接触hexo generater,hexo clean和hexo deploy等命令,估计很少人想过如何调试Hexo这些命令的相关代码。作为基于Node的开源blog项目,其在VS Code中的调试环境是什么样的?如何建立这样的调试环境?调试时需要注意什么? 在VSCode调试Node代码时,可能会遇见方法process.stdout.write和方法console.log的输出内容不在同一位置的问题,该问题如何解决?

Abstract: When using hexo to deploy the blog, often use commands such as hexo generator, hexo clean and hexo deploy. Few people have thought about how to debug the Hexo codes related to these commands. As a node-based open source blog project, what is its debugging environment in VS Code? How to build a debugging environment for debugging Hexo code? What should pay attention to when debugging? When debugging Node code in VS Code, the output content of process.stdout.write and console.log are not in the same location, why? How to solve the problem?

背景

按理说,日常Hexo的使用是不需要考虑代码调试的。一般情况下使用到的Hexo版本也是经过充分测试才发布的正式版本。可能还会有一些隐藏的小问题,但也足以应对日常使用。能想起来调试Hexo的相关代码,完全是出于好奇,想知道hexo deploy命令运行时到底做了些什么,hexo deploy背后的具体流程是什么,如何将项目中的README.md文件在部署时同时被拷贝到**.deploy_git**目录中,进而部署到Github中。带着这些问题,花费了点时间尝试之后,现将调试环境的部署方式记录下来,以便自己以后回顾学习。

方法一

VS Code 编辑器对Node的调试环境做了很大的优化和支持。实际应用中,需要自己做的是很少的,在VS Code中运行调试的设置都在launch.json这个配置文件中。VS Code也为Node项目提供了多配置模版snippets(点击按钮Add Configuration…即可看见配置模版列表),在方法一中我们先选择一个“Launch Program”的模版,基本的配置内容如下:

1
2
3
4
5
6
7
8
9
10
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch",
"program": "${workspaceRoot}/index.js"
}]
}

其中重要的参数request的取值和基本区别如下,两者的应用场景差异的具体细节不是本文重点,就不在本文中进行详细解释。

  • launch 模式:VS Code会启动一个独立的具有debug模式的程序。
  • attach 模式:用于监听一个已经启动的程序。

由于我们选择的是Lauch Program的配置模版,其request的参数默认为launch,该模式也是我们本文中使用的。在添加相应的内容之后,就可以在VS Code中,调试诸如hexo deploy的命令相关代码。接下来,只需要在Javascript文件“./node_modules/hexo-deployer-git/lib/deployer.js”中合适的位置添加断点,然后启动该配置,就可以看到程序在断点停留。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug Hexo Deploy Direct",
"cwd": "${workspaceFolder}",
"runtimeArgs": [
"--nolazy" // 强制V8引擎完成代码的编译工作,这在远程调试时比较有用,可选
],
"program": "./node_modules/hexo-cli/bin/hexo",
"args": [
"deploy",
"--debug" //设置Hexo的 log基本,以便输出更多的日志内容
],
"console": "internalConsole",
"outputCapture": "std"
}
]
}

方法二

我们也可以选择使用“Launch via npm”的模版,选用这个配置模版后会得到以下配置内容。npm作为node第三方依赖模块的管理工具,用npm运行js文件和node运行js文件的差异,我们不在本文中进行讨论。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"version": "0.2.0",
"configurations": [{
"name": "Launch via NPM",
"request": "launch",
"runtimeArgs": [
"run-script",
"debug"
],
"runtimeExecutable": "npm",
"skipFiles": [
"<node_internals>/**"
],
"type": "pwa-node"
}]
}

以上述模版信息为基础,修改添加一些选项后,我们得到以下配置内容。使用该配置内容,也能完成调试环境的搭建。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug Hexo Deploy via npm",
"cwd": "${workspaceFolder}",
"runtimeExecutable": "npm",
"runtimeArgs": [
"run", "deploy"
],
"console": "internalConsole",
"outputCapture": "std"
}
]
}

上述配置中的runtimeArgs配置项中的deploy参数,意指Hexo项目的配置文件package.json中的scripts配置项目中的deploy,参见下列内容:

1
2
3
4
5
6
7
8
9
10
11
12
{
"name": "hexo-site",
"version": "0.0.0",
"private": true,
"scripts": {
"build": "hexo generate",
"clean": "hexo clean",
"deploy": "hexo deploy",
"server": "hexo server"
}
...
}

方法三

有些人也推荐使用另一种方法,该方法以本文中的方法二为基础,不过需要安装依赖模块node-cli。安装该依赖模块的时候,需使用下列命令,以确保该模块被安装在devDependencies节点下,以便以后初始化项目时,运行npm install –production命令时,该依赖模块不会被安装。

1
npm install -save-dev node-cli

在安装完node的CLI后,就需要对Hexo的package.json文件进行修改,在scripts中添加以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"name": "hexo-site",
"version": "0.0.0",
"private": true,
"scripts": {
"build": "hexo generate",
"clean": "hexo clean",
"deploy": "hexo deploy",
"server": "hexo server",
"debug-deploy": "node ./node_modules/hexo-cli/bin/hexo deploy --debug" // 该行
},
...
}

然后修改VS Code的launch.json文件,选用方法二中使用的“Launch via npm”模版,然后参照以下内容完成配置,就可以搭建Hexo代码的调试环境。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug Hexo Deploy via npm",
"cwd": "${workspaceFolder}",
"runtimeExecutable": "npm",
"runtimeArgs": [
"run", "debug-deploy"
],
"console": "internalConsole",
"outputCapture": "std"
}
]
}

以上三种方法都能用于VS Code中Hexo调试环境的搭建工作,三种方法也没有优劣之分,正所谓萝卜白菜各有所爱,使用哪一种方法全凭个人喜好。

应用技巧

Hexo的日志组件Logger的部分方法如下。前文中介绍的相关配置中的“–debug”,就是为了设置日志的输出等级,以便获取更多的程序运行信息。

  • log.info()
  • log.debug()
  • log.warn()
  • log.error()

默认情况下,由于VS Code存在问题(Issues 19750,请点击查看具体内容),所以上述的logger方法,因其内部使用了“process.stdout.write()**”方法,这个方法输出的文本和“console.log()”方法所输出的文本,会输出到不同的地方(虽然理论上console.log内部使用的也是process.stdout.write方法,输出的文本内容应该位于同一地方),仅代码中的console.log输出的内容会显示在VS Code的DEBUG CONSOLE中**。这种情况下,由于缺少日志信息不利于调试,就需要解决该问题。解决方法就是在配置中添加下列代码:

1
2
3
4
5
{
//"port": 9229,
"console": "internalConsole", //integratedTerminal意指 VS Code 的 TERMINAL
"outputCapture": "std"
}

outputCapture 这项配置,如果设置为std,则标准输出stdout 与标准错误stderr的输出都将显示在调试控制台中,而不是在调试端口上的输出。这对于直接写入stdout / stderr流而不是使用console.*的程序或在使用其他第三方日志库时会很有帮助。

能有此文全因自己好奇。在文章最后想说一下,这里没有专家,记录这些主要是为了自己以后回顾学习之方便,文章有不足之处也实属正常。见解不同,诚切赐教,关注微信公众号,一起讨论学习。


版权声明:
文章首发于 Jim Wang's blog , 转载文章请务必以超链接形式标明文章出处,作者信息及本版权声明。