O migracji do Angulara, czyli debiut w świecie open-source

O migracji do Angulara, czyli debiut w świecie open-source

Niedawno pracując przy jednym z projektów które współtworzę natrafiłem na zadanie wymagające żmudnej, manualnej pracy powtarzanej w ten sam sposób w kilkunastu plikach. Postanowiłem, że z odrobiną wysiłku mogę zautomatyzować cały proces dedykowanym narzędziem, które być może przyda się również innym programistom w podobnej sytuacji. Jeśli jesteście zainteresowani jaki problem rozwiązywałem oraz co w efekcie tego procesu powstało, to zapraszam do dzisiejszego posta!

Nowy Angular – nowe przygody

Moment wydania Angulara 2 (dobrych kilkanaście miesięcy temu) był momentem szczególnym dla całego środowiska angularowego. Jego twórcy przedstawili nam bowiem wersję frameworka, do której de facto nie dało się zmigrować inaczej niż przepisując cały projekt na nowo. Dzisiaj, w dobie możliwości równoległego uruchamiania dwóch wersji Angulara na jednej stronie ta sytuacja wygląda nieco lepiej, jednak w pewnym obszarze wciąż mamy braki – myślę tutaj o migracji template’ów komponentów, których składnia zmieniła się w sposób zdecydowany.

Nie dostaliśmy niestety oficjalnego narzędzia, dzięki któremu w łatwy sposób moglibyśmy zaktualizować nasze template’y, dlatego kwestią czasu było stworzenie biblioteki która ten problem rozwiąże. Tak się składa, że z braku dostępnego narzędzia niedawno samemu stworzyłem taką bibliotekę, którą dzisiaj możecie pobrać z npm’a, a w dzisiejszym poście chciałbym pokazać wam, jak wy sami możecie publikować rozwiązania problemów które dotykają was w codziennej pracy z kodem.

W czym rzecz?

Problem, z którym mierzą się programiści migrujący swoje projekty z AngularJS’a do Angulara (tak tak, to dwa różne frameworki), wygląda mniej więcej tak:

Składnia dyrektyw wg frameworka AngularJS:

Składnia dyrektywy wg frameworka Angular:

Dyrektywy to m.in. atrybuty takie jak ng-if, *ngIf czy ng-repeat, dzięki którym używając Angulara możemy rozszerzyć możliwości danego elementu w DOMie. Jak widać na powyższych fragmentach, zmiany składni blokują możliwość używania dyrektyw z AngularJS w widokach nowego Angulara (ng-if to teraz *ngIf, itd.). Na szczęście lista standardowych dyrektyw których postać została zmieniona została przez twórców Angulara zdefiniowana i znajduje się na stronie:

https://angular.io/guide/ajs-quick-reference

Przeglądając powyższą stronę możemy stwierdzić, że problem o którym piszę nie jest tak naprawdę problemem poważnym. Możemy przecież otworzyć nasz projekt i wspomagając się dokumentacją przenosić nasze dyrektywy jedna po drugiej.

Na początku również mi się tak wydawało, jednak kilka plików i kilkanaście dyrektyw później stwierdziłem, że albo cały proces zautomatyzuję, albo po prostu rzucę to w kąt. Postawiłem na automatyzację.

Automatyzować – ale jak?

No dobrze – ale właściwie co chcę stworzyć? Zdecydowałem, że z powodu obracania się w obszarach frontendowo-npmowych najbardziej rozsądnym wyborem będzie node.js, a konkretnie biblioteka do wykorzystania w tym właśnie środowisku.

Strona z przykładami zmian konkretnych dyrektyw działa w moim przypadku jak lista wymagań, które biblioteka automatyzująca cały proces musi spełnić, aby przynosić realną wartość. Przez fakt, że wymagania te są określone w tak konkretny sposób, od razu przyszło mi do głowy podejście TDD – najpierw napiszę testy, a potem kod im odpowiadający. W ten sposób będę miał pewność, że transformacje przewidziane przez twórców Angulara są faktycznie realizowane przez moją bibliotekę.

Sama biblioteka działa w sposób dość niskopoziomowy, ponieważ starałem utrzymać stosunkowo proste API. Całe użycie sprowadza się do wywołania jednej funkcji, której parametrem jest template (string) z AngularJS’a oraz opcje jego transformacji. Na wyjściu dostajemy string z template’em w formacie z nowego Angulara.

