Automatyczny deploy aplikacji Angular na Heroku

Heroku logo

Proces deploymentu, to dla deweloperów temat rzeka. Mamy obecnie wiele możliwości oraz wiele gotowych rozwiązań. W tym wpisie zademonstruję jak wykonać deploy aplikacji napisanej przy użyciu frameworka Angular na Heroku.

Przygotowanie

Na początku musimy trochę zmodyfikować package.json, który został wygenerowany za pomocą Angular CLI. Nasza aplikacja będzie budowana bezpośrednio na serwerze Heroku, dlatego musimy przenieść wymagane zależności z devDependencies do dependencies. W moim przypadku są to:

  • "@angular/cli": "^1.0.1"
  • "@angular/compiler-cli": "^4.1.0"
  • "typescript": "^2.3.1"

Dodatkowo, zadeklarujmy jaką wersję node i npm Heroku powinien wykorzystać do budowania aplikacji. Określamy to w następujący sposób:

"engines": {
  "node": "7.5.0",
  "npm": "4.1.2"
},

W przypadku nie zadeklarowania wersji node i  npm, Heroku użyje domyślnych. W chwili obecnej są to: node 6.10.3 i npm 3.10.10. Lokalnie korzystałem z node 7.5.0 i npm 4.1.2, więc aby wystrzec się błędów i różnic przy instalacji oraz kompilowaniu, zdecydowałem się na zadeklarowanie wersji, z których korzystam.

Budowanie aplikacji

Jeżeli przygotowaliśmy aplikację, przetestujmy czy uda się nam ją zbudować lokalnie. Do tego celu wykorzystamy komendę:

ng build --prod --aot

Parametr --prod oznacza wersję produkcyjną, natomiast --aot Ahead-of-time.

Polecam zerknąć na dokumentację Angular CLI, gdzie znajdziemy wszystkie atrybuty możliwe do wykorzystania podczas budowania aplikacji.

Jeżeli wszystko przebiegnie pomyślnie, zostanie utworzony folder dist/, a w nim znajdować się będzie kod wynikowy. Dodatkowo możemy przetestować poprawność budowania używając serwera http.

Angular app build

Na koniec tego etapu umieszczamy komendę do budowania aplikacji do skryptów. Zależy nam na tym, by Heroku automatycznie wykonało budowanie, więc skrypt nazywamy postinstall.

"scripts": {
  ...
  "postinstall": "ng build --prod --aot"
},

Utworzenie serwera

Do uruchomienia naszej aplikacji na Heroku wykorzystamy niezawodnego Express.js. Instalujemy framework poleceniem:

npm install express --save

Po pomyślnej instalacji, tworzymy prosty skrypt, który wypuści naszą aplikację na domyślny port Heroku czyli 8080:

const express = require('express');
const app = express();

app.use(express.static(__dirname + '/dist'));
app.listen(process.env.PORT || 8080);

Ostatnią czynność jaką musimy wykonać w tym etapie, to podmiana w package.json skryptu start:

"scripts": {
  ...
  "start": "node server.js"
},

Aplikacja na Heroku

Utworzenie aplikacji na Heroku zajmuje chwilę. Na początku wybieramy nazwę aplikacji oraz region gdzie nasza aplikacja będzie uruchomiona.

Heroku create app

Następnie w zakładce Deploy, mamy możliwość wybrania sposobu, w jaki nasza aplikacja ma być dystrybuowana. Mając repozytorium aplikacji w serwisie GitHub, zdecydowałem się na wybranie właśnie tego sposobu.

Heroku deploy app

Teraz możemy zdecydować, czy nasza aplikacja ma być automatycznie deployowana czy też nie. Nic nie stoi na przeszkodzie, by wykonać ręczny deploy w dowolnym momencie.

Heroku automatic deploys

Po wykonanym deployu możemy przejrzeć logi z budowania i uruchomić naszą aplikację.

Heroku log Shopping Manager Web

Migracja do Angular4

Angular4

Nowy Angular żyje i ma się nad wyraz dobrze. Efektem było wypuszczenie nieco ponad miesiąc temu wersji 4.0.0, z kolei zaledwie przedwczoraj wyszła wersja 4.1.0. W tym wpisie omówimy po krótce nową wersję oraz przeprowadzimy migrację z wersji Angular2 do Angular4.

Angular4 – co nowego?

Mniej znaczy szybciej

