/ TypeScript

TypeScript - Web Applikation - Start Template

!ACHTUNG, veraltert! Neuere Template Version siehe:
VS Code/TypeScript Start Template für Node.js und Web Applikationen

Die Überlegungen und grundsätzlichen Anmerkungen sind aber hilfreich und deshalb wurde der Artikel nicht entfernt.

Wie ich ein Node.js Projekt mit TypeScript in VSCode (Visual Studio Code) anlege, habe ich im Artikel TypeScript - Node.js - Start Template thematisiert. Doch wie ist es, wenn der Code nicht in Node.js sondern im Browser laufen soll, wenn man eine Web Applikation baut, wie kann einem da VSCode und TypeScript helfen?

Während der Folgen 17, 18 und 19: VSCode + TypeScript + Web Applikation meines YouTube Kanals Helmbergers Let's Code entstand dieses Template, das einem hilft ein Projekt zu starten.

  • Wie kann man das Template verwenden:

    • Man kann die hier erklärten Schritte nachmachen (indem man die Codeschnipsel in die PowerShell bzw. in VSCode kopiert) und erhält damit die Ausgangsbasis für das eigene Projekt. - So mache ich es meist.
    • Man kann sich aber auch einfach den Source aus GitHub downloaden und damit starten. (In bower.json und package.json den Namen template.web.typescript.1 ersetzen).
  • Template verändert sich

Da sich die JavaScript Welt ständig ändert, kann natürlich auch so ein Template nicht in Stein gemeißelt sein, es wird sich ständig anpassen müssen.

Damit es leicht wiederverwendet werden kann, habe ich mir folgende Aufgabe gestellt:

  • Code der kompiliert und ausführbar ist
  • TypeScript Type Declarations verwenden
  • Eine externe Library als Beispiel inkludieren.
  • Modul Konzept ersichtlich.
  • Debugging soll unterstützt werden.
  • Externe Libraries einfach verwaltbar

Zum Verwalten der Type Definitions, verwende ich gegenüber dem Node.Js Template nun doch das Tool typings und nicht mehr tsd, da das Command-line tool tsd deprecated ist.

Zur Packageverwaltung verwende ich zwei Package Manager: npm und bower. Vermutlich ist bower ein Kandidat, der in der nächsten Version nicht mehr dabei ist. Aber im Moment finde ich die Trennung: npm für die Infrastruktur und bower für die auszuliefernden Libs, nicht so schlecht.

0. Vorbereitung - Packages installieren

Nur eine ganz kurze Anleitung:

  • Visual Studio Code und Chrome installieren

  • Node.js installieren

  • npm updaten

  • TypeScript, typings und bower installieren:

      npm install -g typescript typings bower
    

Näheres findet man in folgendem Blogeintrag:

  • Node.js und npm installieren

  • Bemerkung: Proxy Einstellungen für typings, sind analog zu tsd zu machen. Einfach das File ".tsdrc" (im Ordner C:\Users\meinUser)kopieren und in ".typingsrc" umbenennen.

1. Projektverzeichnis anlegen und Projekt initialisieren

Tipp: Keine Großbuchstaben für den Ordnernamen verwenden.

mkdir template.web.typescript.1
cd template.web.typescript.1
npm init
bower init

Bei den letzten beiden Initialisierungsaufrufen, wird man nach ein paar Parametern gefragt, hier mal einfach mit vielen Returns "weiterklicken", im Moment ist nur wichtig, dass die Files angelegt werden.

2. TypeScript Compiler, Type Declarations, Dateistruktur, Library, VSCode starten

Ein paar Bemerkungen dazu:

  • Als Beispiel library verwende ich wieder lodash, eine Utility Bibliothek.

  • Damit die einzelnen Module asynchron geladen werden können, verwende ich Asynchronous Module Definition (AMD) und benötige daher require.js.

  • Die Bibliothek concurrently wird zum Aufruf des Compilers und Web Servers verwendet. Als Web Server kommt der lite-server zum Einsatz.

Auch dieser zweite Block kann einfach in die PowerShell kopiert werden:

tsc --init
typings init


New-Item README.md -ItemType File
New-Item .gitignore -ItemType File
New-Item app -ItemType Directory
New-Item app\main.ts -ItemType File
New-Item app\common -ItemType Directory
New-Item app\common\utils.ts -ItemType File

New-Item index.html -ItemType File
New-Item require-config.ts -ItemType File

New-Item styles -ItemType Directory
New-Item styles\app.css -ItemType File

npm install concurrently --save-dev
npm install lite-server --save-dev

bower install requirejs-bower --save 
bower install lodash --save 


typings install dt~require --global --save
typings install dt~lodash --global --save


code .

Der letzte Befehl öffnet Visual Studio Code (VS Code) und damit werden nun ein paar Dateien verändert:

3. Files anpassen
  • app/common/utils.ts:

(identisch dem node.js start template)

import * as _ from "lodash";
export default class Utils {   
    public static kebapStyle(input: string): string {
        console.log(`kebapStyle(${input})`);
        return _.kebabCase(input);
    }
}
  • app/main.ts:

Bemerkung: Will man jQuery verwenden, siehe Anhang A.2 jQuery.


import Utils from "./common/utils";

