概要
VueのHelloWorldなプロジェクトをVSCode上でデバッグしたかったのですが、なんだかうまく止まらない。これの解決を目指したお話です。
HelloWorld
Vue関連のインストール等は省略します。
> vue create hello-world-test
と打ってHelloWorldなプロジェクトを作成します。
プロジェクト名に大文字は使えないんですね。
こんなApp.vueができました。CSS部は省略。
<template>
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
ちょっといじってデバッグ
Options APIの書き方でそのままdate()とcreated()を追加して、表示内容を変えました。これをデバッグ実行して処理をdebuggerで止めたいと思います。
<template>
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld :msg="currentTime"/>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
},
data() {
return {
currentTime: null,
};
},
created() {
// eslint-disable-next-line no-debugger
debugger;
this.currentTime = new Date();
},
}
VSCodeのlaunch.jsonでもってデバッグ実行の構成を設定します。
構成の追加で「Chrome起動」を選択したまんま。
{
// IntelliSense を使用して利用可能な属性を学べます。
// 既存の属性の説明をホバーして表示します。
// 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Chrome",
"request": "launch",
"type": "chrome",
"url": "http://localhost:8080",
"webRoot": "${workspaceFolder}"
}
]
}
下記のコマンドで立ち上げて、VSCodeの「実行とデバッグ」からLaunch Chromeを実行。
> npm run serve
すると・・・止まりましたが、App.vue?****(数字)というファイルが開いた形でブレークしています。
左のソースで開いてほしい。
これは多分ハイドレーションがどうとかこうとかいうやつで、詳しくは触れません。
launch.jsonにsourceMapsを追記という記事がよく出てくるのですが、自分の環境ではlaunch.jsonをいじっても状況が変わりませんでした。
それで結論としては、vue.config.jsに下記の通り追記するとうまく行きました。
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
- transpileDependencies: true
+ transpileDependencies: true,
+ configureWebpack: {
+ devtool: "source-map",
+ },
})
設定を変えたらnpm run serve
し直して、Launch Chrome。
ハテナが付かなくなった!・・・けど、まだ左のソースと違うものが開いている。
App.vueのタブにマウスオーバーしてみると、"\${workspaceFolder}"直下のsrc/App.vueというパスになっています。これは正しくは"\${workspaceFolder}/hello-world-test"以下でなくてはなりません。
こちらについてはlaunch.jsonを直す必要があります。下記の通りです。
{
// IntelliSense を使用して利用可能な属性を学べます。
// 既存の属性の説明をホバーして表示します。
// 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Chrome",
"request": "launch",
"type": "chrome",
"url": "http://localhost:8080",
- "webRoot": "${workspaceFolder}"
+ "webRoot": "${workspaceFolder}/hello-world-test"
}
]
}
これで改めてLaunch Chromeしてみると、期待通り元のソースに対してdebuggerが機能しました!
この状態になれば、ブレークポイントを貼る方法についてもきれいに止まるようになります。めでたしめでたし。
※環境によってはこれだけではダメかもしれません。launch.jsonの"sourceMapPathOverrides"という設定が必要かもしれませんが、よく分かっていないこともあるため、ここでは触れません。
サーバー起動&Chrome起動のハッピーセット
動かすとき、いちいちnpm run serve
してVSCodeのデバッグ実行をクリックして~、という手順は繰り返していると煩わしいものです。これをまとめてやってくれる設定の書き方があります。launch.jsonを以下のようにします。
{
// IntelliSense を使用して利用可能な属性を学べます。
// 既存の属性の説明をホバーして表示します。
// 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"compounds": [
{
"name": "Debug on Chrome",
"configurations": [
"Run Serve",
"Launch Chrome"
]
}
],
"configurations": [
{
"name": "Launch Chrome",
"request": "launch",
"type": "chrome",
"url": "http://localhost:8080",
"webRoot": "${workspaceFolder}/hello-world-test",
},
{
"name": "Run Serve",
"request": "launch",
"type": "node",
"runtimeExecutable": "npm",
"runtimeArgs": [
"run",
"serve"
],
"cwd": "${workspaceFolder}/hello-world-test",
"skipFiles": [
"<node_internals>/**"
]
}
"compounds"のところがポイント。2つの処理を両方やってくれるようになります。
しかし、この状態で前章のようにデバッグしようとすると、初回起動時はなんだか止まってくれません。またdebuggerを置いていると、何やら止まっているものの (index)(数字)とかVM(数字)といった謎のファイルが開き、「ソース ~~ を読み込めませんでした: ソースが見つかりません。」というエラーっぽいものが出たりします。
謎のファイル。
ただ、Chromeの画面をリロードすると、以降はブレークポイントで止まるようになります。
この「初回実行時だけなんか止まらない」問題を解決します。
詳しいことは自分がよく分かっていませんが、要するに「まだ準備できてないけどChromeがページを開いちゃって止まっちゃった」という状況なのだろうと思います。それで対策として行うのは、「開発用サーバーのポートが準備出来たことを確認してからChromeを立ち上げる」という制御をするということです。
これを達成するため、設定ファイルと実行ファイルを追加します。いずれも.vscodeフォルダに置いておけばいいと思います。
{
"version": "2.0.0",
"options": {
"shell": {
"executable": "powershell.exe"
}
},
"tasks": [
{
"label": "WaitForPortOpen",
"type": "shell",
"windows": {
"command": [
"Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process;",
". .vscode/wait.ps1;"
]
},
"group": "none",
"presentation": {
"panel": "shared",
"reveal": "never",
"showReuseMessage": false,
"close": true
}
}
]
}
$ErrorActionPreference = "Stop"
while (!(Test-NetConnection -ComputerName 127.0.0.1 -Port 8080).TcpTestSucceeded) {
Start-Sleep -Seconds 5
}
さらに、launch.jsonに下記の通り記述を追加します。
{
"name": "Launch Chrome",
"request": "launch",
"type": "chrome",
"url": "http://localhost:8080",
"webRoot": "${workspaceFolder}/hello-world-test",
+ "preLaunchTask": "WaitForPortOpen"
},
前述の通り、Launch Chromeする前のタスクとして、"WaitForPortOpen"というものをtasks.jsonに用意しました。内容は"wait.ps1"をPowerShellで実行するという感じです。そのwait.ps1は、ポートが通るまで待ちますよ、という命令をしています。
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process
は、PowerShellで実行を許可するためのおまじないです。
"presentation"の中の設定は実行してからVSCodeにPowerShellのターミナルを残さないとか色々の設定です。お好みに合わせて変えてもらえればと思います。ここでは詳しくは解説しません。
以上の設定を踏まえてDebug on Chromeを実行すれば、初回起動時でもきれいにブレークポイントで止まるようになります!
参考