Projektanci frameworka postawili sobie za cel przyspieszenie oraz zredukowanie kodu wynikowego Angular4. Jak możemy przeczytać na oficjalnym blogu:

These changes reduce the size of the generated code for your components by around 60%  in most cases (..) During our release candidate period, we heard from many developers that migrating to 4 reduced their production bundles by hundreds of kilobytes

Animacje zostały wyciągnięte z @angular/core i umieszczone w osobnym pakiecie. By wykorzystać teraz animations, trzeba zaimportować paczkę BrowserAnimationsModule z pakietu @angular/platform-browser/animations.

Features

Na warsztat poszły dyrektywy *ngIf oraz *ngFor. Można od teraz po stronie HTMLa wykorzystywać składnię if/else:

TypeScript

Update przyniósł również wsparcie dla kolejnych wersji języka TypeScript. Angular4.0.0 jest zgodny z TypeScriptem 2.12.2. Z kolei przedwczorajszy update Angular4.1.0 przyniósł zgodność z TypeScriptem 2.22.3.

To tylko kluczowe zmiany. Zainteresowanych zachęcam do zerknięcia w CHANGELOG.

Migracja

Wpierw rzućmy okiem na nasz package.json. Interesują nas zależności @angular, zone.js oraz typescript.

Angular4 - before migration

Proces migracji zaczynamy od podniesienia TypeScriptu do najnowszej wersji:

npm install --save-dev typescript@latest

W moim przypadku musiałem podnieść także @angular/cli:

npm install --save-dev @angular/cli@latest

Przyszedł czas na zone.js:

npm install --save zone.js@latest

Ostatnim etapem jest podniesienie pozostałych wykorzystywanych paczek, u mnie będzie to kolejno:

npm install --save-dev @angular/compiler-cli@latest

oraz

npm install @angular/{common,compiler,core,forms,http,platform-browser,platform-browser-dynamic,router}@latest --save

Proces migrowania do wersji 4.1.0 przeszedł bez żadnych komplikacji. Kluczowym elementem jest niewielki rozmiar mojej aplikacji. Robiłem jednak wcześniej migrację dużo bardziej rozbudowanego systemu. Problemy, które wyniknęły w trakcie, nie blokowały mnie jednak w żadnym stopniu. Pamiętajmy, że nie powinniśmy zbytnio odwlekać w czasie, aktualizacji systemów, które utrzymujemy i tych które się ciągle rozwijają.

Na koniec jeszcze package.json po wszystkich update’ach:

Angular4 - after migration

Źródła:

  1. http://angularjs.blogspot.com/2017/03/angular-400-now-available.html
  2. http://angularjs.blogspot.com/2017/04/angular-410-now-available.html

Angular2 – HTTP – wysyłanie danych – @angular/http

wysyłanie danych

Wysyłanie danych w Angular2 jest możliwe dzięki metodzie post() z pakietu http. W tym wpisie wykorzystamy reaktywny formularz stworzony wcześniej i wyślemy dane na backend naszej aplikacji.

Wysyłanie danych – http.post()

Do wysłania danych użyjemy metody post() z poznanego już pakietu http.

post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response>

Post składa się z trzech parametrów: url, body oraz options. Jako pierwszy parametr podajemy adres URL endpointa w postaci ciągu znaków np. 'http://localhost:8001/product'. Następnie body, czyli dane, które chcemy wysłać. Ostatni parametr to opcje. Jak widać po deklaracji tylko url i body są wymagane.

Nawiązując do przykładu prosty http.post() w naszej aplikacji wygląda następująco:

Opcje – Options

Aby dodać options należy zaimportować Headers i RequestOptions. Obie klasy znajdują się również w paczce http.post().

Tworzymy lokalną zmienną headers, która zawiera zdefiniowane przez nas nagłówki. Następnie tworzymy opcje, w których umieszczamy headers. Tak przygotowaną zmienną, przekazujemy jako trzeci parametr w metodzie post.

Wysyłanie danych

Aby nasza metoda zadziałała, należy ją wykorzystać w metodzie onSubmit w formularzu.

Wykorzystujemy tutaj stworzoną wcześniej metodę create() z naszego repozytorium. Narazie wyświetlamy console.info jeżeli request zakończy się powodzeniem lub console.error w przypadku błędu.

wysyłanie danych - http - 201 - Created

wysyłanie danych - http - 404 - error