W ostatnich kilku tygodniach w pracy miałem okazję przesiąść się na budowanie frontendu zamiast ciągłego rozwijania strony serwerowej. Nasza aplikacja rozwijana jest w Angularze, do którego podchodziłem na początku dosyć sceptycznie. Uważałem go po prostu za Reacta na sterydach, w którym miałem okazję wcześniej hobbistycznie pisać. Muszę przyznać, że naprawdę zostałem miło zaskoczony przez to co zastałem. TypeScript okazał się dla mnie znośną wersją JavaScriptu dzięki typowaniu. Naprawdę czuję wtedy, że mam kontrolę nad tym co się dzieje w moim kodzie. Dodatkowo Angular posiada adnotacje przypominające te ze Springa Javowego jak np. @Component. Z tego powodu moim zdaniem łatwiej jest się zabrać za naukę Angulara jeśli wcześniej pisało się w Javie.

Czym urzekł mnie Angular…

Przykład zapisywania kodu

Na samym początku trzeba jeszcze raz zaznaczyć, że Angular korzysta z TypeScriptu. Pierwszą rzeczą, która przykuła moją uwagę w tym języku było silne typowanie. Naprawdę jest to dla mnie duży przeskok z racji wcześniejszej walki z JavaScriptem. Pisząc w TypeScript czułem się trochę nawet jakbym pisał w Javie poza oczywiście kilkoma niuansami.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class ExampleClass {
  convertNumber(age: number):string {
    if (age < 0) {
      return "Error, negative number";
    }

    switch (age) {
      case 1:
        return "One";
      case 2:
        return "Two";
      case 3:
        return "Three";
    }

    return `Unknown number of ${age}`;
  }
}

let variable = new ExampleClass();
let result: string = variable.convertNumber(2);

console.log(result);

Prawda, że te języki wyglądają dosyć podobnie na pierwszy rzut oka? Konstrukcja switch i if niczym się nie różni, ale warto zwrócić uwagę na kilka różnic. Zacznijmy od deklaracji metody, która domyślnie ma publiczny modyfikator dostępu. Dodatkowo zwracany typ metody deklarujemy na końcu po dwukropku, ale nie jest to obligatoryjne. TypeScript ma tą przewagę, że posiada zdolność wnioskowania typów. Ja sam jednak wolę pisać jaki typ jest zwracany przez metodę, żeby ta informacja była dostępna na pierwszy rzut oka. Oczywiście ten sam mechanizm działa przy deklaracji zmiennych co widać przy zmiennej variable, która nie musi zdefiniowanego podanego typu.

Co jeszcze może się podobać to sposób tworzenia literału bez używania konkatenacji. Dzięki zapisowi informacji w ... mamy możliwość wstawienia tam wartości zmiennych poprzez użycie mechanizmu ${…}.

Wstrzykiwanie zależności

Podczas pracy np. ze Springiem mamy do czynienia z mechanizmem wstrzykiwania zależności (polecam zajrzeć do artykułu o różnicy pomiędzy @Bean i @Component). Skoro o tym mówię to nie zdziwi Was fakt, że Angular też korzysta z wyżej wspomnianej funkcjonalności. Zależności wstrzykujemy do danej klasy przy pomocy konstruktora.

1
2
3
4
5
6
7
@Component({
  selector: 'app-parent',
  templateUrl: './app-parent.component.html'
})
export class ParentClass {
  constructor(private childClass: ChildClass) {}
}

Klasy tak samo jak w Springu są adnotowane przy pomocy @Component, ale dokładne wyjaśnienie tej adnotacji w Angularze nie jest celem mojego artykułu. Warto zaznaczyć fakt, że parametry, które są wstrzykiwane przez konstruktor, stają się automatycznie zmiennymi klasy. Oznacza to, że childClass nie musimy przypisywać do żadnej innej zmiennej w ciele konstruktora, możemy ją wykorzystywać w klasie bez dodatkowych instrukcji.

Struktura plików projektu