function processButtonClick() {
  console.log("processButtonClick");

  let inputElement = (<HTMLInputElement>document.getElementById("hlc-input"));
  let outputElement = (<HTMLElement>document.getElementById("hlc-output"));

  let output = Utils.kebapStyle(inputElement.value);

  outputElement.innerText = new Date().toLocaleTimeString() + " : " + output;

}

window.onload = function () {
  document.getElementById("hlc-btn-process").onclick = processButtonClick;
}


  • .gitignore:

      bower_components
      node_modules
      typings
      .vscode
    
  • tsconfig.json

Zwei Änderungen:
module -> amd
sourceMap -> true

{
    "compilerOptions": {
        "module": "amd",
        "target": "es5",
        "noImplicitAny": false,
        "sourceMap": true
    },
    "exclude": [
        "node_modules"
    ]
}
  • index.html
<!DOCTYPE html>
<html>

<head>
  <title>TEST</title>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="styles/app.css">
  <script src="./bower_components/requirejs/require.js"></script>
  <script src="require-config.js"></script>
  <script>
      require(["app/main"]);
  </script>
</head>

<body>
  <form>
    <input id="hlc-input" type="text" value="">
    <button id="hlc-btn-process" type="button">Process</button>
    <hr />
    <div id="hlc-output"></div>
  </form>
</body>

</html>
  • require-config.ts
  require.config({
      paths: {
          "lodash": "bower_components/lodash/lodash"
          }
  });
  • package.json

start script einfügen:

  "scripts": {
    "start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
4. Builden

Nun Builden, damit ein Task Runner config angelegt wird:

Ctrl + Shift + B
- Configure Task Runner:
  - TypeScript - tsconfig.json
  • .vscode/tasks.json

      "showOutput": "silent",
      => 
      "showOutput": "always",
    

Und nun nochmals builden (Ctrl + Shift + B).

Falls der Build Task nicht endet (der Propeller in der Statusleiste nicht aufhört sich zu drehen), dann am besten VS Code schließen, neu öffnen und neu compilieren.

5. Server starten

In der PowerShell (erreicht man auch durch Ctrl + ö - womöglich vorher konfigurieren in File - Preferences - User setting)

 npm start 
 oder
 npm run start

ausführen.

mit Strg + c
kann man den Server wieder stoppen.

Es öffnet sich der Default Browser.
Tipp: Manchmal ist es nötig die Browserseite zu aktualisieren (F5 im Browser drücken).

6. Debuggen

Sind keine Fehler aufgetreten (Statusleiste zeigt 0 errors), dann starten mit F5.

Es wird nachgefragt (Select Environment) und wir wählen Chrome.

Falls das nicht zur Verfügung steht, dann muss man erst die Extension: "Debugger for Chrome" installieren.

Damit wird eine weitere Datei angelegt, die wir wieder anpassen:

  • .vscode/launch.json

      "url": "http://localhost:3000",
    

Jetzt aber:

F5

Chrome öffnet sich und lädt die Seite:
localhost:3000.

Tipp: Manchmal ist es nötig die Browserseite zu aktualisieren (F5 im Browser drücken).

7. Testen

Man kann einen Breakpoint in einem TypeScript File setzen und den Debugger neuerlich mit F5starten.

Auch sollte man testen, ob IntelliSense funktioniert für die importierte Klasse Utils und für die importierte library lodash (falls das nicht klappt, VS Code schließen und neu starten, hilft meist.)


  • Bemerkung:

Man kann dieses nun generierte Projekt auch nur als Template verwenden und es immer wieder kopieren. (Dazu am besten folgende Folder entfernen: typings, node_modules und bower_components. Und im neuen Projekt dann npm install, typings install und bower install aufrufen.)

Den Sourcecode findet man auch auf GitHub:
GitHub Repository template.typescript.1

Anhang

A.1 VSCode Konfigurationsfiles

Meine Visual Studio Konfigurationsfiles (die sind ja nicht auf GitHub abgelegt)

  • .vscode/settings.json
{
    "files.exclude": {
        "**/*.js.map": true,
        "**/*.js": {
            "when": "$(basename).ts"
        }
    }
}
  • .vscode/tasks.json
{
    "version": "0.1.0",
    "command": "tsc",
    "isShellCommand": true,
    "args": ["-p", "."],
    "showOutput": "always",
    "problemMatcher": "$tsc"
}
  • .vscode/launch.json
{
    "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}"
        }
    ]
}
A.2 jQuery

Will man jQuery verwenden:

bower install jquery --save 
typings install dt~jquery --global --save

In require-config.ts jquery bekanntgeben:

"jquery": "bower_components/jquery/dist/jquery",
"lodash": ...

app/main.ts wird etwas einfacher mit jQuery:


import Utils from "./common/utils";
import * as $ from "jquery";  

function processButtonClick() {
  let input = (<HTMLInputElement>$("#hlc-input")[0]).value;
  let output = Utils.kebapStyle(input);
  $("#hlc-output").text(new Date().toLocaleTimeString() + " : " + output);
}

window.onload = function () {
  $("#hlc-btn-process").click(() => processButtonClick());
}

Links zu Libraries

Artikel in diesem Blog


Weitere Let's Code Artikel.