Taki fragment kodu opakowałem linijkami (które nie znajdują się w samej bibliotece) w których przechodzę po kolejnych folderach mojego projektu, sprawdzam czy w danym katalogu znajduje się template do zaktualizowania i jeśli tak, to “przepuszczam go” przez moją bibliotekę. Wczytuję jego zawartość z pliku, transformuję, a następnie zapisuję w to samo miejsce. Tym sposobem template w formacie AnguarJS zamienia się na template wykorzystujący dyrektywy nowego Angulara.

Pierwsza wersja biblioteki i podstawowe testy zajęły mi kilka godzin, a efekt znacząco przyśpieszył proces migracji mojego projektu. Biblioteka o wdzięcznej nazwie create-angular-template spełniła swoje zadanie.

W tym momencie pomyślałem, że być może to odpowiedni czas, żeby podzielić się swoim projektem ze światem – zamiast czytania i słuchania o open-source, może warto spróbować wydać coś samemu?

Świecie open-source, szykuj się

Zaczęło się dość klasycznie – dla mojej biblioteki powstało publiczne repozytorium na GitHubie. Mając założone repozytorium mogłem uzupełnić kilka pól w pliku package.json, takich jak:

Następnym krokiem było faktyczne opublikowanie mojego narzędzia. Cały proces jest dokładnie opisany w oficjalnej dokumentacji i tak naprawdę składa się z dwóch kroków:

  • utworzenie użytkownika
  • publikacja paczki

Zajmuje to jakieś… 10 minut.

Po przejściu całego procesu publikacji mogłem już odwiedzić stronę dedykowaną mojej bibliotece w npmie:

Dla kogoś, kto mógł się pochwalić liczbą opublikowanych narzędzi równą zeru, widok własnej paczki w npmie robił spore wrażenie. Kurcze… do teraz się tym jaram! 🔥

Co dalej?

Kolejną rzeczą na mojej liście zadań związanych z tą biblioteką było przekonanie ludzi, że to naprawdę działa – projekt się buduje, a dodatkowo ma rozsądne pokrycie testami. W tym celu w README projektu chciałem zawrzeć tzw. shieldsy, czyli odznaki które informują o poszczególnych aspektach związanych z jakością mojego projektu. Więcej o nich na shields.io.

Zależało mi na dodaniu dwóch informacji – pierwszej o stanie brancha master, i drugiej o stopniu pokrycia kodu testami. Aktualnie wygląda to w tej sposób:

Jaka jest rola takich elementów? Pokazują one osobom “z zewnątrz”, że warto poświęcić więcej niż pięć sekund na zainteresowanie się danym narzędziem. Projekt się buduje, ma całkiem rozsądne pokrycie testami – można czytać czym dana rzecz tak naprawdę jest.

W jaki sposób możemy więc wzbogacić nasze projekty o takie shieldsy?

Informację o stanie builda pobierzemy z Travisa, czyli narzędzia do ciągłej integracji naszego kodu. Podstawowa konfiguracja Travisa i jego integracja z GitHubie jest niemal automatyczna – logujemy się kontem z GitHuba, dzięki czemu Travis ma dostęp do naszych publicznych repozytoriów. Będąc zalogowanym wybieramy jakie projekty chcemy integrować a następnie podążamy za krokami w instrukcji:

Po zaznaczeniu odpowiedniego repozytorium z naszym projektem pozostaje nam jeszcze dodać do niego plik .travis.yml, w którym zdefiniujemy w jaki sposób Travis ma go budować:

Oczywiście konfiguracja może być o wiele bardziej rozbudowana, jednak na teraz wystarczy mi tylko tyle ile widać na powyższym fragmencie. Zdefiniowałem tam platformę czyli node.js, wersję (8), a następnie dwa kroki budowania naszego projektu – npm install oraz npm run check (w trakcie którego uruchamiam linter kodu, oraz testy). Jeśli wykonanie tych dwóch poleceń przebiegnie bezproblemowo, to Travis oznaczy nasz projekt jako “budujący się”. Dodatkowo pod poniższym adresem znajdziemy grafikę w formacie svg, która na bieżąco będzie oddawać stan brancha master, oraz którą możemy dodać do naszego README:

