誰向けの記事か
node --inspect=0.0.0.0:9229を実行して、こんなエラーが出てしまっている人
Debugger listening on ws://0.0.0.0:9229/c9b5d9ba-7443-4902-9463-afa66c1126e2
...
Starting inspector on 0.0.0.0:9229 failed: address already in use
なぜinspectorが2回も起動しようとしているの・・・?
まえがき
nodeのデバッグには --inspectオプション(v7以前なら--debugが相当機能)を有効にすることで、ChromeDevToolsやその他デバッグ機能を備えたエディタ(WebStormやVSCode)からnodeのデバッガーに接続することが出来て、とても便利ですよね。
今回はこのデバッグ機能を使おうとしてハマったので、原因と解決方法を共有します。
対策チャート
TypeScriptを使っているか?
YES: 次の設問へ
NO: 原因のところまでジャンプして、あなたの環境の場合の原因に当てはまりそうか考えてみてください。
awesome-typescript-loaderを使っているか?
YES: 次の設問へ
NO: 原因のところまでジャンプして、あなたの環境の場合の原因に当てはまりそうか考えてみてください。
デバッグの実行環境がDockerコンテナ内か?
YES: 対策の項へ!
NO: 次の設問へ
--inspect にIPとportを渡す必要が本当にある?
YES: 対策の項へ!
NO: node --inspect で、デフォルトのIPが127.0.0.1, ポート9229で動作し、ポートが使用済みの場合は自動的に空きポートを使用してくれるので、パラメータなしにしましょう。
原因
awesome-typescript-loaderの内部で、ChildProcessを生成している部分があるが、そこで、Expressを起動しているProcessの実行オプションをそのまま渡しているため、--inspectにポートを指定しているとポートの重複Errorになる。
このようにnodeのinspect機能を有効にしている場合に、使っているライブラリや自身のコードでChildProcessを生成していると、process.Argvをそのまま引き継ぐ実装をしているときにポート重複の罠にハマってしまう。
対策
- ts-loaderを使う
- expressの初期化中にprocess.execArgvの中身を書き換えて、
--inspectからパラメータを除去する - そもそもの原因箇所の修正をする(issueは起こしておきました)
ひとまずは、以下のようなもので対処してみました。
// hack for awesome-typescript-loader
const execArgv = process.execArgv;
for (let i = 0; i < execArgv.length; i++) {
if (execArgv[i].match(/--inspect=.*:?\d{3,5}/)) {
// replace inspect option if it has constant port
execArgv[i] = "--inspect";
} else if (execArgv[i].match(/--inspect=\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)) {
// replace inspect option if it has constant address
execArgv[i] = "--inspect";
}
}