1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

VueプロジェクトのデバッグでVSCode上のブレークポイントがきれいに止まらない件に対応する

Posted at

概要

VueのHelloWorldなプロジェクトをVSCode上でデバッグしたかったのですが、なんだかうまく止まらない。これの解決を目指したお話です。

HelloWorld

Vue関連のインストール等は省略します。

> vue create hello-world-test

と打ってHelloWorldなプロジェクトを作成します。
プロジェクト名に大文字は使えないんですね。

こんなApp.vueができました。CSS部は省略。

App.vue
<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で止めたいと思います。

App.vue
<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起動」を選択したまんま。

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}"
        }
    ]
}

下記のコマンドで立ち上げて、VSCodeの「実行とデバッグ」からLaunch Chromeを実行。

> npm run serve

すると・・・止まりましたが、App.vue?****(数字)というファイルが開いた形でブレークしています。
image.png
左のソースで開いてほしい。

これは多分ハイドレーションがどうとかこうとかいうやつで、詳しくは触れません。
launch.jsonにsourceMapsを追記という記事がよく出てくるのですが、自分の環境ではlaunch.jsonをいじっても状況が変わりませんでした。
それで結論としては、vue.config.jsに下記の通り追記するとうまく行きました。

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。
image.png
ハテナが付かなくなった!・・・けど、まだ左のソースと違うものが開いている。

App.vueのタブにマウスオーバーしてみると、"\${workspaceFolder}"直下のsrc/App.vueというパスになっています。これは正しくは"\${workspaceFolder}/hello-world-test"以下でなくてはなりません。
こちらについてはlaunch.jsonを直す必要があります。下記の通りです。

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が機能しました!
image.png
この状態になれば、ブレークポイントを貼る方法についてもきれいに止まるようになります。めでたしめでたし。
※環境によってはこれだけではダメかもしれません。launch.jsonの"sourceMapPathOverrides"という設定が必要かもしれませんが、よく分かっていないこともあるため、ここでは触れません。

サーバー起動&Chrome起動のハッピーセット

動かすとき、いちいちnpm run serveしてVSCodeのデバッグ実行をクリックして~、という手順は繰り返していると煩わしいものです。これをまとめてやってくれる設定の書き方があります。launch.jsonを以下のようにします。

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(数字)といった謎のファイルが開き、「ソース ~~ を読み込めませんでした: ソースが見つかりません。」というエラーっぽいものが出たりします。
image.png
謎のファイル。

ただ、Chromeの画面をリロードすると、以降はブレークポイントで止まるようになります。
この「初回実行時だけなんか止まらない」問題を解決します。

詳しいことは自分がよく分かっていませんが、要するに「まだ準備できてないけどChromeがページを開いちゃって止まっちゃった」という状況なのだろうと思います。それで対策として行うのは、「開発用サーバーのポートが準備出来たことを確認してからChromeを立ち上げる」という制御をするということです。

これを達成するため、設定ファイルと実行ファイルを追加します。いずれも.vscodeフォルダに置いておけばいいと思います。

tasks.json
{
    "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
            }
        }
    ]
}
wait.ps1
$ErrorActionPreference = "Stop"

while (!(Test-NetConnection -ComputerName 127.0.0.1 -Port 8080).TcpTestSucceeded) {
    Start-Sleep -Seconds 5
}

さらに、launch.jsonに下記の通り記述を追加します。

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を実行すれば、初回起動時でもきれいにブレークポイントで止まるようになります!

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?