Angular pozwala nam podzielić strukturę projektu na klasy, interfejsy, serwisy, komponenty oraz wiele innych elementów. Dzięki temu uzyskujemy przejrzystszy pogląd na naszą aplikację. Całością możemy dodatkowo sterować poprzez modyfikatory dostępu, których mamy do dyspozycji 3: private, public i protected.

Angular struktura projektu
Przykładowa struktura projektu

Wykorzystując Angular CLI z łatwością zadbamy o poprawną strukturę projektu oraz ograniczymy ilość występowania możliwych błędów podczas tworzenia własnoręcznych plików i katalogów.

npm, czyli Twój Maven/Gradle

Do budowania projektów w Angularze wykorzystuje się npm. Tak samo jak w Maven czy Gradle i tutaj możemy łatwo zautomatyzować pobieranie niezbędnych zależności oraz operować fazami budowania projektu. Całość konfiguracji znajduje się w pliku package.json, którego struktura może być podobna do tej z poniższego przykładu.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
{
  "name": "customer-manager",
  "version": "0.0.0",
  "scripts": {
  "ng": "ng",
  "start": "ng serve",
  "build": "ng build",
  "test": "ng test",
  "lint": "ng lint"
  },
  "private": true,
  "dependencies": {
  "@angular/animations": "^10.2.1",
  "@angular/common": "~10.2.0",
  "@angular/compiler": "~10.2.0",
  "@angular/core": "~10.2.0",
  "@angular/forms": "~10.2.0",
  "@angular/platform-browser": "~10.2.0",
  "@angular/platform-browser-dynamic": "~10.2.0",
  "@angular/router": "~10.2.0",
  "bootstrap": "^4.5.3",
  "ngx-toastr": "^13.1.0",
  "rxjs": "~6.6.0",
  "tslib": "^2.0.0",
  "zone.js": "~0.10.2"
  },
  "devDependencies": {
  "@angular-devkit/build-angular": "~0.1002.0",
  "@angular/cli": "~10.2.0",
  "@angular/compiler-cli": "~10.2.0",
  "@types/node": "^12.11.1",
  "ts-node": "~8.3.0",
  "tslint": "~6.1.0",
  "typescript": "~4.0.2"
  }
}

Jest o naprawdę przejrzysty plik o strukturze JSON. Nasze zależności znajdują się pod nazwą dependencies, które polecam dodawać przy pomocy terminala i polecenia ‘*npm install *'.

Środowisko pracy

Jeżeli nie masz licencji do korzystania z IDEA Intellij Ultimate to polecam Ci Visual Studio Code. Z racji wygody pierwsza opcja wydaje się jednak rozsądniejsza. Dzięki takiemu rozwiązaniu możesz posiadać projekt Springowy i Angularowy w jednym IDE. Oczywiście da się też pracować w IDEA Intellij Community, ale nie wydaje mi się to wygodnym rozwiązaniem. Ja osobiście tworzę backend w Intellij natomiast frontend w VSC z racji mniejszej liczby otwartych plików w środowisku programistycznym przez co nie mieszają mi się one. Ile ludzi, tyle pomysłów 😉.

Angular w IntelliJ
Projekt Angularowy w IntelliJ

Podsumowanie

Jak dla mnie osobie, która na co dzień ma styczność z Javą naprawdę jest łatwo przyswoić sobie podstawowe mechanizmy Angulara. Oczywiście na poznanie wszystkich możliwych funkcjonalności trzeba poświęcić dużo więcej czasu, ale z pewnością będzie to dużo prostsze. Mi osobiście sprawiło to wielką satysfakcję, od kiedy potrafię już stworzyć serwer, z którego będę mógł korzystać poprzez przeglądarkową aplikację kliencką.

Mam nadzieję, że tym artykułem zachęciłem Cię do przyjrzenia się Angularowi i TypeScriptowi. Myślę, że i Tobie sprawi to ogromną radość, gdy stworzysz swój pierwszy projekt frontendowy. Oderwiesz się od Javowej codzienności i zapoznasz się z inną perspektywą na tworzenie oprogramowania. Jeśli jednak już tworzysz w Angularze to daj znać w komentarzu czy widzisz może jeszcze więcej podobieństw z Javą?