<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	 xmlns:media="http://search.yahoo.com/mrss/" >

<channel>
	<title>JavaScript &#8211; Nearshore Software Development Company &#8211; IT Outsourcing Services</title>
	<atom:link href="https://nearshore-it.eu/pl/tag/javascript-pl/feed/" rel="self" type="application/rss+xml" />
	<link>https://nearshore-it.eu/pl/</link>
	<description>We are Nearshore Software Development Company with 14years of experience in delivering a large scale IT projects in the areas of PHP, JAVA, .NET, BI and MDM.</description>
	<lastBuildDate>Thu, 07 Nov 2024 14:22:10 +0000</lastBuildDate>
	<language>pl-PL</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>

<image>
	<url>https://nearshore-it.eu/wp-content/uploads/2023/01/cropped-inetum-favicon-300x300-1-32x32.png</url>
	<title>JavaScript &#8211; Nearshore Software Development Company &#8211; IT Outsourcing Services</title>
	<link>https://nearshore-it.eu/pl/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Gulp vs Webpack. Którego narzędzia używać w projekcie?   </title>
		<link>https://nearshore-it.eu/pl/artykuly/gulp-vs-webpack-ktorego-z-nich-uzywac-w-projekcie/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/gulp-vs-webpack-ktorego-z-nich-uzywac-w-projekcie/#respond</comments>
		
		<dc:creator><![CDATA[Maciej Woźnica]]></dc:creator>
		<pubDate>Wed, 23 Aug 2023 03:07:00 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Application development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/gulp-vs-webpack-ktorego-z-nich-uzywac-w-projekcie/</guid>

					<description><![CDATA[Webpack vs Gulp: czym się różnią?  Porównaj oba narzędzia i poznaj ich funkcjonalności, które z pewnością ułatwią ci pracę i zwiększą produktywność.]]></description>
										<content:encoded><![CDATA[
<div class="table-of-contents">
    <p class="title">Przejdź do:</p>
    <ol>
                    <li><a href="#SCSS-vs-CSS-–-podstawyu002du002d">1.  SCSS vs CSS – podstawy </a></li>
                    <li><a href="#Instalacja-Webpackau002du002d">2.  Instalacja Webpacka  </a></li>
                    <li><a href="#Instalowanie-Gulpau002du002d">3.  Instalowanie Gulpa  </a></li>
                    <li><a href="#Konfiguracja-Webpackau002du002d-">4.  Konfiguracja Webpacka </a></li>
                    <li><a href="#Konfiguracja-Gulpau002du002d-">5.  Konfiguracja Gulpa </a></li>
                    <li><a href="#Obsługa-narzędzi-Gulp-vs-Webpack-–-porównanieu002du002d">6.  Obsługa narzędzi Gulp vs Webpack – porównanie </a></li>
                    <li><a href="#Które-narzędzie-wybrać:-Gulp-czy-Webpack?u002du002d-">7.  Które narzędzie wybrać: Gulp czy Webpack?</a></li>
                    <li><a href="#Gulp-vs-Webpack-–-podsumowanieu002du002d-">8.  Gulp vs Webpack – podsumowanie   </a></li>
            </ol>
</div>


<p><strong>Webpack vs Gulp</strong>&#8230; Oba te narzędzia odgrywają ważną rolę w świecie programistycznym. Wybór między nimi często na pierwszy rzut oka wydaje się trudny. Zwłaszcza na początku przygody z programowaniem. Jednak jeśli poznamy ich różnice i podobieństwa, z pewnością będzie łatwiej podjąć właściwą decyzję.</p>



<p>Bez względu na to, czy rozważasz użycie <strong>Gulpa (task runner)</strong>, <strong>Webpacka (module bundler)</strong>, czy może kombinacji obu, znajomość ich funkcjonalności z pewnością ułatwi ci pracę i zwiększy produktywność. Jeśli zatem szukasz odpowiednich narzędzi do swojego projektu, koniecznie przeczytaj ten artykuł.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image size-full">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/blog_2023.08.23_graphic_1.png" alt=" class=" class="wp-image-12066" title="Gulp vs Webpack. Którego narzędzia używać w projekcie?    1"></figure></div>


<div style="height:32px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading" id="SCSS-vs-CSS-–-podstawy--">SCSS vs CSS – podstawy &nbsp;</h2>



<p>Zanim porównam narzędzia Webpack i Gulp, przypomnijmy sobie, czym są technologie CSS i SCSS. Są one niezbędne w programowaniu na front-endzie.</p>



<p>CSS i SCSS to technologie, których na co dzień używamy do przypisywania konkretnych wyglądów do elementów (kolor, rozmiar) i rozmieszczania tych elementów na stronie. Ważne jest jednak, aby przed podjęciem decyzji o skorzystaniu z wybranej z nich wziąć pod uwagę pewne różnice.</p>



<p><strong> CSS to standardowy język arkuszy stylów, </strong>mający ugruntowaną pozycję <strong>w świecie front-endowym</strong>. W porównaniu z SCSS jego składnia wydaje się prostsza i o wiele bardziej intuicyjna. Młodsi programiści zdecydowanie stawiają na CSS, szczególnie na wczesnym etapie nauki. Reguły CSS mają na celu zdefiniowanie stylów dla określonych elementów, takich jak paragrafy, divy czy inne elementy HTML.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">/* Składnia CSS */  

h1 { color: blue; font-size: 24px; } </pre>



<p><strong>SCSS </strong>jest niczym innym jak preprocesorem CSS, to znaczy <strong>rozszerza składnię o dodatkowe funkcje i pozwala na wykorzystanie zaawansowanych technik</strong>, w tym takich jak: </p>



<ul class="wp-block-list">
<li><strong>reguły zagnieżdżania</strong> – selektory CSS można zagnieżdżać w innych, odzwierciedlając strukturę selektorów HTML.&nbsp;</li>



<li><strong>użycie zmiennych</strong> (które umożliwiają przechowywanie wartości wielokrotnego użytku w arkuszu stylów),&nbsp;</li>



<li><strong>operatory matematyczne </strong>(pozwalające na dodawanie, odejmowanie, mnożenie i dzielenie wartości w stylach), dzięki czemu jest łatwiej pisać kod i staje się on bardziej modułowy i po prostu elegancki.&nbsp;</li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">/* Składnia SCSS z zagnieżdżaniem i zmiennymi */ 

$primary-color: blue; 

  

h1 {  

  kolor: $primary-color; 

  font-size: 24px; 

} </pre>



<h3 class="wp-block-heading">Kluczowe różnice między SCSS i CSS: &nbsp;</h3>



<ol start="1" class="wp-block-list">
<li><strong>Składnia:</strong> SCSS oferuje bardziej rozszerzoną składnię, co ułatwia pisanie i utrzymanie kodu. Reguły zagnieżdżania pozwalają pisać bardziej czytelny i logiczny kod. &nbsp;</li>



<li><strong>Zmienne:</strong> SCSS umożliwia definiowanie zmiennych, ułatwiając zmienianie wartości stylu w jednym miejscu i tym samym przyczyniając się do spójności w całym projekcie.&nbsp;</li>



<li><strong>Preprocesor: </strong>SCSS jest jednym z wielu preprocesorów CSS (to znaczy, że kod SCSS musi zostać skompilowany do zwykłego CSS przed wdrożeniem na stronie internetowej). &nbsp;</li>
</ol>



<p>Wybór między SCSS i CSS zależy od tego, na ile złożony jest projekt i jakie są umiejętności zespołu projektowego. W przypadku niezłożonych projektów, które nie wymagają zaawansowanych technik ostylowania, CSS może okazać się odpowiednim wyborem. Jednak w przypadku bardziej złożonych projektów, które wymagają modułowości i łatwego edytowania, <strong>SCSS pozwoli na większą elastyczność i wygodę w zarządzaniu stylami</strong>. &nbsp;</p>



<p><strong>Przeczytaj także:</strong>&nbsp;</p>



<ul class="wp-block-list">
<li><a href="https://nearshore-it.eu/pl/artykuly/testowanie-rxjs-marble-testing/" target="_blank" data-type="URL" data-id="https://nearshore-it.eu/pl/artykuly/testowanie-rxjs-marble-testing/" rel="noreferrer noopener"><strong>Marble testing. Testowanie RxJS</strong>&nbsp;&nbsp;</a></li>



<li><a href="https://nearshore-it.eu/pl/artykuly/jesli-nie-redux-to-co-zarzadzanie-stanem-aplikacji-w-react/" target="_blank" rel="noreferrer noopener"><strong>Jeśli nie Redux, to co? Zarządzanie stanem aplikacji w React</strong></a>&nbsp;<br><strong></strong>&nbsp;</li>
</ul>



<h2 class="wp-block-heading" id="Instalacja-Webpacka--">Instalacja Webpacka &nbsp;</h2>



<p>Funkcje Webpacka pozwalają przede wszystkim na zarządzanie zależnościami i porządkowanie plików. Instalacja narzędzia to naprawdę “bułka z masłem”. Zaczynamy od sprawdzenia, czy jest już zainstalowany <strong>Node Package Manager (NPM)</strong>, który moim zdaniem umożliwia najskuteczniejszą i najszybszą instalację Webpacka. Następnie otwieramy wiersz poleceń i wpisujemy: &nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">npm install webpack –g </pre>



<p>Z wiersza poleceń przechodzimy do katalogu z naszym projektem i wpisujemy polecenie: &nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">npm init </pre>



<p>Możemy tu zauważyć, że w katalogu docelowym został utworzony plik <strong>package.json</strong>. Nie pozostaje nic innego, jak tylko zainstalować Webpacka w naszym projekcie: &nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">npm install --save-dev webpack </pre>



<p>A teraz już możemy cieszyć się ogromnymi możliwościami narzędzia! &nbsp;</p>



<p>W dalszych krokach konfiguracja zależy od potrzeb konkretnego projektu – w punktach poniżej opiszę przykładową, krótką konfigurację. Szczegółowe wytyczne dotyczące możliwości Webpacka można znaleźć w oficjalnej dokumentacji na stronie: Webpack Documentation. &nbsp;</p>



<h2 class="wp-block-heading" id="Instalowanie-Gulpa--">Instalowanie Gulpa &nbsp;</h2>



<p>Gulp stosuje się do automatyzacji niektórych zadań, takich jak kompilacja, minifikacja plików, obrazów lub odświeżanie przeglądarki. Instalacja Gulpa jest tak samo łatwa jak w przypadku Webpacka. Upewniamy się, że mamy zainstalowany NPM. I zaczynamy od polecenia: &nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">npm install -g gulp </pre>



<p>Przechodzimy do naszego katalogu projektów, potem tworzymy plik package.json za pomocą polecenia: &nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">npm init </pre>



<p>Wystarczy teraz dodać Gulpa do naszego projektu: &nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">npm install ---save-dev gulp  </pre>



<p>Jak skonfigurować Webpacka? Po instalacji możemy przystąpić do tworzenia pliku gulpfile.js. Będzie on odpowiadał za konfigurację zadań dla naszego narzędzia. W dalszej części przedstawię również krótką konfigurację dla Gulpa. &nbsp;</p>



<p>Aby poznać wszystkie możliwości Gulpa,<a href="https://gulpjs.com/docs/en/getting-started/quick-start" target="_blank" data-type="URL" data-id="https://gulpjs.com/docs/en/getting-started/quick-start" rel="noreferrer noopener"> skorzystaj z dostępnej dokumentacji</a>.&nbsp;</p>



<h2 class="wp-block-heading" id="Konfiguracja-Webpacka---">Konfiguracja Webpacka  &nbsp;</h2>



<p>Jak wspomniałem wcześniej, przedstawię krótką konfigurację Webpacka. Narzędzie jest na tyle zaawansowane, że nie da rady opisać tu wszystkich jego możliwości. &nbsp;</p>



<p>Zacznijmy od dodania pliku webpack.config.js, który zawiera całą konfigurację Webpacka. &nbsp;</p>



<p>Następnie umieśćmy tam podstawową konfigurację: &nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">module.exports = { 

  entry: './src/main.js', 

  output: { 

    path: __dirname + '/dist',  

    filename: 'bundle.js'  

  },  

  mode: 'production' 

};</pre>



<p>Zdefiniowaliśmy, skąd Webpack ma pobierać pliki źródłowe (<strong>entry</strong>). <strong>Output </strong>określa, gdzie powinny być umieszczone po przetworzeniu. Opcja <strong>mode </strong>określa, czy chcemy zoptymalizować kod, na przykład pod kątem produkcji. Webpack zapewnia szeroki pakiet wtyczek i loaderów, co pozwala dostosować go do naszych potrzeb. &nbsp;</p>



<h2 class="wp-block-heading" id="Konfiguracja-Gulpa---">Konfiguracja Gulpa  &nbsp;</h2>



<p>Gulp to narzędzie do automatyzacji zadań, które możemy odpowiednio dostosować w pliku <strong>gulpfile.js</strong>. W czasie konfiguracji definiujemy takie zadania, jak: minifikacja kodu, kompilacja czy odświeżanie przeglądarki po każdej zmianie w kodzie. &nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const gulp = require('gulp'); 

const uglify = require('gulp-uglify'); 


gulp.task('compress', function() {  

  return gulp.src('src/js/*.js') 

    .pipe(uglify()) 

    .pipe(gulp.dest('dist/js')); 

});</pre>



<p>To przykładowa konfiguracja mająca za zadanie skompresowanie plików JavaScript. &nbsp;</p>



<p>Zaczynamy od stworzenia nowego zadania o nazwie <strong>„Compress”</strong>. Następnie, <strong>za pomocą returngulp.src (&#8217;src/js/*.js&#8217;)</strong>, określamy pliki źródłowe do przetworzenia (w naszym przypadku będą to wszystkie pliki z rozszerzeniem .js, z katalogu src/js).&nbsp;</p>



<p>Kolejny krok to przekazanie plików źródłowych do wtyczki za pomocą <strong>pipe(uglify())</strong>, który kompresuje kod, usuwając np. zbędne spacje, komentarze, tak aby plik był możliwie jak najmniejszy.&nbsp;</p>



<p>Na koniec wskazujemy katalog do zapisywania przetworzonych plików.&nbsp;&nbsp;</p>



<h2 class="wp-block-heading" id="Obsługa-narzędzi-Gulp-vs-Webpack-–-porównanie--">Obsługa narzędzi Gulp vs Webpack – porównanie &nbsp;</h2>



<p>Jeśli miałbym porównać Webpack i Gulp, trudno wskazać jeden słuszny wybór – wszystko zależy od projektu, w którym pracujemy.&nbsp;</p>



<p>Webpack to w głównej mierze pakiet do kompilacji zasobów projektu, tak aby zyskać przejrzystość. Dzięki wtyczkom można łatwo go rozszerzyć i zyskać wachlarz zastosowań, takich jak: &nbsp;</p>



<ul class="wp-block-list">
<li><strong>Transpilacja </strong>– w przypadku JavaScript np. dostosowanie wersji ES6 do starszych przeglądarek&nbsp;</li>



<li><strong>Minifikacja kodu</strong><strong> </strong>(usuwanie niepotrzebnych znaków z kodu, aby zmniejszyć rozmiar, a tym samym poprawić czas ładowania)&nbsp;</li>



<li><strong>Zarządzanie zależnościami</strong>&nbsp;</li>
</ul>



<p>Sprawdź, jakie wtyczki są dostępne dla Gulpa: <a href="https://gulpjs.com/docs/en/getting-started/using-plugins/" target="_blank" rel="noreferrer noopener"><strong>Korzystanie z wtyczki</strong></a><strong> </strong> &nbsp;</p>



<p>Gulp to jednak także narzędzie do automatyzacji zadań, które bardzo usprawnia przepływ pracy. Moim zdaniem bardzo łatwo nauczyć się korzystać z tego narzędzia. Całkiem szybko możemy zacząć tworzyć zadania dla kompilacji plików <strong>SASS </strong>lub <strong>automatycznego odświeżania </strong>przeglądarki. Konfiguracja jest o wiele bardziej czytelna i elastyczna. &nbsp;</p>



<p>Webpack doskonale radzi sobie z zależnościami, natomiast Gulp wyróżnia się na tle innych narzędzi, jeśli chodzi o pełną automatyzację pracy (jeśli na tym ci właśnie zależy). &nbsp;</p>



<p>W skrócie: &nbsp;</p>



<ul class="wp-block-list">
<li><strong>Webpack </strong>pozwala na łączenie modułów. Ale też, tak jak Gulp, umożliwia uruchamianie wielu funkcji dotyczących zadań&nbsp;</li>
</ul>



<ul class="wp-block-list">
<li><strong>Gulp </strong>to narzędzie do automatyzowania zadań, które usprawnia przepływ pracy&nbsp;</li>
</ul>



<h2 class="wp-block-heading" id="Które-narzędzie-wybrać:-Gulp-czy-Webpack?---">Które narzędzie wybrać: Gulp czy Webpack?  &nbsp;</h2>



<p>Wybór pomiędzy nimi zależy od konkretnych potrzeb i architektury naszego projektu. To też kwestia prywatnych preferencji i doświadczenia. Jeśli łączenie i zarządzanie zależnościami są złożone i będą istotne w procesie rozwoju oprogramowania, Webpack może okazać się właściwym rozwiązaniem. Z drugiej strony, jeśli potrzebujmy prostego i czytelnego sposobu na automatyzację typowych zadań programistycznych, Gulp będzie do tego doskonały. &nbsp;</p>



<p>Pamiętaj, że nic nie stoi na przeszkodzie, aby oba narzędzia połączyć. Korzystanie z <strong>Gulpa i Webpacka jednocześnie</strong> oznacza dostęp do zalet każdego z nich. Wpłynie to pozytywnie nie tylko jakość projektu, ale też <strong>pozwoli skrócić czas potrzebny na rozwój oprogramowania</strong>. &nbsp; &nbsp;</p>



<h3 class="wp-block-heading">Użycie Webpacka zamiast Gulpa&nbsp;</h3>



<p>W połączeniu ze skryptami NPM Webpack może z powodzeniem zastąpić Gulpa. Z mojego doświadczenia wynika jednak, że lepiej łączyć narzędzia, niż ograniczać się tylko do jednego, do czego was zachęcam. Jak już wspomniałem, Webpack i Gulp to narzędzia do budowania (<strong>build tools)</strong>, które można wykorzystywać do podobnych zadań. Cechują się jednak różnymi podejściami i każde z nich ma inne mocne strony.&nbsp;&nbsp;</p>



<p>Koniec końców wybór między korzystaniem z samego Webpacka lub połączeniem go z Gulpem będzie zależeć od twojego projektu i twoich własnych preferencji programistycznych. &nbsp;</p>



<h2 class="wp-block-heading" id="Gulp-vs-Webpack-–-podsumowanie---">Gulp vs Webpack – podsumowanie  &nbsp;</h2>



<p>Mam nadzieję, że udało mi się przemycić w artykule korzyści płynące z używania Webpacka i Gulpa. Co do pytania „<strong>Webpack czy Gulp?</strong>”, tu nie ma idealnej odpowiedzi, zwłaszcza jeśli jesteś początkującym front-end developerem. Ten artykuł to tak naprawdę wprowadzenie do tych narzędzi – na każdym etapie warto wspierać się dokumentacją, wiedzą doświadczonych kolegów z projektu, a także Technical Leaderów.&nbsp; &nbsp;</p>



<p>Dokonując wyboru, najlepiej skupić się na swoich umiejętnościach, doświadczeniu i potrzebach projektowych. Nie ma uniwersalnego rozwiązania. Często ekosystem jest narzucany odgórnie. Warto więc eksperymentować z obiema technologiami, łączyć je, testować i tworzyć zoptymalizowane, wydajne środowisko. &nbsp;</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/gulp-vs-webpack-ktorego-z-nich-uzywac-w-projekcie/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Marble testing – wszystko o testowaniu RxJS</title>
		<link>https://nearshore-it.eu/pl/artykuly/testowanie-rxjs-marble-testing/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/testowanie-rxjs-marble-testing/#respond</comments>
		
		<dc:creator><![CDATA[Maciej Woźnica]]></dc:creator>
		<pubDate>Wed, 24 May 2023 10:34:41 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Application development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/testowanie-rxjs-marble-testing/</guid>

					<description><![CDATA[W tym artykule przyjrzymy się RxJS Marble testing – niezbędnemu narzędziu dla testowania biblioteki RxJS. Zbadamy zasady testowania observable (ang. observables), jak również technikę marble testing, która ułatwia tworzenie i analizowanie testów. Przeanalizujemy również korzyści płynące z tego podejścia oraz omówimy najlepsze praktyki związane z testowaniem kodu RxJS.]]></description>
										<content:encoded><![CDATA[
<div class="table-of-contents">
    <p class="title">PRZEJDŹ DO:</p>
    <ol>
                    <li><a href="#RxJS-observables">1.  RxJS observables </a></li>
                    <li><a href="#Czym-jest-testowanie-R">2.  Czym jest testowanie RxJS (marble testing w RxJS)? </a></li>
                    <li><a href="#-przypadki-testowe-RxJS?u002du002d">3.  Jak pisać przypadki testowe RxJS?  </a></li>
                    <li><a href="#-jest-marble-diagram-w-RxJS?-">4.  Czym jest marble diagram w RxJS? </a></li>
                    <li><a href="#diagramy-marble-w-RxJS?-">5.   Jakie są rodzaje testów marble w RxJS? </a></li>
                    <li><a href="#ci-z-testowania-RxJS?">6.  Jakie są korzyści z testowania RxJS? </a></li>
                    <li><a href="#FAQ">7.  FAQ</a></li>
            </ol>
</div>


<h2 class="wp-block-heading" id="RxJS-observables">RxJS observables</h2>



<p>RxJS to biblioteka do tworzenia asynchronicznych strumieni danych, zarządzania nimi oraz obsługiwania zdarzeń w aplikacjach JavaScript. <strong>Kluczowym elementem RxJS są observable</strong>, które reprezentują strumienie danych emitowane w czasie.</p>



<p>Observable opierają się na wzorcu projektowym Obserwator, w którym obserwator „subskrybuje” obserwowany obiekt i oczekuje na emitowane przez niego dane. RxJS oferuje różnorodne operatory, takie jak map, filter czy merge, które pozwalają na przekształcanie, filtrowanie i łączenie strumieni danych.</p>



<p>Szerzej koncepcja biblioteki RxJS została opisana w artykule <a href="https://nearshore-it.eu/pl/artykuly/programowanie-reaktywne-w-js-z-rxjs" target="_blank" data-type="URL" data-id="https://nearshore-it.eu/pl/artykuly/programowanie-reaktywne-w-js-z-rxjs" rel="noreferrer noopener">Programowanie reaktywne z JavaScript w RxJS.</a></p>



<h2 class="wp-block-heading" id="Czym-jest-testowanie-R">Czym jest testowanie RxJS (marble testing w RxJS)?</h2>



<p>RxJS umożliwia reaktywne programowanie w JavaScript, dzięki czemu można obsługiwać asynchroniczne strumienie danych oraz manipulować nimi za pomocą różnych operacji, takich jak mapowanie, filtrowanie czy łączenie. Testowanie RxJS ma na celu zapewnienie, że kod działający na tych strumieniach jest poprawny, wolny od błędów i spełnia oczekiwania.&nbsp;</p>



<h3 class="wp-block-heading">Marble testing&nbsp;</h3>



<p>W kontekście testowania RxJS warto wspomnieć o <strong>marble testing</strong>, które jest jednym z popularnych narzędzi do testowania strumieni danych w tej bibliotece. Marble testing to nic innego jak wizualizacja strumieni danych za pomocą tzw. marble diagrams. W marble strumienie danych <strong>reprezentowane są jako ciągi znaków</strong>, gdzie każdy znak symbolizuje wartość w strumieniu lub specjalne zdarzenie, takie jak zakończenie strumienia czy wystąpienie błędu. Testowanie z użyciem diagramów marble pozwala na definiowanie oczekiwanych wyników oraz porównywanie ich z rzeczywistymi wynikami testowania, co jest szczególnie przydatne w przypadku złożonych operacji asynchronicznych.&nbsp;</p>



<h3 class="wp-block-heading">Rodzaje testów</h3>



<p>Testowanie RxJS, zwłaszcza z wykorzystaniem diagramów marble,<strong> pozwala na weryfikację poprawności działania funkcji i operatorów reaktywnych </strong>w kontekście testów jednostkowych. Testy jednostkowe koncentrują się na ocenie pojedynczych funkcji, operatorów oraz strumieni danych. Ich celem jest izolowanie poszczególnych elementów kodu i sprawdzenie, czy zachowują się zgodnie z oczekiwaniami.</p>



<p><strong>Przeczytaj także:</strong> <a href="https://nearshore-it.eu/pl/artykuly/narzedzia-automatyzacji-testow/">Narzędzia automatyzacji testów czy&nbsp;dobre praktyki? Jak przyspieszyć testowanie?</a></p>



<h3 class="wp-block-heading">Narzędzia testowania RxJS&nbsp;</h3>



<p>W celu ułatwienia testowania z użyciem diagramów marble biblioteka RxJS udostępnia takie narzędzia jak <strong>TestScheduler</strong>, który pozwala na kontrolowanie czasu w wirtualny sposób &#8211; bez wpływu na rzeczywisty czas wykonywania testów. TestScheduler umożliwia definiowanie wartości wejściowych i oczekiwanych wartości wyjściowych za pomocą marble diagrams, a następnie symuluje przepływ danych w strumieniach reaktywnych.&nbsp;</p>



<h2 class="wp-block-heading" id="-przypadki-testowe-RxJS?--">Jak pisać przypadki testowe RxJS?&nbsp;&nbsp;</h2>



<p>Pisanie przypadków testowych RxJS wymaga starannego planowania, zrozumienia kodu źródłowego oraz wykorzystania odpowiednich narzędzi do testowania. Marble testing to jedno z podejść, które pomaga w tworzeniu przejrzystych testów dla strumieni danych. Oto kilka wskazówek, jak napisać testy dla kodu opartego na bibliotece RxJS:&nbsp;</p>



<h3 class="wp-block-heading">1. Zapoznaj się z kodem źródłowym&nbsp;</h3>



<p>Przed przystąpieniem do pisania przypadków testowych dokładnie zapoznaj się z kodem źródłowym, który będzie testowany. Zrozumienie struktury kodu oraz celu poszczególnych funkcji i operatorów pozwoli na opracowanie skutecznych i kompleksowych testów.&nbsp;</p>



<h3 class="wp-block-heading">2. Wybierz odpowiedni framework do testowania&nbsp;</h3>



<p>Wybierz framework do testowania kodu JavaScript, taki jak Jasmine, Mocha czy Jest, który najlepiej odpowiada twoim potrzebom i preferencjom. Upewnij się, że wybrany framework współpracuje z RxJS i pozwala na wykorzystanie marble testing, jeśli planujesz korzystać z tego podejścia.&nbsp;</p>



<h3 class="wp-block-heading">3. Utwórz strukturę testów&nbsp;</h3>



<p>Testy jednostkowe zwykle są organizowane w blokach <strong>describe </strong>(lub podobnych, w zależności od używanego frameworka), które służą do grupowania testów dotyczących określonej funkcji, operatora lub komponentu. Wewnątrz bloków describe umieszczamy poszczególne przypadki testowe, zdefiniowane za pomocą funkcji <strong>it </strong>(lub odpowiednika w wybranym frameworku).&nbsp;</p>



<h3 class="wp-block-heading">4. Zastosuj marble testing&nbsp;</h3>



<p>Marble testing to podejście, które pozwala na wizualizację strumieni danych za pomocą tzw. marble diagrams. W marble testing strumienie danych reprezentowane są jako ciągi znaków, gdzie każdy znak symbolizuje wartość w strumieniu lub specjalne zdarzenie, takie jak zakończenie strumienia czy wystąpienie błędu.&nbsp;</p>



<p>W przypadku testowania RxJS z wykorzystaniem marble testing użyj narzędzi dostarczanych przez bibliotekę, takich jak TestScheduler. TestScheduler pozwala na kontrolowanie czasu w sposób wirtualny oraz definiowanie wartości wejściowych i oczekiwanych wartości wyjściowych za pomocą marble diagrams.&nbsp;&nbsp;</p>



<h3 class="wp-block-heading">5. Zdefiniuj przypadki testowe&nbsp;</h3>



<p>Przypadki testowe powinny być zdefiniowane w sposób czytelny i zrozumiały, opisując oczekiwane zachowanie funkcji, operatora lub strumienia danych. Wykorzystując marble testing, możesz precyzyjnie i czytelnie opisać oczekiwane zachowanie strumieni danych oraz porównać rzeczywiste wyniki z oczekiwanymi.&nbsp;</p>



<h3 class="wp-block-heading">6. Testuj różne przypadki i scenariusze&nbsp;</h3>



<p>Podczas pisania przypadków testowych warto przetestować różne scenariusze, takie jak:&nbsp;</p>



<ul class="wp-block-list">
<li>Przepływ danych o różnych wartościach&nbsp;</li>



<li>Przepływ danych z opóźnieniami lub interwałami&nbsp;</li>



<li>Zachowanie kodu w przypadku wystąpienia błędów&nbsp;</li>



<li>Zakończenie strumieni danych&nbsp;</li>



<li>Właściwe przekazywanie wartości do kolejnych operatorów&nbsp;</li>
</ul>



<ul class="wp-block-list">
<li>Spróbuj także uwzględnić przypadki brzegowe, aby upewnić się, że testowany kod jest odporny na różne sytuacje.&nbsp;</li>
</ul>



<h3 class="wp-block-heading">7. Przeglądaj i ulepszaj przypadki testowe&nbsp;</h3>



<p>Regularnie przeglądaj swoje przypadki testowe, aby upewnić się, że są aktualne i nadal spełniają swoje zadanie. Spróbuj zoptymalizować testy, eliminując powtarzalne lub zbędne fragmenty kodu, a także ułatwiając jego czytanie i zrozumienie. Dzięki temu utrzymanie i rozwój testów będą łatwiejsze w miarę wprowadzania zmian w kodzie źródłowym.&nbsp;</p>



<p>Pisanie przypadków testowych RxJS, zwłaszcza z wykorzystaniem marble testing, wymaga zrozumienia struktury kodu, wyboru odpowiedniego frameworka do testowania, tworzenia struktury testów oraz definiowania przypadków testowych, które precyzyjnie opisują oczekiwane zachowanie strumieni danych. Dzięki stosowaniu tych wskazówek będziesz w stanie tworzyć czytelne i skuteczne testy jednostkowe dla swojego kodu opartego na bibliotece RxJS.&nbsp;</p>



<h2 class="wp-block-heading" id="-jest-marble-diagram-w-RxJS?-">Czym jest marble diagram w RxJS?&nbsp;</h2>



<p>Diagramy marble to wizualne reprezentacje strumieni danych w bibliotece RxJS, które pomagają zrozumieć przepływ danych oraz interakcje między operacjami na strumieniach. Wprowadzenie diagramów marble do procesu wytwarzania oprogramowania z RxJS może poprawić czytelność kodu, ułatwić komunikację między programistami oraz przyspieszyć proces wdrażania testów.&nbsp;</p>



<h2 class="wp-block-heading" id="diagramy-marble-w-RxJS?-">Jak odczytywać diagramy marble w RxJS?&nbsp;</h2>



<p>Diagramy marble używają znaków do przedstawienia wartości emitowanych przez strumień, zakończenia strumienia, wystąpienia błędu oraz subskrypcji i jej anulowania. Oto kilka dodatkowych wskazówek, jak odczytywać diagramy:&nbsp;</p>



<p><strong>Czas:</strong> każdy myślnik (<strong>&#8211;</strong>) oznacza jednostkę czasu, zwaną również „ramką”. W testach marble długość ramki czasowej jest zdefiniowana w narzędziu TestScheduler, co pozwala na kontrolowanie upływu czasu w teście.&nbsp;</p>



<p><strong>Wartości:</strong> znaki alfanumeryczne (np.<strong> a, b, c</strong>) reprezentują wartości emitowane przez strumień danych. Wartości te są zazwyczaj zdefiniowane w obiekcie wartości przekazywanym do metody <strong>toBe()</strong>, który mapuje te znaki na rzeczywiste wartości.&nbsp;</p>



<p><strong>Subskrypcja i anulowanie subskrypcji: </strong>w Marble możemy użyć symbolu <strong>^</strong> do oznaczenia momentu, w którym subskrypcja się rozpoczyna, oraz <strong>!</strong> do oznaczenia momentu, w którym zostaje anulowana.&nbsp;</p>



<p><strong>Przykładowy diagram marble dla RxJS może wyglądać tak:</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">---a---b---c---| 
 </pre>



<p>Ten diagram reprezentuje strumień danych, który emituje trzy wartości: a, b, c, każda z nich emitowana w równych odstępach czasu. Ostatni symbol, |, oznacza, że strumień został zakończony po emisji c.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">---a---b---c---| 

        map(x => x.toUpperCase()) 

---A---B---C---| </pre>



<p>W tym przypadku mamy strumień wejściowy, który emituje wartości <strong>a</strong>, <strong>b</strong>, <strong>c</strong>. Następnie zastosowaliśmy operator map, który przekształca każdą emitowaną wartość na jej odpowiednik z dużą literą. Wynikowy strumień emituje więc wartości <strong>A</strong>, <strong>B</strong>, <strong>C</strong>.&nbsp;</p>



<p>Diagramy marble mogą być znacznie bardziej skomplikowane, z wieloma operatorami i zdarzeniami. Kluczowe jest zrozumienie podstawowej notacji, aby móc interpretować i tworzyć takie diagramy.&nbsp;</p>



<h2 class="wp-block-heading">Jakie są rodzaje testów marble w RxJS?</h2>



<p>Testy marble w RxJS dzielimy na dwa główne rodzaje: testy jednostkowe i testy integracyjne.</p>



<h3 class="wp-block-heading">Testy jednostkowe</h3>



<p>Skupiają się na izolowaniu i testowaniu indywidualnych komponentów, operatorów lub funkcji. Marble testing jest bardzo przydatne w testach jednostkowych, ponieważ pozwala na precyzyjne sprawdzanie sekwencji zdarzeń oraz efektów poszczególnych operatorów na strumieniach danych. W testach jednostkowych korzystamy z TestScheduler, który pozwala kontrolować upływ czasu oraz weryfikować oczekiwane wyniki testów.</p>



<h3 class="wp-block-heading">Testy integracyjne</h3>



<p>Testują interakcje między różnymi komponentami, operatorami lub funkcjami w systemie. Marble testing może być również używane w testach integracyjnych, aby zbadać, jak różne części kodu współpracują ze sobą. W testach integracyjnych sprawdzamy, czy przepływ danych między różnymi komponentami jest zgodny z oczekiwaniami. Testowanie marble w kontekście testów integracyjnych jest bardziej złożone niż w przypadku testów jednostkowych, ale może dostarczyć cenne informacje na temat zachowania systemu jako całości.&nbsp;</p>



<p>W testowaniu z wykorzystaniem diagramów marble&nbsp; istotne jest również zrozumienie operatorów „hot” i „cold”. W kontekście strumieni danych operator „hot” to taki, który emituje wartości niezależnie od tego, czy istnieje obecnie jakakolwiek subskrypcja. Z kolei operator „cold” zaczyna emitować wartości dopiero po subskrypcji. W testach marble operator „cold” jest zazwyczaj reprezentowany przez strumienie oznaczone jako <strong>source</strong>. Najlepiej będzie spojrzeć na przykład:&nbsp;&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import { TestScheduler } from 'rxjs/testing'; 

import { of, Subject } from 'rxjs'; 

import { map, takeUntil } from 'rxjs/operators'; 
 

it('should demonstrate hot and cold observables', () => { 

  const testScheduler = new TestScheduler((actual, expected) => { 

    expect(actual).toEqual(expected); 

  }); 

 

  testScheduler.run(({ cold, hot, expectObservable }) => { 

    const sourceCold$ = cold(' --a--b--c--|'); 

    const sourceHot$ = hot('  --d--e--f--|'); 

    const stop$ = cold('      -----s--|'); 

    const expectedMarble = '  --x--y--(z|)'; 

 

    const resultCold$ = sourceCold$.pipe( 

      takeUntil(stop$), 

      map((value) => value.toUpperCase()) 

    ); 

    const resultHot$ = sourceHot$.pipe( 

      takeUntil(stop$), 

      map((value) => value.toUpperCase()) 

    ); 

    expectObservable(resultCold$).toBe(expectedMarble, { 

      x: 'A', 

      y: 'B', 

      z: 'C' 

    }); 

    expectObservable(resultHot$).toBe(expectedMarble, { 

      x: 'D', 

      y: 'E', 

      z: 'F' 

    }); 

  }); 

}); </pre>



<p>W powyższym przykładzie widzimy dwa strumienie danych: „cold” i „hot&#8221;. Strumień „cold” zaczyna emitować wartości tylko po subskrypcji, podczas gdy strumień „hot” emituje wartości niezależnie od subskrypcji. W teście używamy operatora „<strong>takeUntil</strong>” do zakończenia obserwacji strumieni danych w odpowiednim momencie.&nbsp;</p>



<p>Podsumowując, marble diagrams w RxJS są niezwykle pomocne w zrozumieniu przepływu danych oraz zachowań poszczególnych operatorów w strumieniach danych. Testowanie marble ułatwia tworzenie testów jednostkowych oraz integracyjnych, które są niezbędne dla poprawnego działania aplikacji opartej na RxJS. Wiedza na temat diagramów marble oraz umiejętność pisania skutecznych testów marble są ważnymi kompetencjami każdego programisty korzystającego z biblioteki RxJS.&nbsp;</p>



<p>W przypadku pracy z marble warto pamiętać o kilku dodatkowych zasadach i wskazówkach, które mogą ułatwić proces testowania:</p>



<ul class="wp-block-list">
<li><strong>Konwencje nazewnictwa:</strong> kiedy tworzysz strumienie danych za pomocą diagramów marble, warto utrzymywać konwencje nazewnictwa i używać nazw związanych z funkcjonalnością strumieni. Dzięki temu możemy łatwo zrozumieć, jakie dane przepływają przez strumienie, co ułatwia analizowanie wyników testów.&nbsp;</li>
</ul>



<ul class="wp-block-list">
<li><strong>Korzystanie z helperów: </strong>w wielu przypadkach testowania marble możemy skorzystać z funkcji pomocniczych dostarczanych przez bibliotekę RxJS, takich jak <strong>TestScheduler</strong>,<strong> hot</strong>,<strong> cold</strong>,<strong> time</strong>,<strong> expectObservable </strong>i<strong> expectSubscriptions</strong>. Te funkcje ułatwiają tworzenie diagramów marble oraz zarządzanie nimi i testowanie przepływu danych między różnymi strumieniami.&nbsp;</li>



<li><strong>Weryfikacja wyników testów:</strong> podczas pisania testów marble warto zwracać uwagę na wyniki testów i błędy zgłaszane przez narzędzia do testowania, takie jak Jasmine lub Mocha. Dzięki temu możemy szybko zidentyfikować i naprawić błędy w naszym kodzie.&nbsp;</li>



<li><strong>Dokładność testów:</strong> testowanie marble pozwala na precyzyjne śledzenie sekwencji zdarzeń w strumieniach danych. Jednak ważne jest, aby pamiętać, że testowanie marble nie zastępuje innych rodzajów testowania, takich jak testy jednostkowe czy integracyjne. Warto korzystać z różnych technik testowania w zależności od kontekstu i potrzeb aplikacji.&nbsp;</li>



<li><strong>Praktyka: </strong>testowanie marble może być na początku trudne do zrozumienia, ale z biegiem czasu i nabieranym doświadczeniem staje się coraz łatwiejsze. Praca z różnymi przykładami i scenariuszami pomoże zrozumieć, jak najlepiej wykorzystać diagramy marble w testach RxJS.&nbsp;</li>
</ul>



<p>Używając marble w RxJS, można skutecznie testować strumienie danych oraz interakcje między operacjami. Diagramy marble ułatwiają zrozumienie przepływu danych oraz oczekiwanych wyników testów, co prowadzi do budowania bardziej niezawodnych i wydajnych aplikacji. Praktyka i doświadczenie są kluczowe w opanowaniu testowania marble, ale korzyści płynące z jego zastosowania są nieocenione dla każdego programisty Front-End.</p>



<p><strong>Przeczytaj także:</strong> <a href="https://nearshore-it.eu/pl/artykuly/testy-regresji/" data-type="URL" data-id="https://nearshore-it.eu/pl/artykuly/testy-regresji/" target="_blank" rel="noreferrer noopener">Test regresji – strata czasu czy&nbsp;must have w&nbsp;projekcie?</a></p>



<h2 class="wp-block-heading" id="ci-z-testowania-RxJS?">Jakie są korzyści z testowania RxJS?</h2>



<ul class="wp-block-list">
<li><strong>Działanie kodu zgodne z oczekiwaniami</strong> – testowanie kodu RxJS jest niezwykle ważne, gdyż pozwala na zwiększenie pewności, że kod działa zgodnie z oczekiwaniami. Dzięki testom programiści mogą być pewni, że ich aplikacje rzeczywiście spełniają założone wymagania biznesowe, co przekłada się na mniejsze ryzyko wystąpienia błędów czy niezgodności.&nbsp;</li>



<li><strong>Wykrywanie błędów</strong> – jednocześnie testowanie ułatwia wykrywanie błędów, ponieważ sprawdza indywidualne funkcje, operatory oraz interakcje między nimi. Dzięki temu możliwe jest szybsze zidentyfikowanie i naprawienie problemów w kodzie. To wpływa również na skrócenie czasu debugowania, gdyż testy pomagają programistom szybko zlokalizować źródło błędu.&nbsp;</li>



<li><strong>Łatwiejsze wprowadzanie zmian</strong> – testy RxJS wspierają także wprowadzanie zmian w kodzie, gdyż automatycznie sprawdzają funkcjonalność po każdej modyfikacji. Dzięki temu programista może szybciej wykryć i naprawić ewentualne problemy wynikające z wprowadzonych zmian. Ponadto testy ułatwiają refaktoryzację, gdyż programista może być pewny, że jego zmiany nie wprowadzą regresji.&nbsp;</li>



<li><strong>Dokumentacja kodu </strong>–<strong> </strong>warto również zauważyć, że testy RxJS często służą jako dokumentacja dla kodu, dostarczając informacji o tym, jak korzystać z poszczególnych funkcji i jakie są ich oczekiwane wyniki. Taka dokumentacja jest nieoceniona dla innych programistów, którzy chcą zrozumieć czyjś kod i wiedzieć, jak go używać.&nbsp;</li>
</ul>



<ul class="wp-block-list">
<li><strong>Większe zaufanie do oprogramowania</strong> – wreszcie testowanie zwiększa zaufanie do kodu zarówno wśród programistów, jak i interesariuszy projektu. Wszyscy mogą być pewni, że aplikacja rzeczywiście działa poprawnie i spełnia wymagania. Testy są kluczowe dla utrzymania wysokiej jakości aplikacji opartych na strumieniach danych i reaktywnym programowaniu.&nbsp;</li>



<li><strong>Lepszy kod</strong> – w efekcie testowanie kodu RxJS przyczynia się do lepszej jakości kodu, szybszego wykrywania i naprawiania błędów, łatwiejszego wprowadzania zmian oraz wzrostu zaufania do kodu. Jako ekspert od RxJS, zdecydowanie polecam stosowanie testów we wszelkich projektach opartych na tej bibliotece.&nbsp;</li>
</ul>



<h2 class="wp-block-heading" id="FAQ">FAQ</h2>


<div id="rank-math-faq" class="rank-math-block">
<div class="rank-math-list ">
<div id="faq-question-1684867289692" class="rank-math-list-item">
<h3 class="rank-math-question ">Czym cechują się frameworki testowe RxJS i jak wybrać najlepszy? </h3>
<div class="rank-math-answer ">

<p>Frameworki testowe RxJS to narzędzia służące do tworzenia, organizowania i wykonywania testów dla kodu opartego na RxJS. Wybór najlepszego frameworka zależy od potrzeb projektu i preferencji zespołu. Przy wyborze frameworka testowego dla RxJS warto zwrócić uwagę na następujące aspekty: <br /> <br /><strong>Obsługa Marble Testing:</strong> ważne jest, aby wybrać framework, który obsługuje testy marble, gdyż są one kluczowe w testowaniu reaktywnych strumieni danych. <br /><strong>Integracja z innymi narzędziami:</strong> sprawdź, jak dobrze framework integruje się z innymi narzędziami używanymi w projekcie, takimi jak bundlery, środowiska CI/CD czy lintery.  <br /><strong>Łatwość użycia:</strong> framework testowy powinien być łatwy w konfiguracji i użyciu. <br /><strong>Popularność i wsparcie społeczności:</strong> popularne frameworki testowe mają większe szanse na aktywny rozwój i wsparcie społeczności. <br /><strong>Dokumentacja: </strong>dobra dokumentacja jest kluczowa dla szybkiego wprowadzenia frameworka testowego do projektu oraz dla zrozumienia jego możliwości. <br /><strong>Wydajność:</strong> wydajność frameworka testowego wpływa na czas wykonywania testów. <br /><strong>Elastyczność i możliwości rozszerzenia:</strong> wybrany framework powinien oferować elastyczność w konfiguracji oraz możliwość rozszerzenia o dodatkowe narzędzia lub funkcje. <br />Przykłady popularnych frameworków testowych wspierających RxJS to Jasmine, Jest i Mocha. Każdy z nich oferuje różne funkcje i zalety, dlatego warto dokładnie przeanalizować ich możliwości przed podjęciem decyzji o wyborze. </p>

</div>
</div>
<div id="faq-question-1684867306736" class="rank-math-list-item">
<h3 class="rank-math-question ">Jak wdrożyć testowanie RxJS? </h3>
<div class="rank-math-answer ">

<p>Aby wdrożyć testowanie RxJS w projekcie, na początek należy wybrać odpowiedni framework testowy, który wspiera testy marble, tak jak Jasmine, Jest lub Mocha. Wybór powinien zależeć od potrzeb projektu i preferencji zespołu. Następnie przystąp do instalacji i konfiguracji wybranego frameworka testowego, używając menedżera pakietów, takiego jak npm lub yarn, i postępując zgodnie z instrukcjami dostarczanymi przez dokumentację frameworka. </p>
<p>Jeśli wybrany framework testowy nie obsługuje testów marble bezpośrednio, zainstaluj dodatkowe narzędzia, takie jak rxjs-marbles dla Mochy czy jest-marbles dla Jesta. Teraz możesz zacząć pisanie testów jednostkowych dla komponentów, usług, operatorów i strumieni opartych na RxJS. Wykorzystaj testy marble do reprezentowania i testowania reaktywnych strumieni danych. Upewnij się, że testujesz kluczowe scenariusze, zarówno pozytywne, jak i negatywne, aby sprawdzić poprawność działania kodu. <br />Dobrze jest umieścić testy w dedykowanych plikach lub folderach, aby łatwo można było je znaleźć i zarządzać nimi. Przyjętym standardem jest umieszczanie testów w folderze <strong>__tests__</strong> lub w plikach z rozszerzeniem <strong>.spec.ts </strong>lub <strong>.test.ts.</strong> Aby uruchomić testy, użyj narzędzi dostarczonych przez framework testowy, zarówno lokalnie, jak i na serwerze CI/CD. W zależności od frameworka możesz wykorzystać polecenia CLI, takie jak <strong>npm test</strong>, <strong>yarn test</strong> czy <strong>ng test.</strong> </p>
<p>Monitoruj wyniki testów, analizuj błędy i naprawiaj problemy w kodzie. Użyj narzędzi do generowania raportów i statystyk, aby ocenić jakość kodu oraz śledzić postęp w testowaniu. W miarę jak projekt się rozwija, aktualizuj i utrzymuj testy, pisząc nowe testy dla nowych funkcji oraz aktualizując istniejące testy w przypadku zmian w kodzie. Dzięki temu utrzymanie wysokiej jakości kodu będzie znacznie łatwiejsze  </p>

</div>
</div>
<div id="faq-question-1684867333157" class="rank-math-list-item">
<h3 class="rank-math-question ">Jakie są typowe błędy testowania RxJS? </h3>
<div class="rank-math-answer ">

<p>Jednym z takich błędów jest nieuwzględnienie zasady asynchroniczności przy testowaniu. W przypadku testowania strumieni danych ważne jest, aby pamiętać o użyciu odpowiednich technik testowania asynchronicznego, takich jak testy marble, czy wykorzystywanie funkcji <strong>fakeAsync</strong> i <strong>tick</strong> dostarczanych przez Angulara. </p>
<p>Inny typowy błąd polega na niewłaściwym zarządzaniu subskrypcjami. Jeśli subskrypcje nie zostaną anulowane po zakończeniu testów, może to prowadzić do wycieków pamięci i fałszywie pozytywnych wyników testów. Warto zwrócić uwagę na to, aby odpowiednio zarządzać subskrypcjami, zwłaszcza w przypadku testowania komponentów czy usług. </p>
<p>Częstym błędem jest również niewłaściwe użycie operatorów RxJS, które może prowadzić do nieoczekiwanych rezultatów. Szczególnie ważne jest zrozumienie różnicy między operatorem <strong>switchMap</strong> a <strong>mergeMap </strong>oraz innymi operatorami, które mają wpływ na zachowanie strumieni danych. </p>
<p>Nieodpowiednie testowanie błędów może prowadzić do fałszywego poczucia bezpieczeństwa. Warto zwrócić uwagę na testowanie obsługi błędów, zwłaszcza w przypadku asynchronicznych operacji, takich jak żądania HTTP. W takich przypadkach warto użyć odpowiednich operatorów do obsługi błędów, takich jak <strong>catchError</strong> i <strong>retry</strong>. </p>
<p>Niedokładne testowanie warunków brzegowych i skrajnych scenariuszy może prowadzić do niewykrycia problemów. Dlatego warto dążyć do pełnego pokrycia testami, a także badać różne kombinacje danych wejściowych, które mogą wpłynąć na działanie strumieni danych. Testowanie tych przypadków może ujawnić potencjalne problemy, których można nie zauważyć podczas testowania tylko typowych scenariuszy. </p>
<p>Ostatnim błędem, ale nie mniej ważnym, jest niewłaściwe stosowanie operatorów cold i hot podczas testowania marble. Warto zrozumieć różnice między tymi operatorami oraz wiedzieć, kiedy stosować jeden, a kiedy drugi, aby uzyskać wiarygodne wyniki testów. </p>

</div>
</div>
<div id="faq-question-1684867388576" class="rank-math-list-item">
<h3 class="rank-math-question ">Jakie są wzorce projektowe testowania RxJS? </h3>
<div class="rank-math-answer ">

<p>Wzorce projektowe testowania RxJS to sprawdzone techniki stosowane w testowaniu aplikacji opartych na tej bibliotece. Kluczowym elementem jest wdrożenie testów marble, które umożliwiają wizualizację i testowanie strumieni danych, a także analizę interakcji między nimi. Dzięki stosowaniu takich wzorców testy asynchroniczne staną się bardziej efektywne, a izolacja testowanych części aplikacji od zewnętrznych zależności pozwoli na kontrolowanie zachowań i przetestowanie różnych scenariuszy. </p>

</div>
</div>
<div id="faq-question-1684867400504" class="rank-math-list-item">
<h3 class="rank-math-question ">Jakie są najlepsze praktyki testowania? </h3>
<div class="rank-math-answer ">

<p>W odniesieniu do najlepszych praktyk testowania w kontekście biblioteki RxJS warto skupić się na podejściach i technikach, które czynią testy efektywnymi, wydajnymi i łatwymi w utrzymaniu. Testowanie asynchroniczne, w tym <strong>async</strong>, <strong>fakeAsync</strong> czy <strong>testy marble</strong>, pozwala na przetestowanie różnych scenariuszy związanych z asynchronicznymi operacjami. Kluczowe jest również testowanie obsługi błędów, aby sprawdzić, czy są one prawidłowo obsługiwane w strumieniach danych. Ważne jest, aby testować warunki brzegowe i skrajne scenariusze, co pozwala na wykrycie potencjalnych problemów, które mogą umknąć podczas testowania tylko typowych scenariuszy. Monitorowanie poziomu pokrycia testami oraz dbanie o dobrą organizację testów, umieszczanie ich w dedykowanych plikach lub folderach, ułatwia zarządzanie kodem i utrzymanie jego przejrzystości. </p>

</div>
</div>
</div>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/testowanie-rxjs-marble-testing/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Jeśli nie Redux, to co? Zarządzanie stanem aplikacji w React</title>
		<link>https://nearshore-it.eu/pl/artykuly/jesli-nie-redux-to-co-zarzadzanie-stanem-aplikacji-w-react/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/jesli-nie-redux-to-co-zarzadzanie-stanem-aplikacji-w-react/#respond</comments>
		
		<dc:creator><![CDATA[Hubert Głowiak]]></dc:creator>
		<pubDate>Thu, 13 Apr 2023 11:18:27 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/jesli-nie-redux-to-co-zarzadzanie-stanem-aplikacji-w-react/</guid>

					<description><![CDATA[Większość starszych projektów wykorzystujących React korzysta z biblioteki Redux. To popularne rozwiązanie, które przyzwyczaiło programistów do określonego sposobu działania. W dodatku ma sporą społeczność użytkowników gotowych służyć pomocą. Jeśli pracujesz w nowym projekcie, w którym priorytetem jest szybkość wdrażania i ograniczenie ilości kodu, warto wziąć pod uwagę inne opcje. W artykule przedstawiam kilka intuicyjnych i łatwych w obsłudze narzędzi, które z powodzeniem mogą konkurować z biblioteką Redux. Które wybrać? Sprawdź!]]></description>
										<content:encoded><![CDATA[
<div class="table-of-contents">
    <p class="title">Spis treści:</p>
    <ol>
                    <li><a href="#Zarządzanie-stanem-w-React">1.  Zarządzanie stanem w React</a></li>
                    <li><a href="#Czym-jest-Redux-i-jak-działa?">2.  Czym jest Redux i jak działa?</a></li>
                    <li><a href="#Wykorzystanie-innych-rozwiązań">3.  Wykorzystanie innych rozwiązań</a></li>
                    <li><a href="#Które-rozwiązanie-wybrać?">4.  Które rozwiązanie wybrać?</a></li>
                    <li><a href="#Zarządzanie-stanem-aplikacji-–-podsumowanie">5.  Zarządzanie stanem aplikacji – podsumowanie</a></li>
            </ol>
</div>


<h2 class="wp-block-heading" id="Zarządzanie-stanem-w-React">Zarządzanie stanem w React</h2>



<p>Ktoś stworzył aplikację z przyciskiem. Wciskasz go i za każdym razem wyświetla się inna wartość. Pewnie zastanawiasz się, co dzieje się <strong>„pod spodem”.</strong> To albo czary, albo… zarządzanie stanem aplikacji. Tym razem zajmiemy się tym drugim tematem. Zarządzanie stanem w <a href="https://nearshore-it.eu/pl/artykuly/najlepsze-frameworki-frontendowe/" target="_blank" data-type="URL" rel="noreferrer noopener">React </a>to <strong>proces kontrolowania i aktualizowania danych w aplikacji.</strong> </p>





<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/Redux-Gif.gif" alt="Redux" class="wp-image-6620" title="Jeśli nie Redux, to co? Zarządzanie stanem aplikacji w React 2"></figure></div>


<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Jest jednym z kluczowych zagadnień przy pracy z biblioteką programowania JavaScript.  Stan to taka wartość, która zmienia się na przykład na skutek interakcji użytkownika z aplikacją. W React stan zazwyczaj przechowywany jest w komponentach, a jego zmiana może powodować ponowne renderowanie komponentu lub całego drzewa komponentów. Zarządzanie stanem jest dosyć istotne. Pozwala nam tworzyć dynamiczne i interaktywne aplikacje – dzięki temu aplikacja może:</p>



<ul class="wp-block-list">
<li>dostosowywać się do zmieniającego się stanu,</li>



<li>reagować na interakcję użytkownika,</li>



<li>wykonywać pewne akcje w odpowiednich momentach.</li>
</ul>



<p>Jest to ważne w przypadku złożonych aplikacji, w których wiele komponentów zależy od stanów w innych komponentach.</p>



<h2 class="wp-block-heading" id="Czym-jest-Redux-i-jak-działa?">Czym jest Redux i jak działa?</h2>



<p>Zapewne większość osób zaznajomionych z React, słysząc o zarządzaniu stanem, przed oczami ma tylko jedno – Redux.</p>



<p>Redux jest biblioteką służącą do zarządzania stanem aplikacji w React. Jest to narzędzie, które umożliwia tworzenie bardziej przewidywalnych i łatwiejszych<strong> do testowania aplikacji poprzez uproszczenie zarządzania stanem i zachowywania go w jednym miejscu</strong>. Redux wprowadza wiele pojęć, które pozwalają na bardziej efektywne i przewidywalne zarządzanie stanem. Jednym z nich jest jednostronny przepływ danych. Stan aplikacji jest przechowywany w jednym centralnym magazynie, tzw. store. Dane między store a komponentami przepływają w odpowiedni sposób, zgodny z architekturą Flux. Zmiany w stanie są dokonywane tylko za pomocą akcji, czyli prostych obiektów, które opisują zmiany, jakie mają być wykonane w stanie aplikacji.</p>



<p>Warto również wspomnieć, że <strong>Redux może działać niezależnie od Reacta</strong>. Biblioteka ta jest uniwersalna i może być używana w innych aplikacjach internetowych. Jeśli ktoś jednak poszukuje nieskomplikowanego, intuicyjnego narzędzia, to warto poznać też inne dostępne opcje.</p>





<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import React from "react";
import { Provider, useDispatch, useSelector } from "react-redux";
import { createStore } from "redux";


const incrementAction = () => ({ type: "INCREMENT" });
const decrementAction = () => ({ type: "DECREMENT" });


const counterReducer = (state = 0, action) => {
 switch (action.type) {
   case "INCREMENT":
     return state + 1;
   case "DECREMENT":
     return state - 1;
   default:
     return state;
 }
};


const store = createStore(counterReducer);


const Counter = () => {
 const count = useSelector((state) => state);
 const dispatch = useDispatch();


 return (
   &lt;div>
     &lt;div>Count: {count}&lt;/div>
     &lt;button onClick={() => dispatch(incrementAction())}>+&lt;/button>
     &lt;button onClick={() => dispatch(decrementAction())}>-&lt;/button>
   &lt;/div>
 );
};


const CounterApp = () => {
 return (
   &lt;Provider store={store}>
     &lt;Counter />
   &lt;/Provider>
 );
};
</pre>



<h2 class="wp-block-heading" id="Wykorzystanie-innych-rozwiązań">Wykorzystanie innych rozwiązań</h2>



<p>Na szczęście istnieją różne sposoby zarządzania stanem aplikacji w React:</p>



<h3 class="wp-block-heading"><strong>Context API</strong></h3>



<p>To wbudowane w React narzędzie do przekazywania danych między komponentami bez konieczności przekazywania ich przez <strong>„propsy”</strong> (<em>właściwości, ang. properties</em>). Dzięki temu można przekazywać dane do komponentów znajdujących się niżej w hierarchii bezpośrednio z góry. Można to wykorzystać do zarządzania stanem aplikacji, przekazując stan do całej aplikacji lub tylko do części komponentów.</p>





<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import React, { createContext, useContext, useState } from "react";


const CounterContext = createContext();


const CounterProvider = ({ children }) => {
 const [counter, setCounter] = useState(0);


 const increment = () => {
   setCounter((prevCounter) => prevCounter + 1);
 };


 const decrement = () => {
   setCounter((prevCounter) => prevCounter - 1);
 };


 return (
   &lt;CounterContext.Provider value={{ counter, increment, decrement }}>
     {children}
   &lt;/CounterContext.Provider>
 );
};


const CounterDisplay = () => {
 const { counter } = useContext(CounterContext);


 return &lt;div>Counter: {counter}&lt;/div>;
};


const CounterButtons = () => {
 const { increment, decrement } = useContext(CounterContext);


 return (
   &lt;div>
     &lt;button onClick={increment}>+&lt;/button>
     &lt;button onClick={decrement}>-&lt;/button>
   &lt;/div>
 );
};


const CounterApp = () => {
 return (
   &lt;CounterProvider>
     &lt;CounterDisplay />
     &lt;CounterButtons />
   &lt;/CounterProvider>
 );
};</pre>



<h3 class="wp-block-heading"><strong>MobX</strong></h3>



<p>To biblioteka, która umożliwia łatwe zarządzanie stanem aplikacji w React. W przeciwieństwie do Redux – MobX jest bardziej elastyczny i wymaga mniej kodu. Używa się go do przechowywania stanu w obiektach, które reprezentują dane aplikacji. MobX automatycznie aktualizuje widok, gdy dane zmienią się w magazynie.</p>





<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import React from "react";
import { observable } from "mobx";
import { observer } from "mobx-react";

const counterStore = observable({
 counter: 0,
 increment() {
   this.counter++;
 },
 decrement() {
   this.counter--;
 },
});

const CounterDisplay = observer(() => &lt;div>Counter: {counterStore.counter}&lt;/div>);

const CounterButtons = observer(() => (
 &lt;div>
   &lt;button onClick={() => counterStore.increment()}>+&lt;/button>
   &lt;button onClick={() => counterStore.decrement()}>-&lt;/button>
 &lt;/div>
));

const CounterApp = () => {
 return (
   &lt;div>
     &lt;CounterDisplay />
     &lt;CounterButtons />
   &lt;/div>
 );
};</pre>



<h3 class="wp-block-heading"><strong>RxJS</strong></h3>



<p>To <a href="https://nearshore-it.eu/pl/artykuly/programowanie-reaktywne-w-js-z-rxjs/" target="_blank" data-type="URL" rel="noreferrer noopener">biblioteka reaktywna</a> do zarządzania asynchronicznymi strumieniami danych. Można jej używać do zarządzania stanem w aplikacji. RxJS pozwala na łatwe reagowanie na zmiany w danych i wykonywanie akcji na podstawie tych zmian.</p>





<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import React, { useState, useEffect } from "react";
import { Subject } from "rxjs";
import { scan } from "rxjs/operators";

const counterSubject = new Subject();

const counter$ = counterSubject.pipe(
 scan((count, operation) => {
   if (operation === "+") {
     return count + 1;
   } else if (operation === "-") {
     return count - 1;
   } else {
     return count;
   }
 }, 0)
);

const CounterDisplay = () => {
 const [counter, setCounter] = useState(0);


 useEffect(() => {
   const subscription = counter$.subscribe(setCounter);
   return () => subscription.unsubscribe();
 }, []);


 return &lt;h1>Counter: {counter}&lt;/h1>;
};


const CounterButtons = () => {
 const handleButtonClick = (operation) => {
   counterSubject.next(operation);
 };


 return (
   &lt;div>
     &lt;button onClick={() => handleButtonClick("+")}>+&lt;/button>
     &lt;button onClick={() => handleButtonClick("-")}>-&lt;/button>
   &lt;/div>
 );
};

const CounterApp = () => {
 return (
   &lt;div>
     &lt;CounterDisplay />
     &lt;CounterButtons />
   &lt;/div>
 );
};</pre>



<h3 class="wp-block-heading"><strong>Recoil</strong></h3>



<p>Recoil to biblioteka, która działa poprzez przechowywanie stanu aplikacji w tzw. atomach. Atomy są prostymi obiektami, które zawierają aktualną wartość stanu oraz funkcje, które pozwalają na aktualizację wartości. Dzięki temu łatwo jest zarządzać stanem aplikacji i aktualizować go w reakcji na interakcję podejmowaną przez użytkownika lub inne zdarzenia. </p>





<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import React from "react";
import { useRecoilState, atom, RecoilRoot } from "recoil";


const counterState = atom({
 key: "counterState",
 default: 0,
});

const CounterDisplay = () => {
 const [counter] = useRecoilState(counterState);

 return &lt;div>Counter: {counter}&lt;/div>;
}

const CounterButtons = () => {
 const [counter, setCounter] = useRecoilState(counterState);


 const increment = () => {
   setCounter(counter + 1);
 };

 const decrement = () => {
   setCounter(counter - 1);
 };

 return (
   &lt;div>
     &lt;button onClick={increment}>+&lt;/button>
     &lt;button onClick={decrement}>-&lt;/button>
   &lt;/div>
 );
}

const CounterApp = () => {
 return (
   &lt;RecoilRoot>
     &lt;CounterDisplay />
     &lt;CounterButtons />
   &lt;/RecoilRoot>
 );
};</pre>



<h3 class="wp-block-heading"><strong>Zustand</strong></h3>



<p>Zustand to lekka biblioteka do zarządzania stanem w React, która wykorzystuje podstawowe funkcjonalności React do przechowywania i aktualizowania stanu. Oferuje proste API i pozwala na tworzenie globalnego stanu, zarządzanie stanem w komponentach, własnych modułach, tworzenie selektorów i subskrypcji stanu. Jest szybka i wydajna, co sprawia, że działa dobrze nawet w dużych aplikacjach.</p>





<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import React from "react";
import create from "zustand";

const useCounterStore = create((set) => ({
 counter: 0,
 incrementCounter: () => set((state) => ({ counter: state.counter + 1 })),
 decrementCounter: () => set((state) => ({ counter: state.counter - 1 })),
}));

const CounterDisplay = () => {
 const counter = useCounterStore((state) => state.counter);

 return &lt;div>Counter: {counter}&lt;/div>;
}

const CounterButtons = () => {
 const { incrementCounter, decrementCounter } = useCounterStore();

 return (
   &lt;div>
     &lt;button onClick={incrementCounter}>+&lt;/button>
     &lt;button onClick={decrementCounter}>-&lt;/button>
   &lt;/div>
 );
}

const CounterApp = () => {
 return (
   &lt;div>
     &lt;CounterDisplay />
     &lt;CounterButtons />
   &lt;/div>
 );
};</pre>



<h2 class="wp-block-heading" id="Które-rozwiązanie-wybrać?">Które rozwiązanie wybrać?</h2>



<p>Wybór rozwiązania do zarządzania stanem w React zależy od wielu czynników, takich jak rozmiar i złożoność projektu, preferencje zespołu programistycznego, doświadczenia z innymi bibliotekami i podejściami. Większość starszych projektów w React korzysta z biblioteki Redux, gdyż było to najpopularniejsze rozwiązanie, które przyzwyczaiło programistów do swojego sposobu działania. Redux jest bardzo popularny wśród większych projektów i ma duże wsparcie społeczności, co może pomóc w rozwiązywaniu problemów – nie jest jednak polecany w nowych projektach.</p>



<p>Według mnie, jeśli rozpoczynasz nowy projekt w React i potrzebujesz rozwiązania do zarządzania stanem, to sugerowałbym rozważenie Recoil lub Zustand. Są to biblioteki, które <strong>zostały opracowane z myślą o prostocie i łatwości użycia</strong>, co może być szczególnie ważne w nowym projekcie, w którym chcesz skupić się na szybkim wdrożeniu funkcjonalności i ograniczeniu ilości kodu. <strong>Recoil </strong>i <strong>Zustand </strong>pozwalają na tworzenie stanu przy użyciu hooków, co ułatwia integrację z React i zmniejsza potrzebę tworzenia dodatkowych plików. W przypadku Recoil możesz również korzystać z selektorów, które pozwalają na pobieranie tylko niezbędnych danych ze stanu, co może przyspieszyć renderowanie aplikacji.</p>



<h2 class="wp-block-heading" id="Zarządzanie-stanem-aplikacji-–-podsumowanie">Zarządzanie stanem aplikacji – podsumowanie</h2>



<p>Podsumowując, wybór biblioteki do zarządzania stanem w React powinien być solidnie przeanalizowany i nie jest łatwo odpowiedzieć na pytanie „które narzędzie wybrać?”. Jeśli priorytetem są łatwość użycia i szybka implementacja funkcjonalności, dobrym pomysłem może być wykorzystanie któregoś z innych rozwiązań &#8211; na przykład Recoil lub Zustand. </p>



<p>Jeśli zastanawiasz się nad wyborem Reduxa, to warto jest przeanalizować, czy projekt jest na tyle złożony i wymagający, że jego zastosowanie jest potrzebne. Może się też okazać, że projekt nie wymaga użycia żadnej biblioteki do zarządzania stanem, ponieważ sam React dostarcza narzędzi do zarządzania stanem w komponentach, które są wystarczające dla prostych projektów</p>
]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/jesli-nie-redux-to-co-zarzadzanie-stanem-aplikacji-w-react/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Higher-Order Observable Mapping w RxJS</title>
		<link>https://nearshore-it.eu/pl/artykuly/operator-wyzszego-rzedu-rxjs/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/operator-wyzszego-rzedu-rxjs/#respond</comments>
		
		<dc:creator><![CDATA[Maciej Woźnica]]></dc:creator>
		<pubDate>Wed, 01 Mar 2023 12:26:00 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Application development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/operator-wyzszego-rzedu-rxjs/</guid>

					<description><![CDATA[Biblioteka RxJs, którą szczegółowo opisałem w poprzednim artykule, oferuje szereg możliwości pracy z danymi, reagowania na zachowania użytkownika czy wszelkie inne zdarzenia zachodzące w aplikacji. W skrócie: RxJs to biblioteka ułatwiająca wykorzystanie konceptu programowania reaktywnego. Jednym z takich ułatwień są operatory wyższego rzędu. Z tego artykułu dowiesz się, czym jest Higher-Order Observable Mapping w RxjS, jakie są rodzaje operatorów i jak mogą ci pomóc w pracy ze strumieniowymi danymi. Zaczynajmy!]]></description>
										<content:encoded><![CDATA[
<div class="table-of-contents">
    <p class="title"></p>
    <ol>
                    <li><a href="#Observable">1.  Observable oraz strumień danych </a></li>
                    <li><a href="#Operatory-w-RxJS">2.  Operatory w RxJS</a></li>
                    <li><a href="#Switchmap">3.  SwitchMap</a></li>
                    <li><a href="#Mergemap">4.  MergeMap</a></li>
                    <li><a href="#Contactmap">5.  ContactMap</a></li>
                    <li><a href="#exhaustmap">6.  ExhaustMap</a></li>
                    <li><a href="#faq">7.  FAQ</a></li>
            </ol>
</div>


<h2 class="wp-block-heading" id="Observable">Observable oraz strumień danych</h2>



<p>Jednymi z najważniejszych elementów biblioteki RxJS są Observable oraz strumienie danych.</p>



<p>Oba te pojęcia są podobne, jednak występują między nimi subtelne różnice:</p>



<figure class="wp-block-table aligncenter is-style-stripes"><table><thead><tr><th><strong>Strumienie danych</strong>&nbsp;&nbsp;</th><th><strong>Observable</strong>&nbsp;</th></tr></thead><tbody><tr><td>Strumienie danych są reprezentowane przez klasę Observable w bibliotece RxJS.&nbsp;</td><td>Observable może też reprezentować pojedyncze wartości, a nie tylko strumienie.&nbsp;</td></tr><tr><td>Mają węższy zakres i pozwalają na manipulacje na danych i kontrolowanie ich w ograniczony sposób.&nbsp;</td><td>Ma szerszy zakres zastosowań niż strumienie danych, ponieważ pozwalają na manipulowanie strumieniami i kontrolowanie ich w bardziej zaawansowany sposób.&nbsp;&nbsp;&nbsp;</td></tr><tr><td>Strumienie danych nie pozwalają na multipleksowanie, łączenie, filtrowanie i mapowanie danych.&nbsp;</td><td>Observable pozwala na wykonanie pewnych operacji, takich jak multipleksowanie, łączenie, filtrowanie i mapowanie, co pozwala na bardziej zaawansowaną pracę z danymi.&nbsp;&nbsp;&nbsp;</td></tr><tr><td>Strumienie danych to sekwencje wartości, które są emitowane przez źródło.&nbsp;</td><td>Observable to obiekt, który służy do zarządzania strumieniem danych.&nbsp;&nbsp;&nbsp;</td></tr><tr><td>Nie można za ich pomocą kontrolować czasu przepływu wartości czy sterować błędami.&nbsp;</td><td>Ma dodatkowe cechy pozwalające np. na kontrolowanie czasu przepływu wartości lub sterowanie błędami. &nbsp;&nbsp;</td></tr><tr><td>Strumienie danych są sekwencjami wartości emitowanymi przez źródło.&nbsp;</td><td>Observable to obiekt, który zarządza strumieniami danych i pozwala na manipulowanie nimi.&nbsp;</td></tr></tbody></table></figure>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Podsumowując, Observable mają szerszy zakres zastosowań niż strumienie danych i mają dodatkowe funkcje, pozwalające na kontrolowanie czasu przepływu wartości i sterowanie błędami.</p>



<h2 class="wp-block-heading" id="Operatory-w-RxJS">Operatory w RxJS</h2>



<p>Prawdziwą potęgę biblioteki RxJS stanowią operatory. Operatory pozwalają przekształcać, filtrować, łączyć strumienie danych i zarządzać nimi. RxJS dostarcza szereg operatorów, takich jak: map, filter, reduce, debounceTime, distinctUntilChanged itp., które pozwalają na przetwarzanie danych w strumieniach. Wybór odpowiedniego operatora jest ważny, gdyż źle dobrany operator może wpłynąć na funkcjonowanie systemu. Niżej omawiam najważniejsze z nich.</p>



<p><strong>Przeczytaj także:</strong> <a href="https://nearshore-it.eu/pl/artykuly/programowanie-reaktywne-w-js-z-rxjs/">Programowanie reaktywne w JavaScript z RxJS</a></p>



<p><strong>Higher-Order Observable Mapping</strong></p>



<p>Biblioteka RxJS zawiera szczególny typ operatorów, tzw. <strong>higher-order operators</strong>, czyli operatory wyższego rzędu, które pozwalają na złożone manipulowanie strumieniami danych. Higher-order operators to operatory, które zawierają w argumentach inne operatory lub Observable i zwracają nowe Observable mające zastosowanie do pierwotnego strumienia danych.</p>



<p>Istnienie higher-order operators w bibliotece RxJS jest uzasadnione z kilku powodów:</p>



<ul class="wp-block-list">
<li><strong>Zapewniają one prostsze i bardziej czytelne sposoby manipulowania strumieniami danych. </strong>Dzięki nim można złożyć wiele operacji na strumieniu w jeden łańcuch, co ułatwia czytanie i zrozumienie kodu.</li>



<li><strong>Umożliwiają bardziej elastyczne manipulowanie strumieniami danych. </strong>Wiele higher-order operators pozwala na dynamiczne tworzenie nowych strumieni danych w zależności od zdarzeń zachodzących w pierwotnym strumieniu. Dzięki temu można łatwo dostosować przetwarzanie danych do zmieniających się wymagań.</li>



<li><strong>Higher-order operators pozwalają na wielokrotne wykorzystanie kodu.</strong> Wiele operacji na strumieniach danych jest podobnych i można je zastosować w wielu miejscach w aplikacji. Higher-order operators ułatwiają użycie tych samych operacji w różnych częściach kodu, co pozwala na uniknięcie powtórzeń.</li>
</ul>



<p>Podsumowując, higher-order operators w bibliotece RxJS pozwalają na bardziej elastyczne, czytelne i wielokrotne wykorzystanie kodu do manipulowania strumieniami danych. Dzięki nim programiści mogą złożyć wiele operacji na strumieniu w jeden łańcuch, co ułatwia zarządzanie danymi w aplikacji.</p>



<p>RxJS udostępnia nam cztery operatory wyższego rzędu:</p>



<h3 class="wp-block-heading" id="Switchmap">SwitchMap</h3>



<p><strong>Operator switchMap emituje wartości wewnętrznego Observable, ale każda nowa wartość emitowana przez strumień źródłowy powoduje anulowanie poprzedniego wewnętrznego Observable i utworzenie nowego.</strong> Wewnętrzny Observable zwrócony z funkcji mapującej jest zastępowany nowym wewnętrznym Observable, co oznacza, że jeśli źródłowy strumień emituje wartości z częstotliwością wyższą niż wewnętrzny Observable, operator switchMap przerywa działanie i zastępuje poprzedni wewnętrzny Observable. SwitchMap możemy zastosować w przypadku, gdy chcemy odwołać wcześniejsze żądania i wysłać tylko najnowsze żądanie, np. dotyczące filtrowania wyników wyszukiwania.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import { fromEvent } from 'rxjs'; 

import { switchMap } from 'rxjs/operators'; 

 

Pobieranie danych z serwera 

function fetchData(keyword: string) { 

  return fetch(`https://api.github.com/search/repositories?q=${keyword}`).then(res => res.json()); 

} 
 </pre>



<p>Strumień wejściowy z danymi z pola tekstowego</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const input$ = fromEvent(document.querySelector('input'), 'input'); </pre>



<p>Operator switchMap kończy subskrypcję poprzedniego strumienia i zwraca tylko strumień wyjściowy ostatniego wyemitowanego strumienia</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const result$ = input$.pipe( 

  switchMap(event => fetchData(event.target.value)) 

); </pre>



<p>Subskrypcja strumienia wyjściowego</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">result$.subscribe( 

  data => console.log(data), 

  err => console.error(err), 

  () => console.log('Complete') 

); </pre>



<p>W tym przykładzie operator switchMap przekształca każdą wartość strumienia wejściowego (event z pola tekstowego) na strumień wyjściowy, który pobiera dane z serwera GitHub API na podstawie frazy wyszukiwania. Dzięki temu, kiedy użytkownik wprowadza nową frazę, operator switchMap anuluje subskrypcję poprzedniego strumienia wyjściowego i zwraca tylko wynik dla ostatniej frazy.</p>



<h3 class="wp-block-heading" id="Mergemap">MergeMap</h3>



<p>Operator mergeMap<strong> przetwarza wszystkie wartości w strumieniu źródłowym jednocześnie, emitując wartości wewnętrzne Observable</strong>. Operator tworzy wiele wewnętrznych Observables, co oznacza, że wynikowy strumień wyjściowy może emitować wartości w dowolnej kolejności. Przykładowym zastosowaniem operatora mergeMap może być równoległe pobieranie danych z wielu źródeł.</p>



<p>Operator mergeMap jest szczególnie przydatny w sytuacjach, gdy potrzebujemy wykonać operację asynchroniczną dla każdego elementu strumienia wejściowego i uzyskać strumień wyjściowy składający się z wyników tych operacji.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import { from, Observable } from 'rxjs'; 

import { mergeMap } from 'rxjs/operators'; </pre>



<p>Definicja funkcji zwracającej strumień asynchroniczny</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">function makeHttpRequest(id: number): Observable {

return fetch(https://jsonplaceholder.typicode.com/posts/${id}).then(res => res.json());

}</pre>



<p>Strumień wejściowy z listą identyfikatorów</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const ids$ = from([1, 2, 3, 4, 5]); 

 </pre>



<p>Operator mergeMap przekształca każdy element strumienia wejściowego na strumień wyjściowy</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const posts$ = ids$.pipe( 

  mergeMap(id => makeHttpRequest(id)) 

); </pre>



<p>Subskrypcja strumienia wyjściowego</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">posts$.subscribe( 

  post => console.log(post), 

  err => console.error(err), 

  () => console.log('Complete') 

); </pre>



<p>W tym przykładzie operator mergeMap przekształca każdy element strumienia wejściowego (identyfikator posta) na strumień wyjściowy reprezentujący wynik asynchronicznej operacji pobierania danych z serwera dla danego posta. W efekcie otrzymujemy strumień wyjściowy składający się z pobranych postów, a nie z identyfikatorów.</p>



<h3 class="wp-block-heading" id="Contactmap">ContactMap</h3>



<p>Operator concatMap emituje wartości wewnętrznego Observable w kolejności, w jakiej są one dostarczane. Operator nie tworzy wielu wewnętrznych Observables, dopóki poprzedni Observable nie zakończy działania. W przypadku, gdy w strumieniu źródłowym pojawi się kolejna wartość, zanim zakończy działanie poprzedni wewnętrzny Observable. Operator concatMap umieszcza wartości kolejnego wewnętrznego Observable w kolejce i przetwarza je dopiero po zakończeniu poprzedniego Observable.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import { of } from 'rxjs'; 

import { concatMap, delay } from 'rxjs/operators'; </pre>



<p>Strumień wejściowy z liczbami</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const source$ = of(1, 2, 3, 4, 5); </pre>



<p>Operator concatMap przekształca każdy element strumienia wejściowego na nowy strumień wyjściowy z opóźnieniem w zależności od wartości elementu</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const example$ = source$.pipe( 

  concatMap(value => of(`Delayed by: ${value * 1000}ms`).pipe(delay(value * 1000))) 

); </pre>



<p>Subskrypcja strumienia wyjściowego</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">example$.subscribe(console.log); </pre>



<p>W powyższym przykładzie concatMap przekształca każdą wartość strumienia wejściowego (1, 2, 3, 4, 5) na strumień wyjściowy, który zostaje opóźniony o wartość elementu w sekundach i zwrócony w kolejności ich pojawiania się w źródłowym strumieniu. Dzięki temu pierwszy element (1) zostanie zwrócony po jednej sekundzie, drugi element (2) po dwóch sekundach itd.</p>



<h3 class="wp-block-heading" id="exhaustmap">ExhaustMap</h3>



<p>Operator exhaustMap<strong> przekształca każdy element strumienia wejściowego (źródłowego) na nowy strumień i ignoruje wszystkie kolejne elementy, zanim zakończy działanie strumień wyjściowy.</strong></p>



<p>ExhaustMap jest przydatny, gdy jest nam potrzebne, żeby w danym czasie był emitowany tylko jeden strumień wyjściowy. W przypadku, gdy pojawiają się nowe elementy w strumieniu wejściowym przed zakończeniem strumienia wyjściowego, są one ignorowane aż do zakończenia działania poprzedniego strumienia wyjściowego.</p>



<p>Przykładowym zastosowaniem operatora exhaustMap może być ograniczenie liczby żądań sieciowych w sytuacji, gdy w aplikacji użytkownik kliknie wiele razy na przycisk, ale zwrócone zostanie tylko jedno zapytanie.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""> 

import { interval } from 'rxjs'; 

import { exhaustMap, take } from 'rxjs/operators'; </pre>



<p>Strumień wejściowy z wartościami</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const source$ = interval(1000).pipe(take(4)); </pre>



<p>Operator exhaustMap przekształca każdą wartość strumienia wejściowego na nowy strumień wyjściowy, który zostaje zwrócony dopiero po zakończeniu działania jego poprzednika.&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const example$ = source$.pipe( 

  exhaustMap(value => interval(500).pipe(take(3))) 

); </pre>



<p>Subskrypcja strumienia wyjściowego&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">example$.subscribe(console.log); </pre>



<p>Powyższy przykład obrazuje sytuacje, gdy operator exhaustMap przekształca każdą wartość strumienia wejściowego (0, 1, 2, 3) na strumień wyjściowy emitujący wartości z opóźnieniem 0,5 sekundy. Każdy kolejny strumień wyjściowy zostanie zignorowany, dopóki poprzedni nie zostanie zakończony, dlatego drugi strumień wyjściowy z wartościami (0, 1, 2) nie zostanie wyemitowany, ponieważ pierwszy strumień z wartościami (0, 1, 2) nadal jest w trakcie emisji.</p>



<h2 class="wp-block-heading">Podsumowując:</h2>



<ul class="wp-block-list">
<li><strong>exhaustMap</strong> ignoruje nowe zdarzenia, jeśli obecny strumień wciąż trwa. Jeśli w trakcie trwania strumienia wejściowego operator otrzyma kolejne zdarzenie, to zostanie ono pominięte, aż do momentu, gdy strumień wejściowy się zakończy.</li>



<li><strong>mergeMap</strong> przetwarza wszystkie wartości w strumieniu źródłowym jednocześnie, emitując wartości wewnętrznych Observables.</li>



<li><strong>concatMap</strong> emituje wartości wewnętrznego Observable w kolejności, w jakiej są one emitowane.</li>



<li><strong>switchMap</strong> emituje wartości wewnętrznego Observable, ale zastępuje poprzedni wewnętrzny Observable nowym, gdy źródłowy strumień emituje nowe wartości.</li>
</ul>



<h2 class="wp-block-heading" id="faq">FAQ:&nbsp;&nbsp;</h2>


<div id="rank-math-faq" class="rank-math-block">
<div class="rank-math-list ">
<div id="faq-question-1682427320388" class="rank-math-list-item">
<h3 class="rank-math-question ">Czym jest RxJS?</h3>
<div class="rank-math-answer ">

<p>RxJS to biblioteka programistyczna napisana w języku JavaScript, która implementuje wzorzec programowania reaktywnego, oparty na strumieniach danych. RxJSu <strong>umożliwia programowanie reaktywne w języku JavaScript</strong>.</p>
<p>Biblioteka RxJS zapewnia programistom szereg narzędzi i operacji do tworzenia, przetwarzania i obsługi strumieni danych. Umożliwia tworzenie i łączenie strumieni z różnych źródeł, np. interakcji użytkownika czy zapytań HTTP. RxJS dostarcza także wiele operatorów, które umożliwiają transformowanie, filtrowanie i łączenie strumieni danych.</p>
<p>RxJS ma wiele zastosowań, takich jak obsługa zdarzeń interakcji użytkownika w aplikacjach internetowych, tworzenie strumieni danych z serwera lub integracja z frameworkami frontendowymi, takimi jak Angular czy React.</p>

</div>
</div>
<div id="faq-question-1682427349404" class="rank-math-list-item">
<h3 class="rank-math-question ">Czym jest strumień danych w programowaniu reaktywnym?</h3>
<div class="rank-math-answer ">

<p>W programowaniu reaktywnym strumień danych to sekwencja zdarzeń, która może mieć miejsce w czasie i być przetwarzana asynchronicznie. Może to być na przykład strumień zdarzeń z interfejsu użytkownika, strumień danych z sieci, pliku, bazy danych lub innego źródła. <strong>Strumienie danych są kluczowym elementem w programowaniu reaktywnym, ponieważ pozwalają na przetwarzanie zdarzeń i reagowanie na nie w czasie rzeczywistym, w miarę ich pojawiania się</strong>. Strumienie mogą mieć zero lub wiele wartości. W bibliotece RxJS operatorami są funkcje, które pozwalają na pracę z asynchronicznymi strumieniami danych. Dzięki wykorzystaniu operatorów i strumieni danych programowanie reaktywne umożliwia tworzenie skalowalnych, elastycznych i wydajnych aplikacji. Szerzej zostało to opisane w artykule „Programowanie reaktywne w JS z RxJS”.</p>

</div>
</div>
<div id="faq-question-1682427351812" class="rank-math-list-item">
<h3 class="rank-math-question ">Jak efektywniej wykorzystać bibliotekę RxJS?</h3>
<div class="rank-math-answer ">

<p>&#8211; <strong>Używaj Observables zamiast Promises </strong>– Observables są bardziej elastyczne niż Promises i pozwalają na łatwe operowanie na strumieniu danych.<br />&#8211; <strong>Unikaj nadmiernego korzystania z operatorów </strong>– operatorów w RxJS jest wiele i bardzo łatwo jest przesadzić z ich wykorzystaniem. Zawsze należy zastanowić się, czy dany operator jest potrzebny i czy faktycznie przyczynia się do poprawy czytelności i wydajności kodu.<br />&#8211; <strong>Unikaj jednoczesnego korzystania z wielu strumieniu</strong> – w RxJS bardzo łatwo jest stworzyć wiele strumieni danych, co może prowadzić do problemów z wydajnością aplikacji. Zawsze należy zastanowić się, czy rzeczywiście potrzebujemy tak wielu strumieni i czy nie da się ich połączyć w jeden.<br />&#8211; <strong>Zwracaj uwagę na pamięć</strong> – w RxJS strumienie danych są połączone z pamięcią, więc warto zwracać uwagę na to, czy nie tworzymy niepotrzebnie dużych strumieni, które mogą powodować problemy z wydajnością.<br />&#8211; <strong>Korzystaj z operatorów wysokiego rzędu</strong> – operator wysokiego rzędu w RxJS pozwala na tworzenie bardziej skomplikowanych strumieni danych. Ich umiejętne wykorzystanie może znacznie ułatwić pracę i poprawić czytelność kodu.<br />&#8211; <strong>Testuj kod </strong>– RxJS jest bardzo potężną biblioteką, ale wymaga ona również więcej uwagi podczas testowania. Zawsze warto pamiętać o testowaniu swojego kodu.</p>
<p>Powyższe porady są ogólne i zależą od konkretnych wymagań projektu. W każdym przypadku warto jednak pamiętać o zachowaniu czytelności i przejrzystości kodu, a także o testowaniu swojego rozwiązania.</p>

</div>
</div>
<div id="faq-question-1682427440915" class="rank-math-list-item">
<h3 class="rank-math-question ">Czym jest typ obiektu? Dlaczego musisz go zasubskrybować, aby otrzymać dane?</h3>
<div class="rank-math-answer ">

<p>Typ obiektu w RxJS to abstrakcyjny typ danych, który reprezentuje strumień wartości emitowanych przez źródło. Typ ten definiuje interfejs do tworzenia, przetwarzania i subskrybowania strumieni danych w programowaniu reaktywnym.</p>
<p>Ważną cechą strumienia danych w RxJS jest to, że <strong>nie emituje on danych do subskrybenta automatycznie</strong>. W przeciwieństwie do klasycznych zapytań HTTP, które zwracają wynik tylko raz, strumienie danych mogą emitować wartości wielokrotnie w czasie. Aby otrzymać wartości emitowane przez strumień danych, musisz zasubskrybować go, czyli utworzyć subskrypcję. Subskrypcja reprezentuje połączenie pomiędzy subskrybentem a źródłem danych, które umożliwia odbieranie wartości emitowanych przez strumień.</p>
<p>Subskrypcja umożliwia również zarządzanie cyklem życia strumienia danych. Możesz anulować subskrypcję, jeśli nie potrzebujesz już otrzymywać wartości z danego strumienia. Możesz również wykonywać różne operacje na strumieniu, takie jak transformacje, filtrowanie lub łączenie z innymi strumieniami, poprzez użycie operatorów RxJS.</p>
<p>Podsumowując, <strong>subskrypcja jest niezbędna, aby otrzymać wartości emitowane przez strumień danych w RxJS</strong>. Dzięki temu, że subskrypcje umożliwiają zarządzanie cyklem życia strumienia, można w łatwy sposób manipulować przepływem danych w programowaniu reaktywnym.</p>

</div>
</div>
</div>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/operator-wyzszego-rzedu-rxjs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Wprowadzenie do funkcjonalnego programowania reaktywnego w JavaScript z RxJS</title>
		<link>https://nearshore-it.eu/pl/artykuly/programowanie-reaktywne-w-js-z-rxjs/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/programowanie-reaktywne-w-js-z-rxjs/#respond</comments>
		
		<dc:creator><![CDATA[Maciej Woźnica]]></dc:creator>
		<pubDate>Wed, 26 Oct 2022 10:38:33 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Application development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/programowanie-reaktywne-w-js-z-rxjs/</guid>

					<description><![CDATA[Współczesne aplikacje internetowe wymagają od programistów coraz wydajniejszych rozwiązań. Czasy, kiedy główną funkcjonalnością strony WWW było wyświetlenie statycznego tekstu, obsługa kliknięcia czy wysłanie wiadomości za pomocą formularza, mamy dawno za sobą.  
Bardzo często jako twórcy aplikacji musimy mierzyć się z coraz większymi wymaganiami użytkowników oraz rosnącą ilością danych, co znacząco wpływa na wydajność naszych witryn. Z pomocą przychodzi programowanie reaktywne – w artykule omawiam jego możliwości na przykładzie biblioteki RxJS.]]></description>
										<content:encoded><![CDATA[
<div class="table-of-contents">
    <p class="title">Przejdź do:</p>
    <ol>
                    <li><a href="#Wyzwania-współczesnych-aplikacji-internetowych">1.  Wyzwania współczesnych aplikacji internetowych</a></li>
                    <li><a href="#Czym-jest-programowanie-reaktywne?">2.  Czym jest programowanie reaktywne? </a></li>
                    <li><a href="#Strumienie-danych">3.  Strumienie danych </a></li>
                    <li><a href="#Co-to-jest-observable?">4.  Co to jest observable? </a></li>
                    <li><a href="#Observable-vs-promise-w-JavaScript">5.  Observable vs promise w JavaScript </a></li>
                    <li><a href="#Hot-vs-cold-observables">6.  Hot vs cold observables </a></li>
                    <li><a href="#Tworzenie-observable">7.  Tworzenie observable </a></li>
                    <li><a href="#Subskrybcje">8.  Subskrybcje</a></li>
                    <li><a href="#Observer">9.  Observer</a></li>
                    <li><a href="#RxJS-–-zalety">10.  RxJS – zalety </a></li>
                    <li><a href="#RxJS-–-wady">11.  RxJS – wady </a></li>
                    <li><a href="#Podsumowanie">12.  Podsumowanie </a></li>
            </ol>
</div>


<h2 class="wp-block-heading" id="Wyzwania-współczesnych-aplikacji-internetowych">Wyzwania współczesnych aplikacji internetowych</h2>



<p>Tworząc nowoczesne i wydajne aplikacje internetowe, mierzymy się z wieloma wyzwaniami, o czym wspominał m.in. Paweł Adamowicz w swoim materiale <a href="https://nearshore-it.eu/pl/artykuly/ngrx" target="_blank" data-type="URL" data-id="https://nearshore-it.eu/pl/artykuly/ngrx" rel="noreferrer noopener">Zarządzanie stanem aplikacji frontendowej za pomocą NgRx</a>. Jako programiści powinniśmy między innymi brać pod uwagę to, że nie można blokować użytkownika i kazać mu czekać, aż nasza witryna obsłuży kilka zdarzeń. Co zatem zrobić w momencie, kiedy aplikacja jednocześnie musi uruchomić animację, załadować loader czy zareagować na działanie użytkownika? Jak obsłużyć te wszystkie sytuacje naraz? Tutaj z pomocą przychodzi nam paradygmat programowania reaktywnego wraz z <strong>biblioteką</strong> <strong>RxJS</strong>.</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/jpro_2022.10.26_graphic_1-1.png" alt="RXJS - programowanie reaktywne" class="wp-image-68374" title="Wprowadzenie do funkcjonalnego programowania reaktywnego w JavaScript z RxJS 3"></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading" id="Czym-jest-programowanie-reaktywne?">Czym jest programowanie reaktywne?</h2>



<p>Programowanie reaktywne to paradygmat służący do pisania kodu opierającego się na asynchronicznych strumieniach danych.</p>



<p>Jest to sposób tworzenia aplikacji, które reagują na zachodzące zmiany, w przeciwieństwie do typowego, imperatywnego sposobu pisania oprogramowania, w którym jawnie tworzymy instrukcję krok po kroku, aby te zmiany obsłużyć.</p>



<p>Brzmi to dość skomplikowanie i faktycznie takie podejście wymaga zmiany sposobu myślenia. Jednak istnieją rozwiązania, które zdecydowanie ułatwią zmianę podejścia na reaktywne – w przypadku JavaScript jest nim właśnie biblioteka RxJS.</p>



<h2 class="wp-block-heading" id="Strumienie-danych">Strumienie danych</h2>



<p>Strumień to sekwencja danych uporządkowanych w czasie. Strumienie danych mogą być tworzone z obiektów, zmiennych, struktur danych, za pomocą zdarzeń (kliknięć), odpowiedzi żądań HTTP itd.</p>



<p>Na swojej osi czasu strumień może również emitować error (gdy wystąpi nieoczekiwane zdarzenie powodujące zakończenie strumienia) lub status completed, gdy strumień wyemitował wszystkie dane. Możemy przechwycić te metody (<strong>error i complete</strong>) i wykonać na nich odpowiednie dla nas operacje, o czym więcej piszę w dalszej części.</p>



<p><strong>Przeczytaj także:</strong> <a href="https://nearshore-it.eu/pl/artykuly/angular-zrobmy-swoja-progressive-web-application">Angular – zróbmy swoją PWA</a>.</p>



<h2 class="wp-block-heading" id="Co-to-jest-observable?">Co to jest observable?</h2>



<p>RxJS udostępnia nam obiekt observable, który wykorzystuje wzorzec projektowy – <strong>obserwator</strong>.</p>



<p>Możemy to zilustrować na przykładzie subskrybcji do newslettera. Zapewne nieraz zdarzyło ci się kliknąć przycisk „subskrybuj”, czy to na YouTube, czy np. jakimś blogu. W momencie kiedy pojawi się nowy artykuł lub inny materiał, dostajesz od razu powiadomienie o pojawieniu się nowych zasobów. W każdym momencie możesz także zrezygnować z subskrypcji.</p>



<p>Tak samo działają observable i strumienie.</p>



<ul class="wp-block-list">
<li>Klikając przycisk subscribe, stajesz się obserwatorem danych zasobów,</li>



<li>observable jako obiekt obserwowany serwuje nam strumień danych z nowościami,</li>



<li>subskrypcja do strumienia zapewnia nam metodę „subscribe”,</li>



<li>możemy również wybrać, które dane są dla nas wartościowe jako nowości.</li>
</ul>



<h2 class="wp-block-heading" id="Observable-vs-promise-w-JavaScript">Observable vs promise w JavaScript</h2>



<p>Observable to nic innego jak strumień z wartościami (absolutnie dowolnego typu). Ale zaraz, zaraz… Po co nam ten cały observable, skoro mamy już promise w JavaScript? Observable daje nam dużo większe możliwości, poniżej krótkie porównanie:</p>



<h3 class="wp-block-heading">Promise</h3>



<ul class="wp-block-list">
<li>za każdym razem jest asynchroniczny,&nbsp;</li>



<li>jest „eager” – przetwarzanie rozpoczyna się natychmiastowo po jego zdefiniowaniu,&nbsp;</li>



<li>może zwracać tylko jedną wartość,&nbsp;</li>



<li>nie posiada operatorów,&nbsp;</li>



<li>nie może być anulowany.</li>
</ul>



<h3 class="wp-block-heading">Observable</h3>



<ul class="wp-block-list">
<li>może być zarówno synchroniczny, jak i asynchroniczny,</li>



<li>jest „lazy” – będzie wykonany nie w momencie zdefiniowania strumienia, ale w momencie, w którym utworzona zostanie subskrypcja,</li>



<li>zwraca jedną lub wiele wartości,</li>



<li>do dyspozycji mamy całą gamę operatorów,</li>



<li>możemy go anulować w dowolnym momencie,</li>



<li>daje nam więcej możliwości przy obsłudze błędów (m.in. operator retry()).</li>
</ul>



<h2 class="wp-block-heading" id="Hot-vs-cold-observables">Hot vs cold observables</h2>



<p>Observable dzielimy na hot i cold.</p>



<h3 class="wp-block-heading">Cold observables:</h3>



<ul class="wp-block-list">
<li>emitowanie wartości zaczyna się w momencie pojawienia się pierwszego subskrybenta (gdy pojawi się pierwszy subscribe() – o tym w dalszej części artykułu),</li>



<li>dla każdego nowego subskrybenta zwracają nowe wartości,</li>



<li>przykładem może być np. serwis do pobierania danych z backendu, gdzie żeby wykonać zapytanie, musimy użyć subscribe.</li>
</ul>



<h3 class="wp-block-heading">Hot observables:</h3>



<ul class="wp-block-list">
<li>wysyłają wartości pomimo braku subskrybenta,</li>



<li>dzielą te same dane pomiędzy wszystkich subskrybentów,</li>



<li>przykład: observable stworzony z eventu click.</li>
</ul>



<h2 class="wp-block-heading" id="Tworzenie-observable">Tworzenie observable</h2>



<p>Istnieje wiele sposobów na stworzenie observable. Często spotykamy się z tworzeniem ich z innych struktur danych – tutaj z pomocą przychodzą nam operatory <strong>of </strong>lub <strong>from</strong>. Dla RxJS nie jest również problemem stworzenie jednego observable z kilku innych. Poniżej kilka przykładów.</p>



<p>Operator <strong>from </strong>przyjmuje tylko jeden argument, po którym można iterować (np. tablice, elementy tablicopodobne, weźmy za przykład tablicę obiektów).</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""> 

import { from, Observable } from 'rxjs'; 

  

const to ReadBooks = [  

{  bookId: 1, title: The psychology of money', author: 'Morgan Housel' 

publicationYear: 2020 }, 

{  bookId: 2, title: 'The subtle art of not giving a f*ck', author: 'Mark Manson', 			publicationYear: 2016 }, 

{ bookId: 3, title: How to talk to anyone', author: 'Leil Lowndes', publicationYear: 1999 }, 

{ bookId: 3, title: 'Invent and wander', author: Jeff Bezos', publicationYear: 2020 }, 

  

];  

  

let source2$ = from(toReadBooks); 

source2$.subscribe(book => console.log(book.title)); </pre>



<p><strong>W ten sposób nasza tablica obiektów zamieniła się w observable. Proste, prawda?</strong></p>



<p>A co w sytuacji, gdy mamy kilka strumieni, a potrzebujemy jednego observable? Żaden problem! RxJS udostępnia kilka operatorów, które nam w tym pomogą. Jednym z nich jest <strong>concat</strong>.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import { concat, from, Observable, of } from 'rxjs'; 

  

const toReadBooks = [ 

  

  

{  bookId: 1, title: The psychology of money', author: 'Morgan Housel'  

publicationYear: 2020 },  

{  bookId: 2, title: 'The subtle art of not giving a f*ck', author: 'Mark Manson', 			publicationYear: 2016 },  

{ bookId: 3, title: How to talk to anyone', author: 'Leil Lowndes', publicationYear: 1999 },  

{ bookId: 3, title: 'Invent and wander', author: Jeff Bezos', publicationYear: 2020 }, 

  

];  

  

let source1$ = of('hello', 10, true, toReadBooks[0].title); 

source1$.subscribe(value => console.log(value)); 

  

let source2$ = from(toReadBooks); 

source2$.subscribe(book => console.log(book.title)); 

  

// combine the 2 sources  

concat(source1$, source2$) 

.subscribe(value => console.log(value)); </pre>



<p><strong>Voilà! RxJS naprawdę ułatwia życie!</strong></p>



<h2 class="wp-block-heading" id="Subskrybcje">Subskrybcje</h2>



<p>Powyżej wspomniałem o możliwości subskrypcji do strumienia. Kolejny termin, który brzmi skomplikowanie (ale wcale taki skomplikowany nie jest!). Subskrybcja to po prostu podłączenie się do strumienia. Każdy observable posiada metodę <strong>subscribe(),</strong> do której możemy przekazać parametry na dwa sposoby: jako obiekt z metodami lub jako zestaw callbacków. Obiekt przekazany do metody subscribe nazywamy <strong>observerem</strong>.</p>



<h2 class="wp-block-heading" id="Observer">Observer</h2>



<p>Observer posiada trzy składowe:</p>



<ul class="wp-block-list">
<li>pierwsza metoda (<strong>next</strong>) jest wykonana, jeśli uda nam się odebrać wartość ze strumienia. Każda nowa wartość powoduje wywołanie tej metody,</li>



<li>druga metoda (<strong>error</strong>) jest wykonana, jeśli w strumieniu wystąpi błąd, na przykład w zapytaniu HTTP dostaniemy status 500. W przypadku wystąpienia błędu nasz observer nie przejdzie dalej i nie wykona metody complete, a tym samym zostanie zaznaczony jako closed i przestanie emitować wartości,</li>



<li>trzecia metoda (<strong>complete</strong>) jest wykonana w momencie, gdy strumień wyemituje ostatnią wartość.</li>
</ul>



<h2 class="wp-block-heading" id="RxJS-–-zalety">RxJS – zalety</h2>



<p>Biblioteka RxJS niewątpliwie ułatwia rozwój aplikacji. Możemy ją zintegrować właściwie z dowolnym <a href="https://nearshore-it.eu/pl/artykuly/najlepsze-frameworki-frontendowe" data-type="jpro" data-id="58320">frontendowym frameworkiem</a> (<strong>Angular</strong>, <strong>React</strong>). Również użycie z czystym JavaScriptem nie stanowi problemu. Do dyspozycji mamy ogromną liczbę operatorów, które pozwalają nam na dowolną modyfikację naszych strumieni. Stale pojawiające się aktualizacje sprawiają, że kolejne wydania biblioteki są coraz prostsze w użyciu. Dzięki RxJS zdecydowanie możemy przyspieszyć naszą pracę, jak również poprawić jakość wytwarzanego oprogramowania.</p>



<h2 class="wp-block-heading" id="RxJS-–-wady">RxJS – wady</h2>



<p>Tutaj zdecydowanie trudniej jest mi coś napisać niż w przypadku zalet. Pracując na co dzień z Angularem, nie wyobrażam sobie napisania choćby jednego komponentu bez użycia biblioteki RxJS. Na pewno rzeczą, która sprawia trudność – zwłaszcza początkującym programistom – jest<strong> testowanie kodu wykorzystującego RxJS</strong>. Testowanie takiego kodu wymaga znajomości wielu dodatkowych technik oraz narzędzi. Na szczęście RxJS ma na to swoje rozwiązanie i tu z pomocą przychodzi nam <strong>RxJS Marbles </strong>(umożliwia testowanie asynchronicznego kodu RxJS synchronicznie i krok po kroku za pomocą narzędzia testowego <strong>RxJS TestScheduler</strong> oraz przy użyciu wirtualnych kroków czasowych), jednak jest to dość obszerny temat, któremu można by poświęcić nowy wpis.</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image is-style-default">
<figure class="aligncenter size-full"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/jpro_2022.10.26_graphic_2.png" alt="RXJS - programowanie reaktywne" class="wp-image-68372" title="Wprowadzenie do funkcjonalnego programowania reaktywnego w JavaScript z RxJS 4"></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading" id="Podsumowanie">Podsumowanie</h2>



<p>Powyższe informacje stanowią bardzo ogólny opis programowania reaktywnego oraz biblioteki RxJS. O każdym z powyższych tematów śmiało mógłby powstać oddzielny artykuł, a mój to zaledwie kropla w morzu – wiele aspektów zostało pominiętych.</p>



<p>Jednak bez dwóch zdań używanie RxJS stało się standardem w tworzeniu nowoczesnych i wydajnych aplikacji. Ciągły rozwój i wsparcie dla najpopularniejszych frameworków sprawia, że RxJS jest zdecydowanie najczęściej używaną biblioteką ułatwiającą zapanowanie nad asynchronicznością.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/programowanie-reaktywne-w-js-z-rxjs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Najlepsze frameworki frontendowe</title>
		<link>https://nearshore-it.eu/pl/artykuly/najlepsze-frameworki-frontendowe/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/najlepsze-frameworki-frontendowe/#respond</comments>
		
		<dc:creator><![CDATA[Marek Susniak]]></dc:creator>
		<pubDate>Wed, 05 Jan 2022 05:45:00 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/najlepsze-frameworki-frontendowe/</guid>

					<description><![CDATA[Narzędziownik programisty frontend to nie tylko języki programowania takie jak JavaScript, HTML, TypeScript czy CSS. Każdy programista, który tworzy „na froncie”, powinien zadbać o stack technologiczny, którego istotną część stanowią biblioteki i frameworki. W artykule skupię się na tych drugich… chociaż nie tylko. Omówię 3 narzędzia z mojej subiektywnej listy i spróbuję odpowiedzieć na pytanie, które wciąż wzbudza wiele emocji: który framework frontendowy jest najlepszy?]]></description>
										<content:encoded><![CDATA[
<div class="table-of-contents">
    <p class="title"></p>
    <ol>
                    <li><a href="#Czym-są-frameworki">1.  Czym są frameworki?</a></li>
                    <li><a href="#Angular">2.  Angular</a></li>
                    <li><a href="#Vue.js">3.  Vue.js</a></li>
                    <li><a href="#React">4.  React</a></li>
            </ol>
</div>


<h2 class="wp-block-heading" id="Czym-są-frameworki">Czym są frameworki?</h2>



<p>Framework to nic innego jak szkielet aplikacji wraz z pewnymi schematami zachowań, które pozwalają na ich budowę. Głównym celem każdego frameworka jest poprawa efektywności, zapewnienie swoistego rodzaju niezawodności oraz utrzymanie jakości kodu w pewnych narzuconych ryzach. Oczywiście oprócz wymienionych wyżej zalet istnieją też pewne niedogodności, takie jak na przykład złożoność kodu. Przed przystąpieniem do pracy musimy po prostu nauczyć się reguł, które panują w danym środowisku. Często wyzwaniem może być wydajność, ale jest to kwestia doboru odpowiednich narzędzi do rozwiązania, które budujemy.</p>





<p></p>


</p>
<p>


<h2 class="wp-block-heading" id="Angular">Angular</h2>


</p>
<p>

<div class="wp-block-image">
<figure class="alignleft size-full"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/JPro_2022.01.05_angular.png" alt="Angular framework" class="wp-image-58556" title="Najlepsze frameworki frontendowe 5"></figure></div>

</p>
<p>


<p></p>



<p>Angular to&nbsp;framework stworzony przez&nbsp;firmę Google. W&nbsp;praktyce jest to&nbsp;kolejna gałąź frameworka&nbsp;<strong>AngularJS</strong>, opartego na&nbsp;języku JavaScript. Jednak nie&nbsp;należy spodziewać się tutaj uspójnionych koncepcji czy&nbsp;kontynuacji rozwiązań. Językiem, w&nbsp;którym&nbsp;piszemy w&nbsp;Angularze, jest&nbsp;<strong>TypeScript</strong>. Framework ten wprowadza pełną gamę funkcjonalności, które powinien posiadać każdy szkielet aplikacji. Programiści cenią Angulara przede wszystkim za&nbsp;takie funkcjonalności jak narzucona architektura aplikacji, routing, rozwiązanie wspierające pisanie komponentów, modułowość czy&nbsp;zastosowanie wzorców projektowych.</p>



<p>Istnieją również problemy, które często są&nbsp;zgłaszane przez&nbsp;użytkowników, między innymi:&nbsp;<strong>wysoki próg wejścia</strong>&nbsp;– zanim zacznie się pisać kod, trzeba przyswoić sporo wiedzy. Zatem wyzwaniem bez&nbsp;wątpienia jest&nbsp;<strong>duża złożoność frameworka</strong>&nbsp;oraz&nbsp;paradoksalnie związana z&nbsp;narzuconą architekturą&nbsp;<strong>mała elastyczność tworzonych aplikacji</strong>.</p>



<h2 class="wp-block-heading" id="Vue.js">Vue.js</h2>


<div class="wp-block-image">
<figure class="alignleft size-full"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/JPro_2022.01.05_vue.js.png" alt="Vue.js" class="wp-image-58561" title="Najlepsze frameworki frontendowe 6"></figure></div>




<p>Jest to framework typu open source, zaprojektowany przez szeroką rzeszę specjalistów. Dane autorów możemy znaleźć na stronie: <a href="https://vuejs.org/" target="_blank" rel="noreferrer noopener">https://vuejs.org/</a>. Vue.js proponuje bardzo podobne funkcjonalności co Angular, a jednocześnie można odnieść wrażenie, że jest znacznie prostszym frameworkiem niż jego kuzyn od Google. <strong>Próg wejścia</strong> <strong>jest zdecydowanie niższy</strong>, a często możemy napisać prostą aplikację po kilku minutach nauki, znając podstawy <strong>HTML, CSS</strong> <strong>i JavaScript</strong>. Z drugiej strony jednak powoduje to, że <strong>kod może być zdecydowanie gorszej jakości</strong>. Kolejną rzeczą, która w Vue.js, jak i Angularze nie jest doskonałym rozwiązaniem, jest rozbudowanie HTML o dyrektywy, które pozwalają nam <strong>programować na poziomie szablonu</strong>. W mojej opinii znacznie obniża to czytelność kodu.</p>





<h2 class="wp-block-heading" id="React">React</h2>


<div class="wp-block-image">
<figure class="alignleft size-full"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/JPro_2022.01.05_react.png" alt="React" class="wp-image-58563" title="Najlepsze frameworki frontendowe 7"></figure></div>




<p>Zaraz, zaraz – czy należy o nim mówić jak o frameworku? Zdecydowanie nie! Pewnie zastanawiacie się, dlaczego w takim razie w ogóle React znalazł się na tej liście? Przede wszystkim dlatego, że jest to <strong>biblioteka, która ma ogromną część funkcjonalności frameworka</strong>. Wzbogacona o konkretne biblioteki, powoduje, że ekosystem aplikacji reactowej staje się w pełni działającym frameworkiem. Takie rozwiązanie cechuje się tym, że możemy <strong>w swobodny sposób zarządzać kształtem naszej aplikacji</strong>, nie pomijając dobrych praktyk, które narzucają te narzędzia. Użycie <strong>JSX</strong> jako języka szablonów jest dużo bardziej czytelne niż typowy kod HTML. Ponadto w React możemy wszystko uznać za komponenty, co powoduje, że <strong>nie tworzymy dodatkowych struktur z większą złożonością</strong>. W tym ujęciu okazuje się, że moduły nie są potrzebne, a wprowadzają jedynie dodatkową warstwę deklaracji.</p>


<h2 id="Podsumowując-Który-framework-jest-najlepszy">Podsumowując… Który framework jest najlepszy?</h2>




</p>
<p><strong>Z użyciem Angulara można często spotkać się w projektach, w których wymagany jest duży poziom zaufania do narzędzia</strong> oraz istnieje konkretna specyfikacja, jak np. w projektach bankowych. <strong>W mojej ocenie Vue.js jest najmniej trafnym wyborem</strong> spośród wymienionych narzędzi, ponieważ nie wprowadza żadnej rewolucyjności, a sam w sobie miesza mnóstwo warstw w jednym miejscu.</p>
<p>


</p>
<p>



</p>
<p>


</p>
<p>Istnieje mnóstwo rodzajów frameworków frontendowych. Wymienione wyżej są najczęściej używane w ujęciu komercyjnym. <strong>W mojej opinii</strong> <strong>najbardziej przyjaznym oraz najszybszym jest React</strong>. Pozwala on na szybkie pisanie kodu bez dodatkowych konfiguracji.</p>
<p>


</p>
<p>


</p>
<p>Pamiętajcie jednak, że najważniejsze w budowaniu aplikacji, a tym samym przy wyborze frameworków, jest określenie tego, czego potrzebujemy. Opinie na temat frameworków są subiektywne i często zależne od poziomu wiedzy o nich. Jedno moim zdaniem jest pewne: <strong>nie istnieje coś takiego jak <a href="https://nearshore-it.eu/pl/artykuly/frameworkowe-wojny">„najlepszy framework”</a></strong>, ale na pewno można wskazać <strong>„najlepszy framework pod kątem konkretnego rozwiązania”</strong>. Który? Niech zdecyduje o tym zespół developerów, którzy będą pisali aplikację.</p>
<p> </p>
<p>


</p>
<p>


</p>
<p>


</p>


<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/najlepsze-frameworki-frontendowe/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<media:content url="https://www.youtube.com/embed/BsfPmmDSwjM" medium="video" width="1280" height="720">
			<media:player url="https://www.youtube.com/embed/BsfPmmDSwjM" />
			<media:title type="plain">BiteIT #69: React + TypeScript - Użycie hooków w programowaniu funkcyjnym | Marek Suśniak</media:title>
			<media:description type="html"><![CDATA[👀 Prawdopodobnie każda osoba, która pracowała chociaż trochę nad projektem frontend’owym spotkała się z biblioteką React.js. Większość z Was, prawdopodobnie...]]></media:description>
			<media:thumbnail url="https://nearshore-it.eu/wp-content/uploads/2024/09/2021.01.05_JPro_cover.jpg" />
			<media:rating scheme="urn:simple">nonadult</media:rating>
		</media:content>
	</item>
		<item>
		<title>Styled components oraz useContext – użycie hooków w nowoczesnych aplikacjach frontendowych</title>
		<link>https://nearshore-it.eu/pl/artykuly/styled-components-oraz-usecontext-uzycie-hookow-w-nowoczesnych-aplikacjach-frontendowych/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/styled-components-oraz-usecontext-uzycie-hookow-w-nowoczesnych-aplikacjach-frontendowych/#respond</comments>
		
		<dc:creator><![CDATA[Marek Susniak]]></dc:creator>
		<pubDate>Wed, 08 Sep 2021 06:21:54 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/styled-components-oraz-usecontext-uzycie-hookow-w-nowoczesnych-aplikacjach-frontendowych/</guid>

					<description><![CDATA[Jak pewnie wiecie, React od wersji 16.8 wprowadził do swojego code base’u hooki. Początkowo funkcjonalność ta nie wydawała się być tak rewolucyjna, jednak gdy już zacznie się z niej korzystać oraz przepisywać kod na funkcjonalny, nietrudno zauważyć, jak bardzo ułatwiają one pracę. Pojawienie się hooków przełożyło się również na szereg funkcjonalności, które dają nam rozwiązania znanych problemów lub zagadnień.]]></description>
										<content:encoded><![CDATA[
<p></p>



<div class="table-of-contents">
    <p class="title"></p>
    <ol>
                    <li><a href="#styled-components">1.  Styled components</a></li>
                    <li><a href="#biblioteka-redux-w-kontekscie-hookow">2.  Biblioteka Redux w kontekście… hooków</a></li>
                    <li><a href="#theming">3.  Theming</a></li>
                    <li><a href="#podsumowanie">4.  Podsumowanie</a></li>
            </ol>
</div>


<h2 class="wp-block-heading" id="styled-components">Styled components</h2>



<p>Styled components to właśnie jedna ze wspomnianych przeze mnie wyżej funkcjonalności. Styled components jest globalnym rozwiązaniem dla pisania ostylowanych elementów w kodzie JavaScript, które będą stanowiły komponenty reactowe. Dzięki niej jesteśmy w stanie napisać całość kodu bez użycia plików css, scss czy less. Biblioteka ta może zostać znaleziona na stronie <a href="https://styled-components.com/" target="_blank" rel="noopener">https://styled-components.com/.</a> Rozwiązanie pozwala nam również na stylowanie istniejących już komponentów. Jedynym warunkiem, jaki musi spełnić ów komponent, jest to, że powinien posiadać <strong>props className.</strong> Daje to nam bardzo dużą elastyczność w użyciu naszych elementów.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;</pre>



<h2 class="wp-block-heading" id="biblioteka-redux-w-kontekscie-hookow">Biblioteka Redux w kontekście… hooków</h2>



<p>Doskonałym przykładem użycia kontekstu, a w późniejszych wersjach również hooków, jest dobrze znana reactowcom biblioteka Redux. Realizuje ona zadanie przechowywania i propagowania danych w aplikacji bądź w określonym jej obszarze. Dlaczego łączymy te koncepcje? Tak jak wcześniej wspomniałem, <strong>styled components pozwalają na napisanie w bardzo prosty sposób styli w JavaScript dla elementów HTML,</strong> które będą odwzorowaniem tego, co mamy w szeroko znanych css-ach. Hook useContext natomiast umożliwiau dostępnienie danych niższym komponentom w hierarchii.</p>



<h2 class="wp-block-heading" id="theming">Theming</h2>



<p>Pamiętacie setki zmiennych w<strong> less</strong> lub <strong>scss,</strong> które pisaliśmy dla utrzymania spójności kolorystyki i wyglądu elementów? Teraz to wszystko możemy przenieść na poziom JavaScript. Jest to tak zwany <strong>theming.</strong> Dokładną dokumentację opisanego tutaj połączenia znajdziecie na stronie <a href="https://styled-components.com/docs/advanced#theming" target="_blank" rel="noopener">https://styled-components.com/docs/advanced#theming.</a></p>



<p><strong>Theming to niesamowicie wygodne narzędzie, dzięki któremu utrzymanie spójnego wyglądu aplikacji będzie dużo prostsze</strong>. Ponadto można dzięki temu wyegzekwować używanie przez programistów spójnej nomenklatury dla wariantów wyglądu komponentów.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="asm" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// Define our button, but with the use of props.theme this time
const Button = styled.button`
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border-radius: 3px;
 
  /* Color the border and text with theme.main */
  color: ${props => props.theme.main};
  border: 2px solid ${props => props.theme.main};
`;
 
// We are passing a default theme for Buttons that arent wrapped in the ThemeProvider
Button.defaultProps = {
  theme: {
    main: "palevioletred"
  }
}
 
// Define what props.theme will look like
const theme = {
  main: "mediumseagreen"
};
 
render(
  &lt;div>
    &lt;Button>Normal&lt;/Button>
 
    &lt;ThemeProvider theme={theme}>
      &lt;Button>Themed&lt;/Button>
    &lt;/ThemeProvider>
  &lt;/div>
);
</pre>



<p><a href="https://material-ui.com/" target="_blank" rel="noopener">https://material-ui.com/</a> stanowi doskonały przykład użycia naszego połączenia. Jest to biblioteka, która zawiera zbiór szeroko znanych elementów na stronach internetowych i która została napisana w React. Implementuje takie elementy jak: typografia, przyciski, accordiony itd. W niej również można znaleźć rozwinięcie koncepcji themingu oraz realny przykład użycia.</p>



<p><strong>Przeczytaj także: PWA &#8211;<a href="https://jcommerce.catdesignapp.com/angular-zrobmy-swoja-progressive-web-application" target="_blank" rel="noopener"> Progressive Web Applications</a></strong></p>



<h2 class="wp-block-heading" id="podsumowanie">Podsumowanie</h2>



<p>Podsumowując, funkcjonalności, jakie zyskaliśmy wraz z hookami, to naprawdę bardzo dobre narzędzia, które pozwalają napisać aplikację frontendową w łatwy oraz konfigurowalny sposób. W projektach, w które byłem / jestem zaangażowany, nieraz używaliśmy koncepcji themingu i sprawdza się ona doskonale. Spróbujcie sami!</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/styled-components-oraz-usecontext-uzycie-hookow-w-nowoczesnych-aplikacjach-frontendowych/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Angular – zróbmy swoją PWA (Progressive Web App)</title>
		<link>https://nearshore-it.eu/pl/artykuly/angular-zrobmy-swoja-progressive-web-application/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/angular-zrobmy-swoja-progressive-web-application/#respond</comments>
		
		<dc:creator><![CDATA[Michal Wojcik]]></dc:creator>
		<pubDate>Wed, 22 Jan 2020 06:21:30 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[e-commerce]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/angular-zrobmy-swoja-progressive-web-application/</guid>

					<description><![CDATA[Wraz z rozwojem rynku e-commerce rośnie rola i popularność Progressive Web Apps. Aplikacja PWA pozwala stworzyć szybko ładującą się stronę w formie aplikacji mobilnej, która działa w trybie offline. Dodatkowo można liczyć także na docenienie przez roboty indeksujące Google’a, zgodnie z polityką mobile first i offline first, oraz dopracowane doświadczenie użytkownika. W artykule pokażę, jak samodzielnie krok po kroku z pomocą Angulara stworzyć, a następnie skonfigurować i przetestować swoją PWA.]]></description>
										<content:encoded><![CDATA[
<div class="table-of-contents">
    <p class="title">Przejdź do:</p>
    <ol>
                    <li><a href="#Co-to-jest-PWA">1.  Co to jest PWA?</a></li>
                    <li><a href="#Progressive-Web-App-czy-warto">2.  Progressive Web App – czy warto?</a></li>
                    <li><a href="#PWA-Narzedzia-dla-developera">3.  PWA– narzędzia dla developera</a></li>
                    <li><a href="#Dodanie-Progressive-Web-App-do-Angulara">4.  Dodanie Progressive Web App do Angulara</a></li>
                    <li><a href="#Jak-sprawdzic-dzialanie-PWA">5.  Jak sprawdzić działanie PWA?</a></li>
                    <li><a href="#Mamy-PWA-co-dalej">6.  Mamy PWA – co dalej?</a></li>
                    <li><a href="#Podsumowanie">7.  Podsumowanie</a></li>
            </ol>
</div>


<h2 class="wp-block-heading" id="Co-to-jest-PWA"><strong>Co to&nbsp;jest PWA?</strong></h2>



<p>Aplikacja PWA (Progressive Web App) jest stroną internetową, która zachowuje się jak aplikacja mobilna. Upraszczając, aplikacja PWA od &#8222;zwykłej&#8221; strony internetowej z JavaScript różni się w zasadzie tym, że posiada service worker oraz plik manifest json. Z punktu widzenia użytkownika działa niemal jak natywna aplikacja mobilna, ponieważ service worker umożliwia działanie w trybie offline, a plik manifest json odpowiada za jej wizualne podobieństwo. Z punktu widzenia developera aplikacja PWA daje możliwości stworzenia lepszego doświadczenia dla użytkownika końcowego. W tym krótkim artykule postaram się opisać konfigurację PWA przy użyciu Angulara, która jest bardzo prosta dzięki natywnemu wsparciu przez Angular CLI. Sama konfiguracja service workera nie ogranicza nas jednak tak naprawdę do użycia określonego frameworka JavaScript, typu React Angular czy Vue.js.</p>



<h2 class="wp-block-heading" id="Progressive-Web-App-czy-warto"><strong>Progressive Web App – czy&nbsp;warto?</strong></h2>



<p>Ponad połowa internautów w&nbsp;Polsce korzysta ze stron internetowych za&nbsp;pomocą urządzeń mobilnych, a&nbsp;posiadanie responsywnej, szybko ładującej się strony to&nbsp;obecnie być albo&nbsp;nie&nbsp;być w&nbsp;e-commerce. Wykorzystanie poprawnie zbudowanej aplikacji PWA znacznie ułatwia spełnienie wymagań i zaleceń optymalizacyjnych Google’a, przekłada się też na&nbsp;konkretne rezultaty – w&nbsp;niektórych przypadkach PWA pozwoliła&nbsp;<a href="https://developers.google.com/web/showcase/2016/flipkart" target="_blank" rel="noopener noreferrer">podnieść współczynnik konwersji o&nbsp;70%</a>.</p>



<p>Korzystanie z aplikacji PWA ułatwia możliwość jej instalacji na pulpicie urządzenia końcowego (nie wymaga pobierania z Google Play/ App Store). Użytkownik może korzystać z aplikacji w trybie offline (dane zsynchronizują się w momencie nawiązania połączenia). PWA to również funkcjonalność powiadomień push, które znacząco zwiększają zaangażowanie i są skuteczną metodą odzyskiwania utraconych koszyków w e-commerce.</p>



<p>Koszt rozwoju i utrzymania aplikacji PWA jest nieporównywalnie mniejszy niż w przypadku aplikacji natywnych. Nie wymaga akceptacji procesu aktualizacji po stronie sklepu z aplikacjami, co znacznie usprawnia szybkość wdrażania kolejnych wersji, ułatwia też analizę danych i raportowanie.</p>



<h2 class="wp-block-heading" id="PWA-Narzedzia-dla-developera"><strong>Progressive Web Apps –</strong>&nbsp;<strong>narzędzia dla developera</strong></h2>



<p>Istnieją liczne strony takie jak&nbsp;<a href="https://whatwebcando.today/" target="_blank" rel="noopener noreferrer">https://whatwebcando.today/</a><u>,&nbsp;</u>które zapewniają wsparcie dla developerów. W prosty sposób można uzyskać dostęp do komponentów poprzez JavaScript i service workera. Warto tutaj wspomnieć, że pełne wsparcie komponentów posiada jedynie Google Chrome na systemie Android. Niestety, iPhone z Safari ogranicza nas w niektórych miejscach. Wsparcie komponentów tak dynamicznie się zmienia, że nie warto tutaj poruszać tematu różnic między przeglądarkami. W pierwszej części artykułu postaram się wytłumaczyć, jak w pełni skonfigurować oraz przetestować naszą aplikację. W dalszej części skupię się na innych komponentach, jak tryb offline, notyfikacje, geolokalizacja czy dostęp do plików. Gotowi na przygodę z PWA? Zacznijmy!</p>



<h2 class="wp-block-heading" id="Dodanie-Progressive-Web-App-do-Angulara"><strong>Dodanie Progressive Web App do&nbsp;Angulara</strong></h2>



<p>Zaczynamy od&nbsp;zainstalowania aplikacji angularowej przez&nbsp;Angular CLI. Następnie należy wywołać komendę&nbsp;<strong>ng add @angular/pwa</strong></p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter size-full"><img fetchpriority="high" decoding="async" width="600" height="356" src="https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_1-e1727098585347.jpg" alt="PWA angular ng add @angular/pwa" class="wp-image-29535" title="Angular – zróbmy swoją PWA (Progressive Web App) 8" srcset="https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_1-e1727098585347.jpg 600w, https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_1-e1727098585347-300x178.jpg 300w, https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_1-e1727098585347-495x294.jpg 495w" sizes="(max-width: 600px) 100vw, 600px" /></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Dzięki temu w naszym folderze zostaje dodanych kilka plików potrzebnych do uruchomienia PWA:</p>



<p><strong>ngsw-config.json</strong> – plik konfiguracyjny, który pozwala na ustawienie reguł cache’owania danych. Więcej informacji o strategiach cache’owania można znaleźć tutaj: <a href="https://serviceworke.rs/caching-strategies.html" target="_blank" rel="noopener">https://serviceworke.rs/caching-strategies.html</a></p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="608" height="591" src="https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_2-e1727099074608.jpg" alt="PWA Angular - plik konfiguracyjny - cache’owanie danych" class="wp-image-29538" title="Angular – zróbmy swoją PWA (Progressive Web App) 9" srcset="https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_2-e1727099074608.jpg 608w, https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_2-e1727099074608-300x292.jpg 300w, https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_2-e1727099074608-406x395.jpg 406w" sizes="(max-width: 608px) 100vw, 608px" /></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-text-align-center"><em>Na konfiguracji tego pliku skupimy się w kolejnej części artykułu.</em></p>



<p><strong>manifest.webmanifest</strong> – plik konfiguracyjny, który pozwala na ustawienie zachowania naszej aplikacji po zapisaniu przez użytkownika (orientacja, kolory, ikony).</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="606" height="1057" src="https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_3-e1727099183118.jpg" alt="PWA Angular - manifest.webmanifest" class="wp-image-29541" title="Angular – zróbmy swoją PWA (Progressive Web App) 10" srcset="https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_3-e1727099183118.jpg 606w, https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_3-e1727099183118-172x300.jpg 172w, https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_3-e1727099183118-226x395.jpg 226w" sizes="(max-width: 606px) 100vw, 606px" /></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>*.png</strong> – domyślne ikony, które będą wyświetlać się użytkownikowi po zapisaniu aplikacji na pulpicie ekranu.</p>



<p>Dodatkowo zostaną zaktualizowane pliki:</p>



<p><strong>angular.json</strong> (ustawiona flaga ServiceWorker: true),</p>



<p><strong>index.html</strong> – dodana linijka do wczytania manifestu,</p>



<p><strong>app.module.ts</strong></p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="576" height="59" src="https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_4-e1727099280942.jpg" alt="PWA Angular - app.module.ts" class="wp-image-29544" title="Angular – zróbmy swoją PWA (Progressive Web App) 11" srcset="https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_4-e1727099280942.jpg 576w, https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_4-e1727099280942-300x31.jpg 300w, https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_4-e1727099280942-495x51.jpg 495w" sizes="auto, (max-width: 576px) 100vw, 576px" /></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Dzięki temu nasza aplikacja wie, że gdy uruchomimy ją w trybie produkcyjnym, service worker powinien zostać zarejestrowany do naszej przeglądarki.</p>



<h2 class="wp-block-heading" id="Jak-sprawdzic-dzialanie-PWA">Jak sprawdzić działanie PWA?</h2>



<p>Niestety samo uruchomienie aplikacji przez Angular CLI nie pozwoli nam sprawdzić, czy service worker działa poprawnie. Możemy jednak w łatwy sposób to obejść, uruchamiając zbudowaną przez siebie aplikację lokalnie. Można to zrobić łatwo w dwóch krokach.</p>



<ol class="wp-block-list">
<li>Budujemy aplikację w trybie produkcyjnym: <strong>ng build &#8211;prod</strong></li>



<li>Uruchamiamy http-server (jeżeli nie mamy zainstalowanego lokalnie, to najpierw: <strong>npm i http-server -g</strong>) komenda: <strong>http-server ./dist/pwa-test -o</strong></li>
</ol>



<p>Pamiętajmy, że po <strong>dist</strong> należy wprowadzić swoją nazwę aplikacji. Po wpisaniu komendy powinna uruchomić się nasza strona internetowa. Aby sprawdzić poprawność service workera i manifestu, użyjemy wbudowanych narzędzi w Google Chrome. Po uruchomieniu Developers Tools przechodzimy do zakładki <strong>Application.</strong></p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="600" height="340" src="https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_5-e1727099349383.jpg" alt="PWA Angular - uruchamianie aplikacji PWA lokalnie" class="wp-image-29547" title="Angular – zróbmy swoją PWA (Progressive Web App) 12" srcset="https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_5-e1727099349383.jpg 600w, https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_5-e1727099349383-300x170.jpg 300w, https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_5-e1727099349383-495x281.jpg 495w" sizes="auto, (max-width: 600px) 100vw, 600px" /></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p>W menu bocznym <strong>Service Worker</strong> powinniśmy zobaczyć informację, że nasz service worker został odnaleziony i jest poprawnie zainstalowany.</p>



<p>W zakładce <strong>Manifest</strong> znajdziemy z kolei informację, czy domyślna konfiguracja (kolory, ikony oraz nazwa) jest zaimportowana poprawnie.</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="600" height="340" src="https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_6-e1727099391161.jpg" alt="PWA Angular - testowanie pliku manifest json lokalnie" class="wp-image-29550" title="Angular – zróbmy swoją PWA (Progressive Web App) 13" srcset="https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_6-e1727099391161.jpg 600w, https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_6-e1727099391161-300x170.jpg 300w, https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_6-e1727099391161-495x281.jpg 495w" sizes="auto, (max-width: 600px) 100vw, 600px" /></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Wszystkie te dane są zaczytywane z plików, które zostały wygenerowane przez Angular CLI po zbudowaniu aplikacji. Znajdują się one w folderze <strong>/dist/NazwaAplikacji.</strong></p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="312" height="344" src="https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_7-e1727099430732.jpg" alt="PWA Angular - testowanie lokalnie" class="wp-image-29553" title="Angular – zróbmy swoją PWA (Progressive Web App) 14" srcset="https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_7-e1727099430732.jpg 312w, https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_7-e1727099430732-272x300.jpg 272w" sizes="auto, (max-width: 312px) 100vw, 312px" /></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Dzięki pozytywnemu wgraniu manifestu oraz service workera nasza aplikacja pozwala na korzystanie w pełni z komponentów na urządzeniu mobilnym czy komputerze.</p>



<h2 class="wp-block-heading" id="Mamy-PWA-co-dalej">Mamy PWA – co dalej?</h2>



<p>Dzięki domyślnej konfiguracji możemy jedynie zapisać naszą aplikację na telefonie czy komputerze. Aby to zrobić, na komputerze wystarczy kliknąć ikonę plusika obok adresu strony internetowej.</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="884" height="101" src="https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_8-e1727099461510.jpg" alt="PWA Angular - pobieranie aplikacji na telefon" class="wp-image-29556" title="Angular – zróbmy swoją PWA (Progressive Web App) 15" srcset="https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_8-e1727099461510.jpg 884w, https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_8-e1727099461510-300x34.jpg 300w, https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_8-e1727099461510-768x88.jpg 768w, https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_8-e1727099461510-495x57.jpg 495w" sizes="auto, (max-width: 884px) 100vw, 884px" /></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Nazwa oraz ikona są pobierane z pliku <strong>manifest.</strong></p>



<p>Po zapisaniu nasza strona internetowa będzie zachowywać się jak aplikacja, a użytkownik nie jest świadomy, że uruchamia stronę internetową w przeglądarce. Po uruchomieniu aplikacji (po zapisaniu) powinno nam się wyświetlić tak wyglądające okno:</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="576" height="340" src="https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_9-e1727099510814.jpg" alt="PWA Angular - ekran aplikacji" class="wp-image-29559" title="Angular – zróbmy swoją PWA (Progressive Web App) 16" srcset="https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_9-e1727099510814.jpg 576w, https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_9-e1727099510814-300x177.jpg 300w, https://nearshore-it.eu/wp-content/uploads/2024/09/Angular_screen_9-e1727099510814-495x292.jpg 495w" sizes="auto, (max-width: 576px) 100vw, 576px" /></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p><em>Jak widać na zdjęciu, znikł cały górny pasek z adresem, dodatkami oraz zakładkami. Użytkownik nie jest świadomy, że aplikacja uruchomiła się w przeglądarce.</em></p>



<p>Udało nam się skonfigurować aplikację startową w Angularze, tak aby zachowywała się jak Progressive Web Application. Użytkownik korzystający z naszej strony może na razie jedynie ją zapisać. W kolejnych krokach możemy dodać trochę kodu do naszej aplikacji, tak aby poinformować użytkownika o nowych wersjach naszej strony czy umożliwić korzystanie z niej w trybie offline. W kolejnych artykułach rozwinę temat PWA, pisząc o tym, jak rozwinąć naszą nowo powstałą aplikację o nowe funkcjonalności.</p>



<h2 class="wp-block-heading" id="Podsumowanie">Podsumowanie</h2>



<p>Stworzenie i konfiguracja PWA nie są trudne. W sieci pojawia się coraz więcej publikacji o możliwościach technologii, która już teraz jest nazywana frontendową rewolucją. Nic dziwnego – Progressive Web Application pozwała w łatwy sposób stworzyć przyjazną i szybko ładującą się stronę. Dla developerów to sygnał, że wykorzystując technologię PWA, wdrażają rozwiązanie, które przyniesie konkretne, mierzalne rezultaty.</p>



<p>Czytaj również: <a href="https://nearshore-it.eu/pl/artykuly/najlepsze-frameworki-frontendowe/">Który framework frontendowy jest najlepszy?</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/angular-zrobmy-swoja-progressive-web-application/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
