W artykule chciałbym poruszyć temat, który jest ważny dla nas wszystkich – wersjonowanie semantyczne, znane również jako Semantic Versioning albo SemVer.
SemVer to standard wersjonowania oprogramowania i niezależnie od tego, czy jesteś programistą dowolnej technologii, studentem, testerem, czy kimkolwiek zainteresowanym rozwojem oprogramowania, SemVer wpływa na nas wszystkich.
Korzystamy z SemVer, nawet jeśli nie zdajemy sobie z tego sprawy. Wersjonowanie oprogramowania ma kluczowe znaczenie dla stabilności, zgodności i efektywności naszych aplikacji. Dlatego chciałbym podzielić się z Tobą wiedzą na ten temat, abyś mógł jeszcze lepiej zrozumieć i wykorzystać ten standard w swojej pracy.
W tym artykule zaprezentuję nie tylko teoretyczne aspekty SemVer, ale także zapoznam Cię z jego praktycznym zastosowaniem. Dowiesz się, jak zarządzać zależnościami, aby zapewnić stabilność i bezpieczeństwo projektu. Przyjrzymy się również korzyściom wynikającym z konsekwentnego stosowania SemVer oraz wyzwaniom, na jakie możemy natrafić podczas implementacji.
Czym jest numeracja wersji i dlaczego jest ważna?
Numeracja wersji to sposób identyfikacji i odróżnienia różnych wersji oprogramowania. Każda nowa wersja otrzymuje unikalny numer, który pozwala nam śledzić i kontrolować zmiany. Dzięki numeracji wersji możemy stwierdzić, czy dana wersja oprogramowania jest aktualna, nowsza lub starsza. To szczególnie istotne przy wprowadzaniu zmian i udostępnianiu aktualizacji.
Wersje składają się z trzech cyfr: X.Y.Z
Przykładowo, weźmy pierwszą lepszą bibliotekę, np. React 😉 W dniu pisania tego artykułu najnowsza wersja to 18.2.0. Co oznaczają poszczególne cyfry?
Major
Pierwsza liczba – 18 – reprezentuje numer wersji głównej (major). Jej zwiększenie (np. z 17 do 18) wskazuje na wprowadzenie istotnych modyfikacji, które mogą wpływać na istniejące funkcje i wymagać dostosowania.
Przykład: Zmiana interfejsu użytkownika, nowe funkcjonalności, znaczne zmiany w strukturze kodu.
Minor
Druga cyfra – 2 – to numer wersji mniejszej (minor). Zwiększenie tego numeru (np. z 18.1 do 18.2) wskazuje na wprowadzenie nowych funkcji oprogramowania bez wpływu na istniejące.
Przykład: Dodanie nowego modułu, rozszerzenie istniejących funkcji, ulepszenie wydajności.
Patch
Trzecia cyfra – 0 – reprezentuje numer wersji poprawki (patch). Zwiększenie numeru wersji patch (np. z 18.2.0 do 18.2.1) wskazuje na wprowadzenie poprawek bez zmian w funkcjonalności.
Przykład: Naprawa znalezionych błędów, łatanie luk w zabezpieczeniach, poprawki interfejsu.
Rola oznaczania zmian
Oznaczanie zmian w wersjach ma ogromne znaczenie! Pamiętaj, że dokładne oznaczanie numerów wersji pomaga użytkownikom oprogramowania zrozumieć, jakie zmiany zostały wprowadzone w poszczególnych wersjach. Dzięki temu mogą świadomie decydować o aktualizacjach.
Oznaczanie zmian pozwala im śledzić, jakie modyfikacje zostały wprowadzone między kolejnymi wersjami, a także przewidzieć, jakie zmiany mogą mieć wpływ na istniejące rozwiązania. Dzięki takiej informacji można dostosować się do wprowadzanych zmian, aktualizować swoje aplikacje i unikać potencjalnych problemów.
W świecie programowania istnieje wiele bibliotek i modułów, które pomagają w tworzeniu aplikacji. Zarządzanie zależnościami jest kluczowe, aby nasz projekt działał sprawnie i był aktualny.
Wersjonowanie Semantyczne to standard wersjonowania, który zapewnia spójność i kontrolę nad wersjami używanych bibliotek.
W kolejnej części artykułu dowiesz się, jak deklarować zależności w projekcie i jak wykorzystać podstawowe operatory wersji.
Deklarowanie zależności
W celu określenia wymaganych bibliotek i modułów w aplikacji javascript, korzystamy z pliku konfiguracyjnego package.json. W pliku tym możemy zadeklarować nazwy zależności oraz określić szczególne, minimalne lub maksymalne wersje, które nasz projekt obsługuje.
W powyższym przykładzie widzimy deklarację trzech zależności:
- react,
- @reduxjs/toolkit,
- axios.
Przy każdej zależności możemy określić operator wersji, który pomoże nam zarządzać aktualizacjami.
Operator „^” (marchewka/caret)
Pozwala na aktualizację do najnowszej zgodnej zadeklarowanej wersji, zapewniając przy tym kompatybilność z nowymi funkcjonalnościami. Przykładowo, jeśli zadeklarujemy naszą bibliotekę React w następujący sposób „react”: „^18.1.0” to możemy być pewni, że podczas aktualizacji naszej aplikacji wersja biblioteki może być większa lub równa 18.1.0, ale też mniejsza od 19.0.0.
Operator „~” (tylda)
Umożliwia aktualizację do najnowszej wersji poprawiającej błędy, zachowując zgodność z deklaracją wersji. Przykładowo nasza biblioteka do obsługi stanu aplikacji zadeklarowana następująco „@reduxjs/toolkit”: „~1.8.4” będzie aktualizowana do wersji większej lub równej 1.8.4, ale mniejszej niż 1.9.0.
Dzięki operatorom możemy kontrolować, jakie aktualizacje bibliotek będą uwzględniane w naszym projekcie, jednocześnie zachowując stabilność i unikając niepożądanych zmian.
Jeśli nadal nie masz pewności jak to działa albo chcesz przetestować zadeklarowaną wersję, polecam bardzo fajne narzędzie do testowania dostępne na stronie npmjs.com.
Aktualizowanie wersji
Jest takie magiczne polecenie, które nie wszystkim jest znane, ale znacząco ułatwia proces podbijania wersji. Gdy po wprowadzeniu poprawek chcesz podbić wersję, np. modułu npm, masz do wyboru dwie metody. Możesz to zrobić na piechotę, zmieniając ręcznie plik package.json, albo skorzystać z polecenia npm version.
Oto trzy przykłady, które pokazują, jak to działa w praktyce:
- npm version patch – zwiększa numer wersji poprawki. Przykład: 1.0.0 -> 1.0.1.
- npm version minor – zwiększa numer wersji mniejszej. Przykład: 1.0.0 -> 1.1.0.
- npm version major – zwiększa numer wersji głównej. Przykład: 1.0.0 -> 2.0.0.
Polecenia te automatycznie aktualizują numer wersji w pliku package.json, a jako bonus tworzą nowy tag w repozytorium Git.
Dziękuję, że tutaj dotarłeś!
Mam nadzieję, że podzieliłem się z Tobą wartościową wiedzą i że to, co przeczytałeś, rzeczywiście wpłynie na Twoją efektywność. Wersjonowanie Semantyczne pozwala nam klarownie i jednoznacznie komunikować zmiany w naszym oprogramowaniu. Dzięki precyzyjnie określonym zasadom, zarówno użytkownicy oprogramowania, jak i członkowie zespołu są w stanie łatwo zrozumieć, jakie zmiany wprowadza dana wersja. To ułatwia proces aktualizacji, rozwiązywanie problemów i zapewnianie stabilności projektu.
Nieprawidłowe stosowanie wersjonowania może prowadzić do niejasności, konfuzji i problemów związanych z zależnościami w projekcie. Jeśli nie deklarujemy zależności zgodnie z zasadami SemVer, możemy przypadkowo wprowadzić niekompatybilne zmiany, co może doprowadzić do błędów lub awarii w naszym oprogramowaniu.
Nie mniej poprawne stosowanie SemVer przyniesie korzyści zarówno nam, jak użytkownikom naszego oprogramowania. Dbałość o jasne oznaczenie zmian i odpowiednie zarządzanie zależnościami wpłynie na stabilność, bezpieczeństwo i efektywność naszych projektów.
Dziękuję za poświęcony czas i zapraszam do dalszego zgłębiania tematu SemVer. To ważne narzędzie, które ma bezpośredni wpływ na naszą pracę, więc bądźmy świadomi jego wartości i wykorzystujmy je w praktyce.
***
Jesli ciekawią Cię narzędzia wykorzystywane w IT, zajrzyj również do innych artykułów naszych ekspertów.
„Pierwsza cyfra – 18” – liczba, nie cyfra…
„Przykład: Zmiana interfejsu użytkownika, nowe funkcjonalności, znaczne zmiany w strukturze kodu.” – nowe funkcjonalnosci to nie „major”, tylko „minor”, usuniecie funkcjonalnosci – tak. Zmiany w strukturzekodu to tez nie major – chyba ze wplywaja na API, ktore jest wystawione na swiat (interfejsy, API restowe).
„Trzecia cyfra – 0 – reprezentuje numer wersji poprawki (patch). Zwiększenie numeru wersji patch (np. z 18.2.0 do 18.2.1) wskazuje na wprowadzenie poprawek bez zmian w funkcjonalności.” – nie do konca, czasem fixy bugow wchodza jako patche, mimo ze funkcjonalnosc sie zmienia wtedy.
Dziękuję, „cyfra” poprawiona. A propos pozostałych kwestii poczekajmy na komentarz autora 🙂
W imieniu autora:
Dziękuję za Twój komentarz i zaangażowanie w dyskusję.
W kontekście wersji głównej (major), wspomniałem o zmianie interfejsu użytkownika, nowych funkcjonalnościach i znacznych zmianach w strukturze kodu jako o zespole czynników, które mogą kwalifikować wersję jako główną. To prawda, że nie każda nowa funkcjonalność czy zmiana w kodzie automatycznie kwalifikuje się jako zmiana wersji głównej, ale w połączeniu z innymi istotnymi modyfikacjami, jak zmiana interfejsu użytkownika, może to stanowić podstawę do wydania nowej wersji głównej.
Masz rację, że czasem poprawki bugów wprowadzane jako patche mogą wpłynąć na funkcjonalność, jak zauważyłeś w swoim komentarzu. Te sytuacje są jednak raczej wyjątkami od reguły. W większości przypadków, patche są przeznaczone do drobnych korekt, które nie zmieniają znacząco funkcjonalności oprogramowania. Moja wypowiedź była uproszczeniem mającym na celu ułatwienie zrozumienia tematu dla szerokiej grupy odbiorców.