https://travis-ci.org/psmyrdek/create-angular-template.svg?branch=master

A co z pokryciem kodu testami? Do wygenerowania etykiety z tą informacją wykorzystałem serwis coveralls.io, który jest odpowiednikiem Travisa, skupionym na śledzeniu dokładnie tej metryki związanej z testami. Coveralls konfigurujemy w taki sam sposób, zakładając konto i wybierając projekt którego metryki chcemy śledzić:

Samo dodanie projektu nie wystarczy – serwis musi się przede wszystkim dowiedzieć jak to faktyczne pokrycie testami wygląda.

Metryka ta w moim przypadku opiera się o raport pokrycia kodu wygenerowany przez framework Jest, który jest moim podstawowym narzędziem do testowania biblioteki o której piszę w dzisiejszym poście. Raport z Jesta prezentuje się następująco (polecenie jest z flagą –coverage):

Taki raport możemy teraz zapisać w folderze coverage tworzonym w trakcie budowania projektu w Travisie, a następnie za pomocą biblioteki node-coveralls przesłać go do usługi coveralls (znalezione tutaj):

Z informacjami zapisanymi w coveralls.io możemy teraz za pomocą tego samego serwisu pobrać link do naszego badga informującego o pokryciu kodu testami:

https://coveralls.io/repos/github/psmyrdek/create-angular-template/badge.svg?branch=master

…i dorzucić to do README. Gotowe! Informacje o pracy którą włożyliśmy w podniesienie jakości naszego kodu są od teraz dostępne na wyciągnięcie ręki.

Chociaż to dopiero początek…

Publikacja własnego narzędzia była czymś, co chodziło za mną od dłuższego czasu. Brakowało tylko… problemu wartego rozwiązania. Przy migracji projektu do Angulara 5 taki problem się pojawił, no i pojawiło się też publicznie dostępne rozwiązanie.

Bibliotekę create-angular-template, której poświęciłem dzisiejszy wpis, możecie znaleźć w dwóch miejscach:

Wszystkich zainteresowanych tematem migracji do Angulara zachęcam do zapoznania się z moim narzędziem, a w przypadku konkretnego użycia i ew. problemów – do tworzenia GitHubowych issues’ów. Razem zastanowimy się jak daną kwestię rozwiązać, a wspólnym wysiłkiem będziemy mogli ulepszyć to narzędzie zdecydowanie łatwiej i szybciej. Contributors welcomed!

Dzisiejszym postem chciałbym też zachęcić was do wypróbowania takich narzędzi jak Travis i Coveralls. Ich interfejs użytkownika jest na tyle intuicyjny, że proste konfiguracje jesteście w stanie stworzyć kilkoma kliknięciami myszy. Będzie to dobry wstęp do tematu ciągłej integracji kodu oraz budowania waszych projektów przez zewnętrzne usługi CI / CD.

Dodatkowo, celem nieco bardziej ambitnym jest opublikowane waszych własnych narzędzi w npm – być może w waszych szufladach leżą projekty którymi chcielibyście zainteresować świat, a do tej pory wydawało wam się to skomplikowane? Rozbudowując wasze CV o takie projekty możecie jedynie zyskać!

 

Powiązane

JavaScript poza przeglądarką – wprowadzenie ... W której części aplikacji webowej swoją rolę odgrywa JavaScript? Pierwsza poprawna odpowiedź brzmi - w części aplikacji uruchamianej po stronie klient...
Automatyzacja backupów w Node.js, czyli potrzeba m... Stare porzekadło mówi, że istnieją dwa rodzaje ludzi - ci, którzy robią kopie zapasowe, oraz ci, którzy będą je robić. Backupy i innego rodzaju za...
Jak wykorzystać tryb offline do zwiększenia możliw... Niedawno pisaliśmy na naszym blogu o PWA, czyli nowej fali aplikacji webowych które sposobem działania przypominają to, co znamy z natywnych aplikacji...
Artykuły o .Net i Javascript – DDZ #4 Paczka wartościowych materiałów, które możecie znaleźć w sieci. Jeżeli chcesz zapoznać się z pozostałymi ciekawymi linkami możesz zrobić to tutaj....