Angular 2 Debug mit Visual Studio Code

Angular 2 mit TypeScript ist ein Power-Duo. TypeScript erweitert Javascript mit Typisierung und „transpiliert“ („compiliert“) daraus Javascript. Mit Visual Studio Code kann man das einfach automatisieren. Richtig aufgesetzt kann auch das Debugging gelöst werden. Nicht ganz einfach.

Voraussetzungen

  • Chrome installiert
  • Visual Studio Code installiert
  • NodeJs installiert
  • Angular 2 installiert
  • tsconfig.json erstellt, damit werden die TypeScript Transpilierungs-Optionen festgehalten

Automatisch .js Dateien erstellen mit tasks.json

TypeScript wird in .ts Dateien geschrieben und in .js „transpiliert“. Visual Studio Code führt dazu beim Kompilieren  (CTRL-SHIFT-B) die Datei ./.vsocde/tasks.json aus. Bei der ersten Compilation verlangt Visual Studio Code, dass diese Datei erstellt wird. Aus den verfügbaren Optionen wählt man am besten „TypeScript – Watch Mode“ aus. Damit „tranpiliert“ Visual Studio Code jede .ts Änderung beim Speichern sofort und die Webpage wird neu angezeigt. Das ist natürlich für die Entwicklung komfortabel.

vsctask

„isWatching“ überwacht die File-Änderungen

Launch-Tasks definieren

Bei Ausführen (F5) der Applikation verlangt Visual Studio Code, dass die Launch-Task definiert wird. Analog zu oben, wird die Launch-Task beim ersten Starten definiert.

Wenn man NodeJs installiert hat, kann der Node Lite Server gestartet werden. Dazu wird die Program-Variable (Default: app.js) überschrieben:

Debugging nur auf dem Server

Da Visual Studio Code uns NodeJs integriert sind, erwartet man, dass nun auch das Debugging funktioniert. Und eigentlich tut es das auch. Allerdings nur für serverseitiges Javascript. Davon gibt es mit Angular 2 natürlich nichts.

Chrome Extension für clientseitiges Debugging

Die Chrome Extension kann direkt aus Visual Studio Code heraus installiert werden. F1 und dann „Extensions„.

vscchromeextension

 

Mit Return zeigt Visual Studio Code eine Liste der möglichen Extensions an. Mit „Chrome“ weiter einschränken und „Debugger for Chrome“ auswählen.

vscchromeextensiondebugger

 

 

Sobald die Extension installiert ist, können im launch.json mehr Optionen definiert werden. Am einfachsten ./.vscode/launch.json löschen und erneut F5 drücken.

Die unterschiedlichen Launch Optionen können dann in Visual Studio Code im Debug Fenster ausgewählt werden. Im folgende Screenshot habe ich die Namen leicht angepasst.

vscdebuglaunchoptions

Interessant ist natürlich die neue Option, wonach Chrome mit der URL „http://localhost“ gestartet werden kann. Da der Node Lite Server aber in einer separaten Launch Konfiguration definiert ist, kann dieser nicht mehr automatisch gestartet werden..

lite-server manuell starten

Der Node Lite Server kann von einem Terminalfenster / Command Line heraus gestartet werden. Am einfachsten wird der lite-server aus dem Rootverzeichnis der Applikation heraus gestartet

Damit die lite-server Konfiguration nicht angepasst werden muss, änderte ich den Port auf 3000 für die Chrome Extension im launch.json

Natürlich könnte man auch andere Server starten, z.B. kann mit npm einfach den http-server oder browser-sync installiert werden, welche auch einen Servermodus kennt. Ich habe beides probiert, aber beide Alternativen haben Nachteile:

  • http-server kennt kein File-Watching und macht kein automatisches Refresh
  • browser-sync start –server kann kein Refresh des Browsers machen, da das Angular 2 Routing über Javascript funktioniert, z.B. /dashboard aus der Url im Browser heraus funktioniert nicht. Im Umkehrschluss bedeutet das, dass der lite-server immer ein Fallback auf index.html machen muss. Das würde dann eigentlich heissen, dass in einer produktiven Applikation ein serverseitiges Rewrite nötig sein. Bin gespannt.

Happy Debugging

Nun kann in Visual Studio Code ein Breakpoint gesetzt werden. Selbstverständlich im TypeScript File und nicht im transpilierten Javascript File.

F5 mit der „Chrome Debug Launch“ Konfiguration aus launch.json und los geht’s und …

…nichts passiert!

Aus irgendeinem Grund muss man im Browser nochmals ein Refresh machen. Aber ab dann geht’s.

vscdebugging

 

 

Urs Verfasst von:

2 Comments

  1. Michael Csitkovics
    17. September 2016

    Hi Urs!
    Früher hat das ja, wie von dir ausgezeichnet beschrieben, super funktioniert. Aber bei den neuen Angular 2-Apps (auf Basis des aktuellen Angular-CLI mit der finalen 2.0.0 und Webpack) leider nicht mehr. Es wird ja „ng serve“ anstatt dem Lite-Server verwendet, was vermutlich noch nicht das Problem ist. Auch der Start der Debug-Session über die launch.json funktioniert (wenn man nicht auf die zusätzliche Angabe von „userDataDir“ vergisst). Setzt man aber einen Breakpoint, so wird dieser einfach nicht getroffen. Hat wohl irgendwas mit den Sourcemaps zu tun. Die scheinen aber zu funktionieren, denn innerhalb der Chrome-Dev-Tools funktionieren die Breakpoints in den TypeScript-Files (innerhalb des Webpack zu finden). Hast du vielleicht schon Erfahrungen damit gemacht?

    • Urs
      18. September 2016

      Beim Starten mit npm start sieht man:

      [1]
      [1] > angular2-quickstart@1.0.0 lite /Users/ursmeier/ionic/angular2
      [1] > lite-server
      [1]
      [0]
      [0] > angular2-quickstart@1.0.0 tsc:w /Users/ursmeier/ionic/angular2
      [0] > tsc -w
      [0]
      [1] Did not detect a
      bs-config.json or bs-config.js override file. Using lite-server defaults...
      [1] ** browser-sync config **
      [1] { injectChanges: false,
      [1] files: [ './**/*.{html,htm,css,js}' ],
      [1] watchOptions: { ignored: 'node_modules' },
      [1] server: { baseDir: './', middleware: [ [Function], [Function] ] } }
      [1] [BS] Access URLs:
      [1] --------------------------------------
      [1] Local: http://localhost:3000
      [1] External: http://192.168.1.106:3000
      [1] --------------------------------------
      [1] UI: http://localhost:3001
      [1] UI External: http://192.168.1.106:3001
      [1] --------------------------------------
      [1] [BS] Serving files from: ./
      [1] [BS] Watching files...

      entsprechend kann im launch.json der Port auf 3000 gesetzt werden:

      {
      "version": "0.2.0",
      "configurations": [
      {
      "name": "Launch Chrome against localhost, with sourcemaps",
      "type": "chrome",
      "request": "launch",
      "url": "http://localhost:3000",
      "sourceMaps": true,
      "webRoot": "${workspaceRoot}"
      },
      {
      "name": "Attach to Chrome, with sourcemaps",
      "type": "chrome",
      "request": "attach",
      "port": 9222,
      "sourceMaps": true,
      "webRoot": "${workspaceRoot}"
      }
      ]
      }

      Vorgehen:
      a) alle Chrome Instanzen schliessen
      b) npm start (startet Safari)
      c) F5 mit Launch Chrome against localhost, with source maps

      Happy Debugging!

Die Kommentare sind geschlossen