Visual Studio Code のデバッグコンソールにログが出力されない話

スタッフブログ

Photo by Anas Alshanti

皆様どうも、こんにちは!
こまりのバックエンドエンジニア、桑木です。

社内システムのAPIサーバを、Node.js + Expressで作ってみようかなっ。という軽いノリでコーディングしていたところ、Visual Studio Code(以下VSCode)のデバッグコンソールにログが出力されなくて困惑したという話をしたいと思います。もちろん解決しました。

ターミナルでは問題が起こらない

express-generatorを使うかどうかは別にして、Node.jsアプリ開発なのでnpmはバリバリ使います、よね? Yarnかも知らんけど。なので、基本的にターミナルでnpmを叩いて、実行もターミナルでそのまま npm start とかやっていた時はそんな問題には気付きませんでした。

ところが、VSCodeのデバッガを利用しようかな、とlaunch.jsonを設定してVSCodeから実行したら、動作はするもののログが出力されませんでした。VSCodeの「ターミナル」は見たまんまコマンドプロンプトとかシェルと呼ばれる物で、「デバッグコンソール」はブラウザの開発者ツールのコンソールみたいな物なので、両者は別々の物です。だから違いがあるのはわかりますが、ログを表示することに関しては両者とも同じようにできないと困ります。

ずばり、原因はその「違い」だった

最初は、「npm start」と「launch.jsonにもとづく実行」の環境の違いを疑いました。例えば、両者で環境変数が違ってログの出力方式が変わっている、とかね。そんな設定にはなっていませんでしたが。

Expressのログ出力に使用している morgan モジュールのソースコードを読んでみたら、ログの出力には process.stdout を使用していました。
試しにデバッグコンソールで、
process.stdout.write("abc")
などと実行しても、出力されません。
console.log("abc")
なら出力されます。なるほど、原因はこのあたりにありそうです。

確かに名前の通りではありますが、デバッグコンソールに出力するには console.log を使いますし、標準出力(stdout)に出力するには process.stdout を使います。通常、Node.jsでは console.log は標準出力に出力されることになっていたと思います。[要出典] しかし、現実問題としてVSCodeのデバッグコンソールはコンソールであって標準出力ではない、という主張みたいです。

とはいえ、困るものは困るので対処方法

launch.jsonに、
"outputCapture": "std"
を指定すると良いです。’process.stdout.write calls don’t show in the console from node2 debug sessions #19750に書いてありました。を参考にしました。まさにこの問題に対処するために、このオプションが作られたみたいですね。

他の対処法として、これも同じくlaunch.jsonに、
"console": "integratedTerminal"
を指定して、デバッグにターミナルを使用するという方法もあるみたいです。本来の出力とデバッグコンソールの出力が混ざらないのは、場合によっては有用かもしれません。

コメント