<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Spaceout blog]]></title><description><![CDATA[Spaceout blog]]></description><link>https://blog.spaceout.pl/</link><image><url>https://blog.spaceout.pl/favicon.png</url><title>Spaceout blog</title><link>https://blog.spaceout.pl/</link></image><generator>Ghost 3.12</generator><lastBuildDate>Wed, 21 Oct 2026 21:55:39 GMT</lastBuildDate><atom:link href="https://blog.spaceout.pl/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[ESBuild czyli czy da radę zapomnieć o webpacku ?]]></title><description><![CDATA[<p></p><p>Poprzednia dekada przyniosła programistom rozkwit narządzi typu "bundler".  W okolicach roku 2010 można było jeszcze spotkać, że pliki strony czy appek webowych były przygotowywane ręcznie przez programistów na produkcje.  W roku 2021 żaden chyba profesjonalny developer nie robi manualnie takich procesów jak minimalizacja js, css, konwertowanie js w es6 na</p>]]></description><link>https://blog.spaceout.pl/esbuild-czyli-czy-da-sie-zapomniec-o-webpacku/</link><guid isPermaLink="false">60f28de7d49b7f49e445dcc4</guid><category><![CDATA[esbuild]]></category><category><![CDATA[express.js]]></category><category><![CDATA[Typescript]]></category><category><![CDATA[React.js]]></category><category><![CDATA[node.js]]></category><category><![CDATA[tailwindcss]]></category><dc:creator><![CDATA[Spaceghost]]></dc:creator><pubDate>Sun, 18 Jul 2021 21:40:56 GMT</pubDate><media:content url="https://blog.spaceout.pl/content/images/2021/07/36C1938E-9893-4EA6-A9DF-EB46437E7180.jpeg" medium="image"/><content:encoded><![CDATA[<img src="https://blog.spaceout.pl/content/images/2021/07/36C1938E-9893-4EA6-A9DF-EB46437E7180.jpeg" alt="ESBuild czyli czy da radę zapomnieć o webpacku ?"><p></p><p>Poprzednia dekada przyniosła programistom rozkwit narządzi typu "bundler".  W okolicach roku 2010 można było jeszcze spotkać, że pliki strony czy appek webowych były przygotowywane ręcznie przez programistów na produkcje.  W roku 2021 żaden chyba profesjonalny developer nie robi manualnie takich procesów jak minimalizacja js, css, konwertowanie js w es6 na es5 czy innych transformacji związanych w tworzeniu tak zwanego "bundle" produkcyjnego.  </p><p>Narzędzia takie jak grunt, gulp przyczyniły się do rozwoju obecnie chyba najbardziej wykorzystywanego "bundlera" czyli webpack'a. Webpack i familia  to naprawdę potężna i dobrze działająca machina. Na pewno dobry wybór nawet i do corporate level app, z dobrą dokumentacją oraz bardzo dużym ekosystemem. </p><p>Webpack jako "stary wół" jest jednak czasem dość powolny, następne iteracje webpacka wydają się nie wpływać na jego performance, a wręcz przeciwnie jego performance spada tak  jak to sugeruje  strona główna esbuild.</p><h2 id="enter-the-esbuild">Enter the esbuild </h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.spaceout.pl/content/images/2021/07/image.png" class="kg-image" alt="ESBuild czyli czy da radę zapomnieć o webpacku ?"><figcaption><a href="https://esbuild.github.io/">https://esbuild.github.io/</a></figcaption></figure><p>Natrafiłem na esbuild'a już jakiś czas temu, nowej generacji "bundler" o "niesamowitych" osiągach.  Jako że w tamtym czasie był dopiero na początku swojej drogi, nie poświeciłem mu zbytnio dużo czasu.  Pracując ostatnio nad optymalizacją buildu (webpack), w konfiguracji loadera plików ts podmieniłem ts-loader na esbuild-loader, 40%-50% szybszy build time okazał się dużym zaskoczeniem. </p><p>Zachęcony wynikami, postanowiłem sprawdzić czy da rade porzucić webpacka na esbuild i jak rożni się praca pomiędzy młodym zawodnikiem (esbuild) a wysłużonym weteranem (webpack v5). </p><p>Na cel objąłem full stackowy setup node.js (express) + react. </p><p>Pierwsze kroki przygotowania bundle poszły dość bezproblemowo, dość ogarnięta dokumentacja esbuilda pomaga. Esbuild integruje się z TS bez zbędnych pluginów, works out of the box wraz z pobieraniem aliasów z tsconfig.json (np @components)</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">const { build } = require('esbuild');
const fs = require('fs-extra');
const postCss = require('esbuild-plugin-postcss2').default;
const autoprefixer = require('autoprefixer');
const tailwindcss = require('tailwindcss');

const generateBuild = async () =&gt; {
  await fs.rmdirSync('./build/public/static', { recursive: true });

  await build({
    // Bundles JavaScript.
    bundle: true,
    sourcemap: true,
    loader: { '.svg': 'dataurl', '.png': 'dataurl' },
    // Defines env variables for bundled JavaScript; here `process.env.NODE_ENV`
    // is propagated with a fallback.
    define: {
      'process.env.NODE_ENV': JSON.stringify(
        process.env.NODE_ENV || 'development',
      ),
    },
    // Bundles JavaScript from (see `outfile`).
    entryPoints: ['./src/client/index.tsx'],
    // Uses incremental compilation (see `chokidar.on`).
    incremental: true,
    // Removes whitespace, etc. depending on `NODE_ENV=...`.
    minify: true,
    // Bundles JavaScript to (see `entryPoints`).
    outdir: './build/static/',
    plugins: [
      postCss({
        plugins: [autoprefixer, tailwindcss],
      }),
    ],
  }).catch(() =&gt; process.exit(1));

  process.exit(0);
};

generateBuild();</code></pre><figcaption>esbuild posiada wbudowane opcje env, możliwość podłączenia "community plugins", udało także się podłączyć <a href="https://postcss.org/">postCSS</a> i <a href="https://tailwindcss.com/">tailwindCSS</a> wraz z czyszczeniem stylów kaskadowych (<a href="https://purgecss.com/">purge css</a>).&nbsp;</figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-javascript">(async () =&gt; {
  // `esbuild` bundler for JavaScript / TypeScript.
  await build({
    // Bundles JavaScript.
    bundle: true,
    sourcemap: false,
    // set platform for node, default is browser
    platform: 'node',
    loader: { '.svg': 'dataurl', '.png': 'dataurl' },
    // Defines env variables for bundled JavaScript; here `process.env.NODE_ENV`
    // is propagated with a fallback.
    define: {
      'process.env.NODE_ENV': JSON.stringify(
        process.env.NODE_ENV || 'Production',
      ),
    },
    // Bundles JavaScript from (see `outfile`).
    entryPoints: ['./src/server/index.ts'],
    // Uses incremental compilation (see `chokidar.on`).
    incremental: true,
    // Removes whitespace, etc. depending on `NODE_ENV=...`.
    minify: true,
    // Bundles JavaScript to (see `entryPoints`).
    outdir: './build/',
  }).catch(() =&gt; process.exit(1));

  process.exit(0);
})();</code></pre><figcaption>esbuild build function potrzebuje tylko flagę z platformą node aby, zkompliować podstawowy serwer express.js, napisany w typsecriptcie. Tutaj także trzeba przyznać, że konfiguracja przeszła szybko i bezproblemowo.</figcaption></figure><h2 id="webpack-dev-server">Webpack-dev-server ? </h2><p>Ale praca "na projekcie" to nie sam build, o ile nodemon w sprawie serwera daje sobie  spokojnie radę, to pytanie co z HMR, Live relead dla Reacta ? Esbuild może jest i szybki,  ale żaden z devów nie chce klikać refresh co chwilę, dodatkowo gubiąc stan komponentów. </p><p>Niestety brakuje esbuildowi rozsądnego rozwiązania czy pluginu z community w temacie live developmentu, na pewno brakuje tutaj jakieś wskazówki, "oficjalnej" konkretnej ścieżki jak można by było osiągnąć hot refreash, ja w końcu zdecydowałem się na bibliotekę "servor", rozgrzewa się na pewno trochę dłużej niż webpack-dev-server ale zdaje egzamin w  sprawie live reloadu. </p><figure class="kg-card kg-bookmark-card kg-card-hascaption"><a class="kg-bookmark-container" href="https://github.com/lukejacksonn/servor"><div class="kg-bookmark-content"><div class="kg-bookmark-title">lukejacksonn/servor</div><div class="kg-bookmark-description">Dependency free file server for single page app development - lukejacksonn/servor</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://github.githubassets.com/favicons/favicon.svg" alt="ESBuild czyli czy da radę zapomnieć o webpacku ?"><span class="kg-bookmark-author">lukejacksonn</span><span class="kg-bookmark-publisher">GitHub</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://opengraph.githubassets.com/4ca6f6fc321f3ce2f554331d43171dde5cca44b3867ff5ce7cd8c40d97b93a9f/lukejacksonn/servor" alt="ESBuild czyli czy da radę zapomnieć o webpacku ?"></div></a><figcaption>r</figcaption></figure><p>esbuild jest na razie bardzo eksperymentalnym projektem, z bardzo ograniczonym ekosystemem pluginów.  Brakuje mu dużo stabilności i dojrzałości, jest jednak nadzieja na nowej generacji bundler, który jeszcze bardziej przyczyni się do poprawy wydajności pracy programisty w przyszłości. </p><p>Do tego czasu, na razie proponuje jednak spróbować esbuild-loader w  waszych ustawieniach webpacka. </p><p>Przykładowe repo z ustawieniem esbuild only </p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://github.com/MassivDash/typescript-react-express-esbuild"><div class="kg-bookmark-content"><div class="kg-bookmark-title">MassivDash/typescript-react-express-esbuild</div><div class="kg-bookmark-description">Express.js + React + Typescript + Esbuild + tailwindCss - MassivDash/typescript-react-express-esbuild</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://github.githubassets.com/favicons/favicon.svg" alt="ESBuild czyli czy da radę zapomnieć o webpacku ?"><span class="kg-bookmark-author">MassivDash</span><span class="kg-bookmark-publisher">GitHub</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://opengraph.githubassets.com/0745d4173b7126ec140bff1614273fff72e96686c3c4d71af5ad09bf38f9ebe1/MassivDash/typescript-react-express-esbuild" alt="ESBuild czyli czy da radę zapomnieć o webpacku ?"></div></a></figure>]]></content:encoded></item><item><title><![CDATA[Svelte Chess Timer]]></title><description><![CDATA[<p>Ostatnio coraz bardziej przekonuje się do nowego javascript frameworka svelte.js (więcej o tym możecie przeczytać na moim blogu, <a href="https://blog.spaceout.pl/sveltecybernetically-enhanced-web-apps/">tutaj</a>). </p><p>W ramach ćwiczeń i ekspolracji tego nowego narzędzia postanowiłem zrobić mini apkę. Jestem zagorzałem fanem gry w szachy, za młodu próbowałem nawet swoich sił w szelakich turniejach, co zawsze będzie</p>]]></description><link>https://blog.spaceout.pl/svelte-chess-timer/</link><guid isPermaLink="false">60db6959d49b7f49e445dc4a</guid><category><![CDATA[svelte.js]]></category><category><![CDATA[framework]]></category><category><![CDATA[JS]]></category><category><![CDATA[responsive]]></category><category><![CDATA[ux]]></category><dc:creator><![CDATA[Spaceghost]]></dc:creator><pubDate>Tue, 29 Jun 2021 21:21:54 GMT</pubDate><media:content url="https://blog.spaceout.pl/content/images/2021/06/image_processing20200721-7132-589sbj.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.spaceout.pl/content/images/2021/06/image_processing20200721-7132-589sbj.png" alt="Svelte Chess Timer"><p>Ostatnio coraz bardziej przekonuje się do nowego javascript frameworka svelte.js (więcej o tym możecie przeczytać na moim blogu, <a href="https://blog.spaceout.pl/sveltecybernetically-enhanced-web-apps/">tutaj</a>). </p><p>W ramach ćwiczeń i ekspolracji tego nowego narzędzia postanowiłem zrobić mini apkę. Jestem zagorzałem fanem gry w szachy, za młodu próbowałem nawet swoich sił w szelakich turniejach, co zawsze będzie mi się kojarzyło z bardziej profesjonalną grą, to zegar szachowy. </p><p>I właśnie taki zegar szachowy postanowiłem przenieść na świat wirtualny. Praca z apką przy użyciu svelte była dla mnie czystą radością. Myśle że ten framework ma dużo do zaferowania pod względem trzymania stanu czy reaktywności komponetów, do tego oferując bardzo dobry performance. </p><figure class="kg-card kg-image-card"><img src="https://blog.spaceout.pl/content/images/2021/06/12cfcf101086777.5f170fd51556e.jpeg" class="kg-image" alt="Svelte Chess Timer"></figure><p>Co według mnie potrzebuje dobry zegar szachowy ? Po pierwsze nie zależny system timerów, często podczas ćwiczeń z lepszymi zawodnikami, ustawiali sobie oni mniej czasu, gra pod presją czasową to zupełnia inna gra w szachy. Tarcze timerów maja możliwość obrotu dając możliwość położenia telefonu obok szachownicy tak aby obydwaj gracze mogli widzieć swój czas. Zmiana tury odbywa sie poprzez dotknięcie tarczy zegara gracza. </p><figure class="kg-card kg-image-card"><img src="https://blog.spaceout.pl/content/images/2021/06/b4b83f101086777.5f170fd515a4a.png" class="kg-image" alt="Svelte Chess Timer"></figure><p>Zachecam do korzystania, apka totalnie za free, zero trackerów ani tego typu podobnych rzeczy. Powodzenia w przyszłych grach. </p><p>Apka znajduje się tutaj: <a href="https://chess-timer.spaceout.pl/">https://chess-timer.spaceout.pl/</a></p><p>Repo:  <a href="https://github.com/MassivDash/Svelte-Chess-Timer">https://github.com/MassivDash/Svelte-Chess-Timer</a></p>]]></content:encoded></item><item><title><![CDATA[Co to jest Service Worker.js ? Aplikacja progresywna od Google.]]></title><description><![CDATA[Aplikacja progresywna (progreessive application) to nowy typ aplikacji  mocno wspierany przez Google. W założeniu serviceworker.js, skypt oparty na java scriptcie tworzy specjalny ...]]></description><link>https://blog.spaceout.pl/co-to-jest-service-worker-js-aplikacja-progresywna-od-google/</link><guid isPermaLink="false">5e7f498a028743ff49f7ba93</guid><category><![CDATA[javascript]]></category><category><![CDATA[serviceworker]]></category><category><![CDATA[proggressive website app]]></category><dc:creator><![CDATA[Spaceghost]]></dc:creator><pubDate>Tue, 24 Mar 2020 11:02:32 GMT</pubDate><media:content url="https://blog.spaceout.pl/content/images/2020/03/pwa.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://blog.spaceout.pl/content/images/2020/03/pwa.jpg" alt="Co to jest Service Worker.js ? Aplikacja progresywna od Google."><p>Aplikacja progresywna (progreessive application) to nowy typ aplikacji mocno wspierany przez Google. W założeniu serviceworker.js, skypt oparty na java scriptcie tworzy specjalny gateway, "program" który ma się stać mostem pomiędzy aplikacją w trybie online i offline.</p><p>Do tej pory istniały głównie dwa podejścia do budowy aplikacji webowych i mobilnych. Wersja online czyli typowe aplikacja internetowa (netflix, facebook) oraz aplikacje offline (którą trzeba wcześniej ściągnąć).</p><p>Tutaj wchodzi service worker i daje 2 dodatkowe możliwości rozwoju aplikacji; Online first oraz offline first, oraz duże możliwości zarządzaniem cache naszej strony / aplikacji.</p><p>Możemy przechwytywać żądania użytkownika, zmusić przeglądarkę aby ściągnęła i zachowała treści i zdjęcia. Dodatkowo ustalać zasady dotyczące priorytetu treści online / offline. Service worker odpowiednio skonfigurowany pomoże także w sytuacji "lie-fi" (dobry zasięg a jednak sie nie otwiera ... )</p><p>Warto zaznaczyć że jak narazie service worker jest obsługiwany tylko przeglądarkę Chrome (Web / Android), dodatkowym wymogiem jest protokół HTTPS.</p><h2 id="jak-to-dzia-a"><strong>Jak to działa ?</strong></h2><p>W praktyce nasza strona internetowa może zostać pełnoprawną ikonką w momencie otworzenia przez urządzenia mobilne.</p><figure class="kg-card kg-image-card"><img src="https://blog.spaceout.pl/content/images/2020/03/proggersiveapp.png" class="kg-image" alt="Co to jest Service Worker.js ? Aplikacja progresywna od Google."></figure><p>Po wejściu w naszą aplikację progresywną, pojawia się wcześniej ustalony splashscreen. Stronę / aplikację możemy pokazywać w wybranej formie: standalone (full screen), Web browser. Ustalić orientację ekranu itp ...</p><p>Co najważniejsze i najfajniejsze w tym wszytskim ?</p><h3 id="nasza-strona-dzia-a-w-trybie-offline-na-kom-rki-i-na-komputerze-"><strong>Nasza strona działa w trybie offline na komórki i na komputerze.</strong></h3><h4 id="service-worker"><strong>Service Worker</strong></h4><p>Rejestracja serviceworker.js na index.html / index.js<br>Typowa rejestracja serviceworker następuje przez umieszczenie następującego js scriptu;</p><pre><code>
if ('serviceWorker' in navigator) {
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('/service-worker.js');
  });
}
</code></pre><p>Przyklad prostego service workera do pracy w trybie offline;</p><pre><code>

"use strict";

console.log('WORKER: executing.');

/* Numer wersji może się okazać pomocny podczas updatu naszego service workera. 
*/
var version = 'v1::';

/* Poniższe zasoby będą ściągane podczas instalacji naszej progresywnej appki na komputer czy komórkę. Jeżeli coś się nie powiedzie, service worker nie zostanie zainstalowany.
*/
var offlineFundamentals = [
  '',
  '/assets/css/style.css',
  '/assets/js/global.js'
];

/*  Instalacja zostanie rozpoczęta, gdy serviceworker.js zostanie najpierw zainstalowany. Możesz użyć "event listener", aby przygotować sw.js do obsługi
   plików, gdy odwiedzający są w trybie offline.
*/
self.addEventListener("install", function(event) {
  console.log('WORKER: install event in progress.');
  /* Użycie event.waitUntil(p) blokuje instalacje na poniższym "promise" czyli 
     asychonicznym wezwaniu. Jeżeli "promise" zostanie odrzucony, service worker nie będzie zainstalowany.
  */
  event.waitUntil(
    /* Wbudowany API "Cache" oparty na "promise" pomaga w cachowaniu odpowiedzi, znajdowaniu i usuwaniu plików.
    */
    caches
      /* To pozwala aby otwierac cache po nazwie, ta metoda także zwraca "promise". Możemy używać "versioned cache name", przypisanej nazwy cache aby poźniej pozbywac się starszych wpisów / "entries" z cache'u, kiedy będziemy wprowadzać nowego service workera. 
      */
      .open(version + 'fundamentals')
      .then(function(cache) {
        /* Po otworzeniu cache, możemy go uzupełnić z zapisanymi wcześniej "offline fundamentals".
        */
        return cache.addAll(offlineFundamentals);
      })
      .then(function() {
        console.log('WORKER: install completed');
      })
  );
});

/* Zdarzenie pobierania jest wywoływane za każdym razem, gdy strona kontrolowana przez tego serviceworker.js żada zasoby (request) zasób. Nie jest to tylko  ograniczone do żądania  `fetch` lub nawet XMLHttpRequest, ale nawet do request'u strony HTML przy pierwszym załadowaniu, plików JS, CSS, fontów czy obrazów itp.
*/
self.addEventListener("fetch", function(event) {
  console.log('WORKER: fetch event in progress.');

  /* Powinnismy cacho'wac tylko "GET request", resztą niech zajmie się przeglądarka poprzez zarządzanie (handling) nieudanymi requestów "POST,PUT,PATCH, itp".
  */
  if (event.request.method !== 'GET') {
    /* 
Jeśli nie zablokujemy zdarzenia, jak pokazano poniżej, żądanie zostanie wysłane przez sieć jak zwykle.
    */
    console.log('WORKER: fetch event ignored.', event.request.method, event.request.url);
    return;
  }
  /* Podobnie jak "event.waitUntil", blokujemy zdarzenie pobierania na "promise" 
     Wynik realizacji zostanie użyty jako odpowiedź, a odrzucenie zakończy się na
     Odpowiedzi (http) informująca o awarii.
  */
  event.respondWith(
    caches
      /* 
Ta metoda zwraca "promise", która rozwiązuje problem z dopasowaniem wpisu pamięci podręcznej (cache) do naszego request'u. Gdy "promise" zostanie spełniony, będziemy mogli udzielić odpowiedzi na żądanie pobrania.
      */
      
      .match(event.request)
      .then(function(cached) {

/* Nawet jeśli odpowiedź znajduje się w naszej pamięci podręcznej, robimy wezwanie także do do sieci. Ten wzorzec jest znany z wywoływania "świeżych" reakcji,gdzie natychmiast zwracamy buforowane odpowiedzi, a tymczasem ciągniemy odpowiedź sieciowa i zapisz ją w pamięci podręcznej.
*/
        var networked = fetch(event.request)
          // We handle the network request with success and failure scenarios.
          .then(fetchedFromNetwork, unableToResolve)
          // We should catch errors on the fetchedFromNetwork handler as well.
          .catch(unableToResolve);

        /* We return the cached response immediately if there is one, and fall
           back to waiting on the network as usual.
        */
        console.log('WORKER: fetch event', cached ? '(cached)' : '(network)', event.request.url);
        return cached || networked;

        function fetchedFromNetwork(response) {
        
/* Klonujemy  "response". To jest odpowiedź, która będzie przechowywana w pamięci podręcznej ServiceWorker. */

          var cacheCopy = response.clone();

          console.log('WORKER: fetch response from network.', event.request.url);

          caches
            //Otwieramy pamięć podręczną, aby zapisać odpowiedź na to żądanie. 
            
            .open(version + 'pages')
            .then(function add(cache) {
            
              /* Przechowujemy odpowiedź na to żądanie. Później ta odpowiedz będzie  dostępna dla wywołań caches.match (event.request) podczas wyszukiwania zbuforowanych odpowiedzi. 
              */
              return cache.put(event.request, cacheCopy);
            })
            .then(function() {
              console.log('WORKER: fetch response stored in cache.', event.request.url);
            });

          // Zwróć odpowiedź, aby obietnica została spełniona.
          return response;
        }

        /* Gdy wywoływana jest ta metoda, oznacza to, że nie jesteśmy w stanie wytworzyć odpowiedzi z pamięci podręcznej lub sieci. Dobra okazja do wyświetlenia jakies wiadomosci jeżeli wszystko inne zawiedzie. Typu "Usługa niedostępna" lub ogólna wiadomość błędu.
        */
        function unableToResolve () {
       

          console.log('WORKER: fetch request failed in both cache and network.');

          /* Tutaj programujemy odpowiedź. Pierwszym parametrem jest
             treść odpowiedzi, a druga określa opcje odpowiedzi.
          */
          
          return new Response('&lt;h1&gt;Service Unavailable&lt;/h1&gt;', {
            status: 503,
            statusText: 'Service Unavailable',
            headers: new Headers({
              'Content-Type': 'text/html'
            })
          });
        }
      })
  );
});

/* Zdarzenie activate uruchamia się po pomyślnym zainstalowaniu modułu serwisowego.
Jest to najbardziej przydatne przy wycofywaniu starszej wersji, jeżeli serviceworker.js został zainstalowany poprawnie. W tym przykładzie usuwamy stare pamięci podręczne, które nie pasują do wersji w właśnie zakończonym procesie instalacyjnym.
*/
self.addEventListener("activate", function(event) {
  /* Podobnie jak w przypadku instalacji, event.waitUntil aktywuje się na "promise".  Aktywacja zakończy się niepowodzeniem, dopóki "promise" nie zostanie spełniony.
  */
  console.log('WORKER: activate event in progress.');

  event.waitUntil(
    caches
      /* 
Ta metoda zwraca obietnicę, która rozwiąże "array"" dostępnych
         kluczy pamięci podręcznej
      */
      .keys()
      .then(function (keys) {
        // Zwracamy "promise", która "settle"  się po usunięciu wszystkich nieaktualnych pamięci podręcznych. 
        return Promise.all(
          keys
            .filter(function (key) {
              //Filtruj według kluczy, które nie rozpoczynają się od prefiksu najnowszej wersji.
              return !key.startsWith(version);
            })
            .map(function (key) {
              /* Zwróc "promise" która zostala spelniona po tym jak przestarzaly cache zostal zwrocony.
              */
              return caches.delete(key);
            })
        );
      })
      .then(function() {
        console.log('WORKER: activate completed.');
      })
  );
});

</code></pre><p>Więcej informacji na temat serviceworker.js:</p><p><a href="https://developers.google.com/web/fundamentals/codelabs/">https://developers.google.com/web/fundamentals/codelabs/</a></p><p><a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API">https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API</a></p>]]></content:encoded></item><item><title><![CDATA[Gatsby js]]></title><description><![CDATA[Generator stron statycznych Gatsby.js. Gatsby.js to framework webowy, zbudowany o bibliotekę React.js oraz GraphQL, ...]]></description><link>https://blog.spaceout.pl/gatsby-js/</link><guid isPermaLink="false">5e7f498a028743ff49f7ba92</guid><category><![CDATA[Gatsby.js]]></category><category><![CDATA[node.js]]></category><category><![CDATA[node_modules]]></category><category><![CDATA[graphql]]></category><category><![CDATA[blogowanie]]></category><category><![CDATA[proggressive website app]]></category><dc:creator><![CDATA[Spaceghost]]></dc:creator><pubDate>Sat, 21 Mar 2020 15:19:36 GMT</pubDate><media:content url="https://blog.spaceout.pl/content/images/2020/03/gatsbyjscover.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.spaceout.pl/content/images/2020/03/gatsbyjscover.png" alt="Gatsby js"><p>Jeżeli do waszych Reactowych aplikacji podłączaliście niezliczone dodatkowe moduły takie jak serwery (express, koa), klientów lub serwery apollo, konfiguracje webpacka, pisaliście funkcje SSR (sever side render), oraz łączyliście to w całość, to na pewno zdajecie sobie sprawę z czasochłonności całego tego procesu. Gatsby.js może okazać się rozwiązaniem na te wszystkie problemy.</p><h3 id="development">Development</h3><p></p><p>Gatbsy.js to głównie React, Webpack i GraphQL, jeżeli znacie ten stack to właściwe cały system stoi przed was otworem, z automatu mamy dostęp do pisania (develop) w trybie Hot Module Reloading ( ten tryb jednak wymaga czasami restartu) i budowy plików statycznych. Piszemy w react'cie normlanie, dostraczamy dane lub treść za pomocą GraphQL, webpack nam to wszytsko \"bundeluje\" do kupy i tak w ten sposób mam prawie gotowy produkt.</p><p>Gatsby zdobył już ogromną popularność i posiada wiele gotowych rozwiązań, ekosystem pluginów jest naprawdę duży. SASS, LESS, CSS Inline, PWA - Offline,Css modules, transformer-remark, gatsby sharp image, tego wszystkiego jest naprawdę dużo. Oficjalna lista pluginów na <a href="https://www.gatsbyjs.org/plugins/">https://www.gatsbyjs.org/plugins/</a>.</p><p>To właśnie ten ekosystem gotowych rozwiązań skusił mnie najbardziej do zastosowania gatsby.js w komercyjnych projektach. Dość szybka implementacja wszystkich niezbędnych funkcji aplikacj React, zautomatyzowaniu procesu podłączenia (service.worker.js) Proggressive Web App, super szybkich przejść pomiędzy stronami (pre-fetch, za pomocą \"native\" gatsby-router-link) oraz wielu innym gotowym rozwiązaniom sprawił, że zakochałem się w tym systemie tworzenia stron internetowych. Jest on kompilacją wszystkich moich ulubionych narzędzi, jakich używałam wcześniej, ale teraz nie muszę się nimi opiekować i aktualizować na bieżąco.\</p><p>Muszę też przyznać, że dokumentacja techniczna jest dość dobrze i przejrzyście zorganizowana. I wszystko dział, jak trzeba. Nie doświadczyłem większych problemów przy tworzeniu aplikacji webowych w ten sposób. Z szybkich rad mogę tylko zwrócić uwagę na to, że przy stosowaniu css modules, pliki muszą mieć końcówke cośtam.modules.css (lub .scss). W wersji developerskiej plik bez koncówki \"modules\" działa zaś przy wersji produkcyjnej nie. Spędziłem trochę czasu zanim wychwyciłem o co chodzi.</p><p>Gatsby produkuje pliki statyczne, ale czy to znaczy, że możemy je wcisnąć na każdy serwer hostingowy, jaki jest dostępny w Polsce ? Polecałbym zastosowanie serwera z silnikiem node.js. Jednakże wszytsko także zależy od pluginów i naszej strony. Może okazać się, że zwykła strona na gatsby, pojdzie na każdy serwerze.\n\nSam stawiając stronę wybrałem operatora https://netlify.com. Możemy na nim postawić \"mniejszą\" stronę za darmo (do 100 000 wejśc w mieśiącu) wraz z certyfikatem SSL( za darmo Let's Encrypt), oraz możliwą integracją z ich dość prostym system CMS, Netlify CMS. To dość prosty panel do obsługi treści, będzię wymagał od nas konfiguracji, zrobienia podglądu wpisów. Działa on zasadzie edycji projektu przez wersji GIT, a dokładnie na edycji plików markdown, które są jednym ze sposobów dostarczania treści w frameworku Gatsby.</p><p>Jednakże, dlatego że GraphQL jest głównym silnikiem treści w Gatsby.js, mamy dowolność w podłączaniu jakichkolwiek danych, jakie będą nam potrzebne, z automatu mamy dostęp do pluginów, które pomagają połączyć się z Wordpressem, Drupal, GraphCMS, itd.</p><h3 id="beyond-static">Beyond Static</h3><p>Warto zauważyć, że pomimo tego, iż jest to generator stron statycznych, nasza aplikacja nie musi być statyczna, co często chyba się zdarzać mysleć deweloperom.\nCiągle możemy zstosować gatsby.js do sklepów, czatów ... i bardziej dynamicznych aplikacji. Ciągle mamy dostęp do wszystkich component life cycles w React. Musimy wtedy dostarczyć baze pod aplikacje, a resztę doładujemy w Component Did Mount na bieżąco. Jednakże ze względu na SEO, musimy pamiętać że ta dynamiczna treśc nie będzie czytna przez roboty i crawlery.</p><p>Produkt końcowy i szybkość\nGatsby.js urzeka szczególnie swoją prostotą obsługi oraz tym, że za pomocą dużego systemu pluginów skraca pracę deweloperom. Może się okazać bardzo cennym narzędziem nawet przy budowie dużych aplikacji webowych.\n\nGatsby.js chwali się swoją zawrotną szybkością i jest ona rzeczywiście odczuwalna, szczególnie przy ładowaniu czy nawigowaniu stron aplikacji. Nie znaczy to jednak, że z automatu osiągniemy wynik 100 / 100 w Google Page Speed Insights. Nad tym wynikiem będziemy musieli sami pracować, używając własnych narzędzi lub niektórych z pluginów gatsby (Uncss, Css-inline, Gatsby-Image). </p><p>Jeżeli lubicie pracować z React.js, a chcielibyście sobie skrócić czas robienia aplikacji webowych to gorąco polecam gatsby.js. Na moim koncie w github, znajdziecie parę projektów zbudowanych o gatsby.js wraz z mini starterem gatsby.js z trochę większa ilością pluginów niż tzw golas.<br></p>]]></content:encoded></item><item><title><![CDATA[Komendy Docker CLI]]></title><description><![CDATA[Lista najczęściej używanych komend Docker. Bez zbędnej gadki ... ]]></description><link>https://blog.spaceout.pl/komendy-docker-cli/</link><guid isPermaLink="false">5e7f498a028743ff49f7ba7b</guid><category><![CDATA[docker]]></category><category><![CDATA[docker-compose]]></category><category><![CDATA[cli]]></category><dc:creator><![CDATA[Spaceghost]]></dc:creator><pubDate>Sun, 26 Jan 2020 21:15:29 GMT</pubDate><media:content url="https://blog.spaceout.pl/content/images/2020/03/dockercli.jpg" medium="image"/><content:encoded><![CDATA[<h2 id="zarz-dzanie-obrazami">Zarządzanie obrazami</h2><img src="https://blog.spaceout.pl/content/images/2020/03/dockercli.jpg" alt="Komendy Docker CLI"><p><br><code>docker build</code></p><pre><code>docker build [options] .
  -t "app/container_name"    # name
</code></pre><p>Stwórz <code>image</code> z pliku Dockerfile.</p><h3 id="docker-run"><code>docker run</code></h3><pre><code>docker run [options] IMAGE
  # see `docker create` for options
</code></pre><p>Zarządzanie konetnerami</p><h3 id="docker-create"><code>docker create</code></h3><pre><code>docker create [options] IMAGE
  -a, --attach               # attach stdout/err
  -i, --interactive          # attach stdin (interactive)
  -t, --tty                  # pseudo-tty
      --name NAME            # name your image
  -p, --publish 5000:5000    # port map
      --expose 5432          # expose a port to linked containers
  -P, --publish-all          # publish all ports
      --link container:alias # linking
  -v, --volume `pwd`:/app    # mount (absolute paths needed)
  -e, --env NAME=hello       # env vars
</code></pre><h4 id="przyk-ad">Przykład</h4><p>Stwórz <code>container</code> z <code>image</code>.</p><pre><code>$ docker create --name app_redis_1 \
  --expose 6379 \
  redis:3.0.2
</code></pre><p><code>docker exec</code></p><pre><code>docker exec [options] CONTAINER COMMAND
  -d, --detach        # run in background
  -i, --interactive   # stdin
  -t, --tty           # interactive
</code></pre><h4 id="przyk-ad-1">Przykład</h4><p>Komendy w <code>container</code>.</p><pre><code>$ docker exec app_web_1 tail logs/development.log
$ docker exec -t -i app_web_1 rails c
</code></pre><p></p><p>Start/stop a <code>container</code>.</p><p><code>docker start</code></p><pre><code>docker start [options] CONTAINER
  -a, --attach        # attach stdout/err
  -i, --interactive   # attach stdin

docker stop [options] CONTAINER
</code></pre><p>Zarządzanie <code>container</code> przy pomocy ps/kill.</p><h3 id="docker-ps"><code>docker ps</code></h3><pre><code>$ docker ps
$ docker ps -a
$ docker kill $ID
</code></pre><p>Obrazy</p><p>Zarządzanie <code>image</code></p><h3 id="docker-images"><code>docker images</code></h3><pre><code>$ docker images
  REPOSITORY   TAG        ID
  ubuntu       12.10      b750fe78269d
  me/myapp     latest     7b2431a8d968
</code></pre><pre><code>$ docker images -a   # also show intermediate
</code></pre><p>Kasowanie <code>image</code></p><h3 id="docker-rmi"><code>docker rmi</code></h3><pre><code>docker rmi b750fe78269d
</code></pre><p></p><h2 id="zobacz-tak-e">Zobacz także</h2><ul><li><a href="http://www.docker.io/gettingstarted/">Getting Started</a> <em>(docker.io)</em></li></ul><h1 id="dockerfile">Dockerfile</h1><h3 id="inheritance">Inheritance</h3><pre><code>FROM ruby:2.2.2
</code></pre><h3 id="variables">Variables</h3><pre><code>ENV APP_HOME /myapp
RUN mkdir $APP_HOME
</code></pre><h3 id="initialization">Initialization</h3><pre><code>RUN bundle install
</code></pre><pre><code>WORKDIR /myapp
</code></pre><pre><code>VOLUME ["/data"]
# Specification for mount point
</code></pre><pre><code>ADD file.xyz /file.xyz
COPY --chown=user:group host_file.xyz /path/container_file.xyz
</code></pre><h3 id="onbuild">Onbuild</h3><pre><code>ONBUILD RUN bundle install
# when used with another file
</code></pre><h3 id="commands">Commands</h3><pre><code>EXPOSE 5900
CMD    ["bundle", "exec", "rails", "server"]
</code></pre><h3 id="entrypoint">Entrypoint</h3><pre><code>ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
</code></pre><p>Konfiguruje kontener, który będzie działał jako plik wykonywalny.</p><pre><code>ENTRYPOINT exec top -b
</code></pre><p><br>Spowoduje to użycie przetwarzania powłoki do podstawienia zmiennych powłoki i zignoruje wszelkie argumenty wiersza poleceń uruchamiane przez<code>CMD</code> lub <code>docker run</code></p><p>Metadata</p><pre><code>LABEL version="1.0"
</code></pre><pre><code>LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
</code></pre><pre><code>LABEL description="This text illustrates \
that label-values can span multiple lines."
</code></pre><h2 id="zobacz-tak-e-1">Zobacz także</h2><ul><li><a href="https://docs.docker.com/engine/reference/builder/">https://docs.docker.com/engine/reference/builder/</a></li></ul><h1 id="docker-compose">docker-compose</h1><h3 id="podstawowy-przyk-ad">Podstawowy przykład</h3><pre><code># docker-compose.yml
version: '2'

services:
  web:
    build: .
    # build from Dockerfile
    context: ./Path
    dockerfile: Dockerfile
    ports:
     - "5000:5000"
    volumes:
     - .:/code
  redis:
    image: redis
</code></pre><h3 id="komendy">Komendy</h3><pre><code>docker-compose start
docker-compose stop
</code></pre><pre><code>docker-compose pause
docker-compose unpause
</code></pre><pre><code>docker-compose ps
docker-compose up
docker-compose down
</code></pre><h2 id="referencje">Referencje</h2><h3 id="budowa">Budowa</h3><pre><code>web:
  # build from Dockerfile
  build: .
</code></pre><pre><code>  # build from custom Dockerfile
  build:
    context: ./dir
    dockerfile: Dockerfile.dev
</code></pre><pre><code>  # build from image
  image: ubuntu
  image: ubuntu:14.04
  image: tutum/influxdb
  image: example-registry:4000/postgresql
  image: a4bc65fd
</code></pre><h3 id="porty">Porty</h3><pre><code>  ports:
    - "3000"
    - "8000:80"  # guest:host
</code></pre><pre><code>  # expose ports to linked services (not to host)
  expose: ["3000"]
</code></pre><h3 id="komeny">Komeny</h3><pre><code>  # command to execute
  command: bundle exec thin -p 3000
  command: [bundle, exec, thin, -p, 3000]
</code></pre><pre><code>  # override the entrypoint
  entrypoint: /app/start.sh
  entrypoint: [php, -d, vendor/bin/phpunit]
</code></pre><h3 id="zmienne-rodowiskowe">Zmienne środowiskowe</h3><pre><code>  # environment vars
  environment:
    RACK_ENV: development
  environment:
    - RACK_ENV=development
</code></pre><pre><code>  # environment vars from file
  env_file: .env
  env_file: [.env, .development.env]
</code></pre><h3 id="zale-no-ci-dependencies"><br>Zależności / Dependencies</h3><pre><code>  # makes the `db` service available as the hostname `database`
  # (implies depends_on)
  links:
    - db:database
    - redis
</code></pre><pre><code>  # make sure `db` is alive before starting
  depends_on:
    - db
</code></pre><h3 id="inne-opcje">Inne opcje</h3><pre><code>  # make this service extend another
  extends:
    file: common.yml  # optional
    service: webapp
</code></pre><pre><code>  volumes:
    - /var/lib/mysql
    - ./_data:/var/lib/mysql
</code></pre><h2 id="opcje-zawansowane">Opcje zawansowane </h2><h3 id="labels">Labels</h3><pre><code>services:
  web:
    labels:
      com.example.description: "Accounting web app"
</code></pre><h3 id="dns-servers">DNS servers</h3><pre><code>services:
  web:
    dns: 8.8.8.8
    dns:
      - 8.8.8.8
      - 8.8.4.4
</code></pre><h3 id="devices">Devices</h3><pre><code>services:
  web:
    devices:
    - "/dev/ttyUSB0:/dev/ttyUSB0"
</code></pre><h3 id="external-links">External links</h3><pre><code>services:
  web:
    external_links:
      - redis_1
      - project_db_1:mysql
</code></pre><h3 id="hosts">Hosts</h3><pre><code>services:
  web:
    extra_hosts:
      - "somehost:192.168.1.100"
</code></pre><h3 id="serwisy">Serwisy</h3><p>Sprawdź wszytskie serwisy</p><pre><code>docker service ls 

</code></pre><p>Aby zobaczyć wszystkie uruchomione usługi wraz z zaawansowanymi funkcjami</p><pre><code>docker stack services stack_name
</code></pre><p>wszytskie logi</p><pre><code>docker service logs stack_name service_name 
</code></pre><p>Aby szybko skalować usługi w kwalifikowanym węźle</p><pre><code>docker service scale stack_name_service_name=replicas
</code></pre><h3 id="clean-up">clean up</h3><p>Skasuj nie używane obrazy</p><pre><code>docker image prune 
</code></pre><p>Skasuj wszystkie obrazy, które nie są używane w kontenerach</p><pre><code>docker image prune -a 
</code></pre><p>Wyczyść system </p><pre><code>docker system prune 
</code></pre><p>Wyjdz z ze swarm'a</p><pre><code>docker swarm leave  
</code></pre><p>Usuń cały swarm wraz z całymi wolumenami i bazami danych</p><pre><code>docker stack rm stack_name  
</code></pre><p>Zniszcz (kill) wszystkie kontenery </p><pre><code>docker kill $(docekr ps -q ) </code></pre>]]></content:encoded></item><item><title><![CDATA[Słuchawki bluetooth i centos 8]]></title><description><![CDATA[Jeżeli używacie centos 8 i macie problem z podłączeniem swoich słuchwek bluetooth, poniższa konfiguracja powinna działać na każdym systemie linuks, który posiada gnome-bluetooth ]]></description><link>https://blog.spaceout.pl/bluetoothsluchawkicentos8/</link><guid isPermaLink="false">5e7f498a028743ff49f7ba90</guid><category><![CDATA[centos8]]></category><category><![CDATA[centos7]]></category><category><![CDATA[gnome]]></category><category><![CDATA[Linux]]></category><category><![CDATA[bluetooth]]></category><dc:creator><![CDATA[Spaceghost]]></dc:creator><pubDate>Sun, 26 Jan 2020 20:57:13 GMT</pubDate><media:content url="https://blog.spaceout.pl/content/images/2020/03/bluetooth.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://blog.spaceout.pl/content/images/2020/03/bluetooth.jpg" alt="Słuchawki bluetooth i centos 8"><p>Jeżeli używacie centos 8 i macie problem z podłączeniem swoich słuchwek bluetooth, poniższa konfiguracja powinna działać na każdym systemie linuks, który posiada gnome-bluetooth </p><pre><code>sudo nano /etc/bluetooth/audio.conf
</code></pre><p>oraz dodać poniższy config </p><pre><code>[General]
Disable=Socket
Disable=Headset
Enable=Media,Source,Sink,Gateway
AutoConnect=true
load-module module-switch-on-connect
</code></pre><p>Następnie zedytować  <code>/etc/bluetooth/main.conf</code> na lini </p><pre><code># Restricts all controllers to the specified transport. Default value
# is "dual", i.e. both BR/EDR and LE enabled (when supported by the HW).
# Possible values: "dual", "bredr", "le"
ControllerMode = bredr
</code></pre><p>Aby właczyć auto łączenie systemu zedytuj linie </p><pre><code># AutoEnable defines option to enable all controllers when they are found. 
# This includes adapters present on start as well as adapters that are plugged 
# in later on. Defaults to 'false'. 
AutoEnable=true
</code></pre><p>Teraz reboot systemu i połaczyć się po raz pierwszy ze słuchawkami </p>]]></content:encoded></item><item><title><![CDATA[Sharp Machine: Czyli jak zrobić własne narzędzie CLI z Inquirer.js]]></title><description><![CDATA[Jak szybko stworzyć własne CLI, które przyda nam się przy naszych codziennych zadaniach ? Odpowiedź to inquire.js i dobry pomysł na nasze CLI. ]]></description><link>https://blog.spaceout.pl/sharp-machine-czyli-jak-zrobic-wlasne-cli/</link><guid isPermaLink="false">5e7f498a028743ff49f7ba8f</guid><category><![CDATA[node.js]]></category><category><![CDATA[cli]]></category><category><![CDATA[Sharp]]></category><category><![CDATA[automatyzacja pracy]]></category><category><![CDATA[javascript]]></category><category><![CDATA[node_modules]]></category><category><![CDATA[Optymalizacja]]></category><category><![CDATA[Produktywność]]></category><dc:creator><![CDATA[Spaceghost]]></dc:creator><pubDate>Sun, 24 Nov 2019 15:09:32 GMT</pubDate><media:content url="https://blog.spaceout.pl/content/images/2020/06/sharpMachine-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.spaceout.pl/content/images/2020/06/sharpMachine-1.png" alt="Sharp Machine: Czyli jak zrobić własne narzędzie CLI z Inquirer.js"><p>Jak szybko stworzyć własne CLI, które przyda nam się przy naszych codziennych zadaniach ? Odpowiedź to inquire.js (i dobry pomysł na nasze CLI). </p><p>W większości nowych instalacjach np. <a href="https://blog.spaceout.pl/gatsby-js/">Gatsby.js</a> czy <a href="https://blog.spaceout.pl/ghostv2/">Ghost.js,</a>  mamy już gotowe implementacje modułu optymalizacji zdjęć i nie musimy się tym przejmować po za początkową konfiguracją. Jednakże moje starsze instalacje albo wordpressy nie mają tego szczęścia. </p><p>Mój problem był dość prosty, od czasu do czasu potrzebowałem narzędzia, które uruchomię na dowolnym folderze, które pozwoliło by mi szybko, bez bólu i bez pamiętania konfiguracji, komend, itp. przyciąć, zoptymalizować lub zmienić format zdjęć, które znajdują się wybranym folderze. </p><p>Szukając gotowych rozwiązań, upewniłem się tylko w przekonaniu, że nie ma nic na internecie co by sprostało moim wymaganiom, szczególnie jeżeli chodzi możliwość optymalizacji całego folderu i swego rodzaju UX całej operacji. Większość tools'ów wymaga dodatkowych argumentów, opcji do wpisania wraz z komendą, co powoduję, że za każdym razem muszę przeglądać dokumentacje w poszukiwaniu właściwej konfiguracji. </p><p>Tak zrodził się pomysł na mały program, który nazwałem Sharp Machine. Zdecydowałem się na <a href="https://github.com/lovell/sharp">lovell/sharp</a>: </p><blockquote>"High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP and TIFF images. Uses the libvips library."</blockquote><p>ze względu na jego szybkość i znajomość biblioteki (<a href="https://blog.spaceout.pl/gatsby-js/">Gatsby.js </a>korzysta z sharpa'a). </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.spaceout.pl/content/images/2020/06/sharpMachine.png" class="kg-image" alt="Sharp Machine: Czyli jak zrobić własne narzędzie CLI z Inquirer.js"><figcaption>Sharp machine, <a href="https://github.com/MassivDash/SharpMachine">https://github.com/MassivDash/SharpMachine</a></figcaption></figure><h3 id="budowa-w-asnego-cli">Budowa własnego CLI</h3><p>Budowa własnego CLI, okazała się dobra zabawą dzięki gotowym rozwiązaniom dostępnym w internecie. Szczególnie, mogę pochwalić bibliotekę I<a href="https://github.com/SBoudrias/Inquirer.js/">nquirer.js</a>, która czyni tworzenie interaktywnych pytań i uzyskiwanie odpowiedzi od użytkownika dość trywialnym procederem. </p><p>index.js</p><pre><code>const inquirer  = require('./libs/inquirer');

const run = async () =&gt; {
 const location = await inquirer.askInputQuestions(); 
};

run(); </code></pre><p>inquirer.js</p><pre><code>const inquirer = require('inquirer');

module.exports = {
  askInputQuestions: () =&gt; {
    const questions = [
      {
        name: 'inputDir',
        type: 'input',
        message: 'Enter input directory (type . for current folder): ',
        validate: function( value ) {
          if (value.length) {
            return true;
          } else {
            return 'Gotta type in something';
          }
        }
      },
      {
        name: 'outputDir',
        type: 'input',
        message: 'Enter output directory :',
        validate: function(value) {
          if (value.length) {
            return true;
          } else {
            return 'Please Enter output directory';
          }
        }
      }
    ];
    return inquirer.prompt(questions);
  },
};</code></pre><p>Po uruchomieniu programu i odpowiedzeniu na przygotowane pytania. W naszej zmiennej location przechowywane są odpowiedzi użytkownika. Na ich podstawie zadajemy kolejne pytania lub uruchamiamy odpowiednie procesy. W moim przypadku jest to sprawdzenie podanego folderu pod kątem obecności zdjęć oraz dalsze operacje i pytania o zadania dla modułu sharp. Inquirer.js posiada w swoim api, pytania; input, list, checkbox, expand, ... oraz editor. Ta ostatnia opcja okazała się doskonałym rozwiązaniem dla stworzenia custom configu do Sharp Machine. Ten typ pytania powoduje otwarcie ulubionego edytora tekstu oraz możliwość edycji pełnego obiektu konfiguracyjnego, które sprawia, że łatwo dostosować sharp machine do swoich potrzeb. </p><p>Do dalszych prac na interfejsem swojego CLI wykorzystałem:  </p><ul><li><a href="https://github.com/chalk/chalk">Chalk.js</a>: daje możliwość ostylowania naszych wiadomości pokazywanych w konsoli. </li><li><a href="https://github.com/scottgonzalez/figlet-js">Figlet.js</a>: daje możliwość zrobienia consolowego splash screena / tytułu naszego programu CLI </li><li><a href="https://github.com/nathanpeck/clui">Clui.js</a>: daje możliwość dołączenia spinnera, progress bar'a  podczas operacji CLI</li></ul><p>Sharp Machine został przemyślany jako moduł  do pracy globalnej, aby upewnić się, że nasz moduł będzie odpowiednio działać, warto pamiętać aby dodać do index.js (na samej górze pliku)</p><pre><code>#!/usr/bin/env node</code></pre><p> oraz do pliku package.json </p><pre><code>  "bin": {
    "nazwa_naszego_pakietu": "./index.js"
  }</code></pre><p>Tworzenie własnego CLI to dobre ćwiczenie do pracy z czystym node.js oraz asynchronicznymi działaniami. Polecam dla każdego kto uwielbia zabawy i pracę z node konsolą.    </p><p>Pełne źródło<a href="https://github.com/MassivDash/SharpMachine"> SharpMachine na githubie</a> lub do przetestowania samemu </p><pre><code>npm i -g sharpmachine
sharpmachine
</code></pre><p>Pozdrawiam </p><p></p>]]></content:encoded></item><item><title><![CDATA[Co to Svelte.js ? 
Cybernetyczne appki webowe ?(Cybernetically enhanced web apps)]]></title><description><![CDATA[Do grona najlepszych ma zamiar dołączyć Svelte.js jednak w przeciwieństwie do Reacta, svelte.js nie używa techniki podmiany prawdziwego DOM z tym wirtualnym a metody kompilacji możliwych zmian w aplikacji o wstrzykiwaniu go bezpośrednio do kodu strony podczas budowy aplikacji.]]></description><link>https://blog.spaceout.pl/sveltecybernetically-enhanced-web-apps/</link><guid isPermaLink="false">5e7f498a028743ff49f7ba8d</guid><category><![CDATA[svelte.js]]></category><category><![CDATA[JS]]></category><category><![CDATA[react]]></category><category><![CDATA[vue]]></category><dc:creator><![CDATA[Spaceghost]]></dc:creator><pubDate>Sat, 02 Nov 2019 21:33:37 GMT</pubDate><media:content url="https://blog.spaceout.pl/content/images/2020/03/1_OJLglSTFZ1PbwpRG0U2xXA.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.spaceout.pl/content/images/2020/03/1_OJLglSTFZ1PbwpRG0U2xXA.png" alt="Co to Svelte.js ? 
Cybernetyczne appki webowe ?(Cybernetically enhanced web apps)"><p>Krąży wiele żartów po sieci, że prawie codziennie powstaje nowy framework JS. Mamy już święta trójce współczesnego frontendu;  Reacta, Angular i Vue oraz wiele wiele innych. </p><p>Do grona najlepszych ma zamiar dołączyć Svelte.js jednak w przeciwieństwie do Reacta, svelte.js nie używa techniki podmiany prawdziwego DOM z tym wirtualnym a metody kompilacji możliwych zmian w aplikacji o wstrzykiwaniu go bezpośrednio do kodu strony podczas budowy aplikacji.</p><p>Twórcy svelte.js przekonują, że używanie metody wirtualnego DOMu jest nie efektywne oraz wręcz nie potrzebne.</p><h3 id="wi-c-czy-wirtualny-dom-jest-wolny">Więc ... czy wirtualny DOM jest wolny?</h3><p><br>„Wirtualny DOM jest zwykle wystarczająco szybki”, ale z pewnymi zastrzeżeniami.</p><p>Tradycyjne frameworki umożliwiają pisanie deklaratywnego kodu sterowanego stanem, ale istnieje kara: przeglądarka musi wykonać dodatkową pracę, aby przekonwertować te deklaratywne struktury na operacje DOM, wykorzystując tzw Virtual DOM</p><p>Oryginalną obietnicą React'a było to, że mogłeś ponownie wy-renderować całą aplikację przy każdej zmianie stanu bez obawy o wydajność. Gdyby tak jednak było, nie byłoby potrzeby takich optymalizacji, jak shouldComponentUpdate albo pureComponent. Nawet w przypadku shouldComponentUpdate aktualizowanie wirtualnego DOM całej aplikacji za jednym razem to dużo pracy. Jakiś czas temu zespół React'owy wprowadził React Fibre, które pozwala podzielić aktualizację na mniejsze części. Oznacza to (między innymi), że aktualizacje nie blokują głównego wątku (main thread) przez długi czas, chociaż nie zmniejsza to całkowitej ilości pracy ani czasu potrzebnego na aktualizację prawdziwego DOMu</p><p>Zamiast tego Svelte działa podczas kompilacji, przekształcając komponenty w wysoce wydajny kod imperatywny, który chirurgicznie aktualizuje DOM. W rezultacie możesz pisać ambitne aplikacje o doskonałych parametrach wydajnościowych.</p><h3 id="cybernetyczne-appki-webowe">Cybernetyczne appki webowe ?</h3><p>Svelte.js używa własnego typu plików ".svelte", który przyjmuje 3 bloki kodu (style, code, html markdown, przykład poniżej). Svetle w swej ideologii chcę aby programista pisał jak najmniej kodu, gdyż to zwiększa jego czytelność, nadzór i późniejsze rewizję, zamieszczam poniżej ten sam komponent w React'cie, Vue oraz Svelte.</p><h3 id="svetle">Svetle</h3><!--kg-card-begin: markdown--><pre><code>&lt;style&gt;
  p {
  color: red;
  }
&lt;/style&gt;
&lt;script&gt;
	let a = 1;
	let b = 2;
&lt;/script&gt;

&lt;input type=&quot;number&quot; bind:value={a}&gt;
&lt;input type=&quot;number&quot; bind:value={b}&gt;

&lt;p&gt;{a} + {b} = {a + b}&lt;/p&gt;
</code></pre>
<!--kg-card-end: markdown--><h3 id="react">React</h3><!--kg-card-begin: markdown--><pre><code>export default () =&gt; {
  const [a, setA] = useState(1);
  const [b, setB] = useState(2);

  function handleChangeA(event) {
    setA(+event.target.value);
  }

  function handleChangeB(event) {
    setB(+event.target.value);
  }

  return (
    &lt;div&gt;
      &lt;input type=&quot;number&quot; value={a} onChange={handleChangeA}/&gt;
      &lt;input type=&quot;number&quot; value={b} onChange={handleChangeB}/&gt;

      &lt;p&gt;{a} + {b} = {a + b}&lt;/p&gt;
    &lt;/div&gt;
  );
};

</code></pre>
<!--kg-card-end: markdown--><h3 id="vue"> Vue</h3><!--kg-card-begin: markdown--><pre><code>&lt;template&gt;
  &lt;div&gt;
    &lt;input type=&quot;number&quot; v-model.number=&quot;a&quot;&gt;
    &lt;input type=&quot;number&quot; v-model.number=&quot;b&quot;&gt;

    &lt;p&gt;{{a}} + {{b}} = {{a + b}}&lt;/p&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
  export default {
    data: function() {
      return {
        a: 1,
        b: 2
      };
    }
  };
&lt;/script&gt;
</code></pre>
<!--kg-card-end: markdown--><p>Jak widać kod "Reactowy" jest prawie 3 dłuższy. Dodatkowo według oficjalnej dokumentacji svelte, możemy zapomnieć o manualnej optymalizacji komponentów za pomocą takich funckji jak useMemo, useEffect, useCallback. Svelte ma wbudowane wszystkie rozwiązania w swój compiler.  </p><p>Svelte jako compiler , który następnie pakuje swoje pliki do czystego vanilla JS, html i css, ma dość bogate wbudowane API, od bindingów danych, animacje i przejścia między komponentami, moduły odpowiadające głównym reactowym bibliotekom takim jak wbudowany store (reactowy redux lub context api jak kto woli), head (react helmet) oraz wiele innych. Sprawdź więcej na <a href="https://svelte.dev/docs">oficjalnej dokumentacji svelte w języku angielskim </a>.</p><h3 id="podsumowanie">Podsumowanie </h3><p>Svelte obecnie (01.11.2019) jest w swojej wersji 3.0, ale wydaje mi się, że jeszcze przed nim długa droga rozwijania samego "compilera", społeczności oraz koncepcji nie używania wirtualnego DOM'u. W testach prezentowanych przez jednego z twórcą Rich Harris, svelte pokonuje wszystkie dostępne frameworki JS zarówno pod względem rozmiaru paczki jak i samej szybkości działania aplikacji , co może się okazać kluczową sprawą podczas budowania i projektowania aplikacji na urządzenia IoT (internet of things). Na teraz nadaję się raczej do budowania prostych aplikacji i stron statycznych, niż pełno flagowych aplikacji webowych. </p>]]></content:encoded></item><item><title><![CDATA[Ściśle mówiąc]]></title><description><![CDATA[Czym jest tryb "use strict" ? W 2009 roku wraz z wydaniem ES5 powstał tryb ścisły, ponad 10 lat później, opcjonalność trybu ścisłego oznacza, że ​​nadal niekoniecznie jest on domyślny dla programistów JS.]]></description><link>https://blog.spaceout.pl/scislie/</link><guid isPermaLink="false">5e7f498a028743ff49f7ba8e</guid><category><![CDATA[javascript]]></category><category><![CDATA[JS]]></category><dc:creator><![CDATA[Spaceghost]]></dc:creator><pubDate>Sat, 02 Nov 2019 19:51:40 GMT</pubDate><media:content url="https://blog.spaceout.pl/content/images/2020/03/niketh-vellanki-QkSN_8XcXwQ-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://blog.spaceout.pl/content/images/2020/03/niketh-vellanki-QkSN_8XcXwQ-unsplash.jpg" alt="Ściśle mówiąc"><p>W 2009 roku wraz z wydaniem ES5, JS dodał tryb ścisły jako mechanizm opt-in do zachęcania programistów do pisania lepszych programów JS.</p><p>Korzyści z trybu ścisłego znacznie przewyższają koszty, ale stare nawyki umierają ciężko, a "naprawa" istniejących („legacy) baz kodu jest naprawdę trudna. Niestety, ponad 10 lat później, opcjonalność trybu ścisłego oznacza, że ​​nadal niekoniecznie jest on domyślny dla programistów JS.</p><p>Dlaczego tryb ścisły? Tryb ścisły nie powinien być traktowany jako ograniczenie tego, czego nie możesz zrobić, ale raczej jako przewodnik po najlepszym sposobie robienia rzeczy, aby silnik JS miał najlepszą szansę na optymalizację i wydajne działanie kodu.</p><p>Większość elementów sterujących w trybie ścisłym ma postać wczesnych błędów, co oznacza błędy, które nie są błędami ściśle składniowymi, ale wciąż są zgłaszane w czasie kompilacji (przed uruchomieniem kodu). Na przykład tryb ścisły uniemożliwia nazywanie dwóch parametrów funkcji tak samo i powoduje błąd. Niektóre inne kontrolki trybu ścisłego są obserwowalne tylko w czasie wykonywania, na przykład domyślna wartość słowa "this" jako niezdefiniowana (undefinded).</p><p>Zamiast walczyć i kłócić się w trybie ścisłym, jak dziecko, które chce po prostu przeciwstawić się temu, co mówią im rodzice, najlepszym sposobem myślenia o trybie "ścisłym" jest to, że jest on jak liniowiec przypominający, jak JS powinien być napisany, aby mieć najwyższą jakość oraz najlepszą szansę na wydajność. Jeśli czujesz się zakuty w kajdanki, próbując obejść tryb ścisły, powinna to być czerwona flaga ostrzegawcza, którą sygnalizuje, że musisz przemyśleć całe podejście.</p><p>Tryb ścisły jest włączony dla każdego programu (dla pliku!) W następujący sposób:</p><!--kg-card-begin: markdown--><pre><code>// only whitespace and comments are allowed
// before the use-strict pragma

&quot;use strict&quot;;

// everything in this file runs in strict
// mode
</code></pre>
<!--kg-card-end: markdown--><p>W górnej części pliku musi pojawić się pragma trybu ścisłego, z dozwolonymi tylko białymi spacjami lub komentarzami.</p><p>Niewielką sprawą, o której trzeba pamiętać, jest, że nawet zabłąkany ";" uczyni pragmię bezużyteczną; nie są zgłaszane żadne błędy, ponieważ poprawne JS ma wyrażenie dosłowne w pozycji instrukcji, ale po cichu nie włączy trybu ścisłego!</p><p>Tryb ścisły można alternatywnie włączyć w zależności od zakresu (scope) funkcji, z dokładnie tymi samymi regułami / upomnieniami dotyczącymi jego pozycjonowania):</p><!--kg-card-begin: markdown--><pre><code>function someOperations() {
    // whitespace and comments are fine here
    &quot;use strict&quot;;

    // all this code will run in strict mode
}
</code></pre>
<!--kg-card-end: markdown--><p>Co ciekawe, jeśli cały plik ma włączony tryb ścisły, trybu ścisły na poziomie funkcji jest niedozwolony. Więc musisz wybrać jedno lub drugie.</p><p>Jedynym uzasadnionym powodem zastosowania podejścia do trybu ścisłego dla poszczególnych funkcji jest konwertowanie istniejącego programu  i konieczne jest stopniowe wprowadzanie zmian w miarę upływu czasu. W przeciwnym razie znacznie lepiej jest po prostu włączyć tryb ścisły dla całego pliku / programu.</p><p>Wielu zastanawia się, czy JS kiedykolwiek nada trybowi domyślnemu tryb ścisły? Odpowiedź brzmi: prawie na pewno nie. Jak już wcześniej mówilIstnieje jednak kilka czynników, które zmniejszają przyszły wpływ tego niewystarczającego „zaciemnienia” trybu ścisłego.iśmy o kompatybilności wstecznej, jeśli aktualizacja języka JS oznaczyła by, że każdy kod jest trybem ścisłym, wtedy wszystkie kody "legacy" nie przechodziły by nowej walidacji silnika JS. </p><p>Warto zaznaczyć, że praktycznie cały transpilowany kod kończy się w "trybie ścisłym", nawet jeśli oryginalny kod źródłowy nie jest zapisany jako taki. Większość produkowanych kodów JS została przetranspilowana, co oznacza, że ​​większość kodu JS na www, już przestrzega trybu ścisłego. </p><p>Co więcej, zachodzi szeroka zmiana w kierunku pisania nowego kodu JS przy użyciu formatu ES6. Moduły ES6 przyjmują tryb ścisły, więc cały kod w takich plikach jest automatycznie domyślnie ustawiany na ten tryb.</p><p>Tryb ścisły jest w dużej mierze de facto domyślny, chociaż technicznie tak naprawdę nie jest domyślny.</p>]]></content:encoded></item><item><title><![CDATA[SQL vs. NoSQL]]></title><description><![CDATA[Prędzej czy później każdy system, aplikacja czy instalacja webowa potrzebuje zachowywać i pobierać dane, przed projektantem systemowym staje dość trudne i istotne pytanie; Jaki typ bazy danych wybrać SQL czy NoSQL ? ]]></description><link>https://blog.spaceout.pl/sql-vs-nosql/</link><guid isPermaLink="false">5e7f498a028743ff49f7ba8b</guid><category><![CDATA[NoSQL]]></category><category><![CDATA[Bazy Danych]]></category><category><![CDATA[mySQL]]></category><category><![CDATA[SQL]]></category><category><![CDATA[mongoDB]]></category><dc:creator><![CDATA[Spaceghost]]></dc:creator><pubDate>Mon, 23 Sep 2019 16:17:15 GMT</pubDate><media:content url="https://blog.spaceout.pl/content/images/2020/03/nsqlvssq-.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://blog.spaceout.pl/content/images/2020/03/nsqlvssq-.jpg" alt="SQL vs. NoSQL"><p>Czas na kolejną batalie między konkurencyjnymi systemami (<a href="https://blog.spaceout.pl/graphql-vs-rest/">sprawdź także REST vs GraphQL</a>) , tym razem na warsztat idą bazy danych.  Prędzej czy później każdy system, aplikacja czy instalacja webowa potrzebuje zachowywać i pobierać dane, przed projektantem systemowym staje dość trudne i istotne pytanie; Jaki typ bazy danych wybrać SQL czy NoSQL ? </p><p>Warto zaznaczyć, że nie ma tutaj jednej właściwej odpowiedzi, a raczej zestaw czynników, które trzeba wsiąść pod uwagę. </p><p><strong>SQL</strong>   </p><p>Baza danych SQL doskonale nadaje się do systemów zorientowanych na transakcje, takich jak narzędzia do zarządzania relacjami z klientami, oprogramowanie księgowe i platformy handlu elektronicznego. Każdy wiersz w bazie danych SQL jest odrębnym podmiotem (np. Klientem), a każda kolumna jest atrybutem opisującym ten podmiot (np. Adres, stanowisko, zakupiony towar itp.).</p><p>Ze względu na te odrębne, u strukturyzowane relacje między wierszami i kolumnami w tabeli, bazy danych SQL są najlepsze, gdy potrzebujesz zgodności z <a href="https://en.wikipedia.org/wiki/ACID_(computer_science)">ACID compliance</a>:</p><blockquote><strong>Atomowość (Atomicity)</strong> - każda transakcja kończy się powodzeniem lub jest całkowicie wycofywana.</blockquote><blockquote><strong>Spójność </strong>- dane są zapisywane w bazie danych muszą być prawidłowe zgodnie ze wszystkimi zdefiniowanymi regułami.<br></blockquote><blockquote><strong>Izolacja</strong> - gdy transakcje są uruchamiane jednocześnie, nie konkurują ze sobą i działają tak, jakby były uruchamiane sekwencyjnie.</blockquote><blockquote><strong>Trwałość</strong> - po zatwierdzeniu transakcji w bazie danych jest ona uznawana za trwałą, nawet w przypadku awarii systemu.</blockquote><p>Zgodność z ACID chroni integralność danych poprzez dokładne określenie, czym jest transakcja i jak wchodzi ona w interakcję z bazą danych. Pozwala to uniknąć synchronizacji tabel bazy danych, co jest bardzo ważne w przypadku transakcji finansowych. Zgodność z ACID gwarantuje ważność transakcji nawet w obliczu błędów, awarii technologii, katastrofalnych zdarzeń itp.</p><p>Jeśli Twoje dane są bardzo u strukturyzowane, a zgodność z ACID jest koniecznością, SQL jest doskonałym wyborem. Z drugiej strony, jeśli Twoje wymagania dotyczące danych nie są jasne lub jeśli Twoje dane są niestrukturyzowane, NoSQL może być najlepszym rozwiązaniem.</p><p>Dane przechowywane w bazie danych NoSQL nie potrzebują przedefiniowanego schematu, jak w przypadku bazy danych SQL. Dane mogą być raczej składami kolumn, parami zorientowanymi na dokument, opartymi na wykresach lub klucz-wartość. Zapewnia to znacznie większą elastyczność i mniej planowania z góry podczas zarządzania bazą danych.</p><p><strong>Na NoSQL możesz:</strong></p><blockquote>Tworzyć dokumenty bez wcześniejszego dokładnego definiowania ich struktury<br></blockquote><blockquote>Dodawać pola do bazy danych bez zmiany pól istniejących dokumentów<br></blockquote><blockquote>Przechowywać dokumenty, które mają swoją unikalną strukturę<br></blockquote><blockquote>Posiadać wiele baz danych o różnych strukturach i składni</blockquote><p>Baza danych NoSQL najlepiej nadaje się do przechowywania danych, takich jak treść artykułów, posty w mediach społecznościowych, dane z czujników i inne rodzaje danych niestrukturyzowanych, które nie mieszczą się w tabeli. Bazy danych NoSQL zostały zbudowane z myślą o elastyczności i skalowalności i są zgodne z modelem spójności BASE, co oznacza:</p><ul><li><strong>Podstawowa dostępność (Basic Availability)</strong> - oznacza to, że chociaż baza danych gwarantuje dostępność danych, baza danych może nie uzyskać wymaganych danych lub dane mogą być w stanie zmieniającym się lub niespójnym.<br></li><li><strong>Stan miękki (Soft State) -</strong> Stan bazy danych może się zmieniać z czasem.</li><li><strong>Ostateczna spójność (Eventual consistency) -</strong> Baza danych ostatecznie stanie się spójna, a dane będą propagowane wszędzie w dowolnym momencie w przyszłości.</li></ul><blockquote>Struktura danych jest najważniejszym czynnikiem decydującym o tym, czy użyć bazy danych SQL, czy NoSQL, więc zastanów się nad tym przed podjęciem decyzji.</blockquote><h3 id="mo-liwo-zapytania-danych">Możliwość zapytania danych</h3><p><br>Następnym czynnikiem, który należy wziąć pod uwagę, jest częstotliwość wysyłania zapytań do danych, szybkość uruchamiania zapytań i kto będzie odpowiedzialny za ich uruchamianie.</p><p>Ponieważ twoje dane są ładnie u strukturyzowane i zorganizowane, bardzo wydajne jest wyszukiwanie danych w bazie danych SQL.</p><p>SQL jest popularnym językiem programowania, który istnieje od ponad 45 lat, więc jest niezwykle dojrzały i dobrze znany. Wydajnie wykonuje zapytania oraz szybko pobiera i edytuje dane. Jest bardzo lekki i deklaratywny, a zatem łatwy do nauczenia. Dlatego zapytania mogą być uruchamiane przez mniej techniczny personel, taki jak analitycy biznesowi i marketerzy.</p><p>Baza danych NoSQL zapewnia ogromną elastyczność w zakresie typów danych, które można przechowywać, ale ze względu na potencjalnie duże różnice w strukturach danych zapytania nie są tak wydajne, jak w przypadku bazy danych SQL.</p><p>Podczas budowania technologii baz danych NoSQL programiści skupili się na skalowalności i elastyczności, a nie na wydajności zapytań.</p><h3 id="skalowanie">Skalowanie</h3><p><br>Bazy danych SQL i NoSQL skalują się w różny sposób. Bazy danych SQL są skalowane w pionie, co oznacza, że ​​musisz zwiększyć pojemność jednego serwera (zwiększenie procesora, pamięci RAM lub SSD), aby skalować bazę danych. Bazy danych SQL zostały zaprojektowane do działania na jednym serwerze w celu zachowania integralności danych, więc nie są łatwe do skalowania.</p><p>Bazy danych NoSQL skalują się w poziomie, co oznacza, że ​​możesz dodać więcej serwerów, aby zasilać rosnącą bazę danych. Jest to ogromna przewaga, jaką NoSQL ma nad SQL.</p><p>Zdolność baz danych NoSQL do skalowania w poziomie wiąże się z brakiem struktury danych. Ponieważ NoSQL wymaga znacznie mniej struktury niż SQL, każdy przechowywany obiekt jest prawie samowystarczalny i niezależny. W ten sposób obiekty mogą być łatwo przechowywane na wielu serwerach bez konieczności łączenia. Nie dotyczy to SQL, w którym każdy wiersz tabeli i kolumna muszą być powiązane.</p><p>W miarę rozwoju firmy rośnie również baza danych. Upewnij się, że bierzesz pod uwagę swoje potrzeby skalowania.</p><h3 id="konwergencja-sql-i-nosql">Konwergencja SQL i NoSQL</h3><p><br>Zarówno bazy danych SQL, jak i NoSQL mają swoje zalety i wady. W związku z tym nastąpił ruch, aby wziąć najlepsze cechy obu typów baz danych i zintegrować je, aby użytkownicy mogli realizować to, co najlepsze z obu światów.</p><p>Na przykład MySQL, najpopularniejsza relacyjna baza danych typu open source, oferuje MySQL Document Store. Zapewnia to strukturę bazy danych MySQL w połączeniu z elastycznością i wysoką dostępnością NoSQL bez konieczności wdrażania oddzielnej bazy danych NoSQL.</p><p>MongoDB, jedna z najpopularniejszych baz danych NoSQL, oferuje transakcje wielodokumentowe ACID.</p><p>DynamoDB, zarządzana przez AWS baza danych NoSQL, zapewnia także funkcje transakcyjne zgodne z ACID.</p><p>A dzięki łatwej konfiguracji bazy danych oferowanej przez dostawców usług w chmurze masz możliwość korzystania z bazy danych SQL i NoSQL w architekturze chmury w celu zaspokojenia potrzeb w zakresie przechowywania danych.</p><p>Teraz masz znacznie większą elastyczność, niezależnie od tego, czy wybierzesz bazę danych SQL, czy NoSQL, i na pewno będą bardziej elastyczne opcje w przyszłości.</p><h3 id="opcje-bazy-danych">Opcje bazy danych</h3><p><br>Niezależnie od tego, czy korzystasz z bazy danych SQL, czy NoSQL, istnieje wiele opcji do wyboru.</p><p>Lokalne oferty baz danych SQL obejmują:</p><ul><li>MySQL - jak wspomniano wcześniej, najpopularniejsza relacyjna baza danych typu open source<br></li><li>Serwer Microsoft SQL - korporacyjna wersja SQL firmy Microsoft<br></li><li>PostgreSQL - oraz korporacyjna baza danych typu open source skoncentrowana na rozszerzalności<br></li><li>Oracle - kompleksowa (i droga) opcja SQL<br></li><li>MariaDB - ulepszona wersja MySQL, stworzona przez oryginalnych programistów MySQL</li></ul><p><br>Główne platformy usług w chmurze mają własne opcje SQL:</p><p>AWS ma:</p><ul><li>RDS</li><li>Aurora, która koncentruje się na zwiększonej przepustowości i skalowalności</li></ul><p>Microsoft Azure ma: </p><ul><li>Baza danych Azure SQL, zarządzana baza danych jako usługa (SAAS) </li><li>Baza danych Azure dla MySQL,</li><li>PostgreSQL  </li><li>MariaDB</li></ul><p>Google Cloud Platform (GCP) ma:</p><ul><li>Cloud SQL, którego możesz używać dla MySQL i </li><li>PostgreSQL</li><li>Cloud Spanner, który łączy elementy SQL i NoSQL</li></ul><p>Lokalne opcje bazy danych NoSQL obejmują:</p><ul><li>MongoDB - zdecydowanie najpopularniejsza baza danych NoSQL<br></li><li>Redis - superszybka, rozproszona baza danych z kluczami i wartościami w pamięci<br></li><li>Cassandra - darmowa, otwarta baza danych NoSQL stworzona przez Facebooka, która koncentruje się na skalowalności i wysokiej dostępności<br></li></ul><p>Dostawcy usług w chmurze oferują również wiele opcji NoSQL:</p><p>AWS ma:</p><ul><li>DynamoDB, zarządzana baza danych NoSQL<br></li><li>DocumentDB, szybka, skalowalna, wysoce dostępna baza danych zgodna z MongoDB</li></ul><p>Microsoft Azure oferuje:</p><ul><li>CosmosDB, globalnie dystrybuowana, wielomodelowa baza danych</li></ul><p>Google Cloud ma:</p><ul><li>Bigtable, szerokokolumnowa usługa bazy danych NoSQL<br></li><li>Cloud Datastore, usługa bazy danych dokumentów NoSQL<br></li><li>Cloud Firestore, natywna dla chmury baza danych dokumentów NoSQL, która pomaga przechowywać i przeszukiwać dane aplikacji</li></ul><h3 id="podsumowanie">Podsumowanie </h3><p>Istnieje wiele mitów i nieporozumień dotyczących SQL; na przykład, że SQL jest przestarzały i powinien być zastąpiony przez NoSQL, gdy tylko jest to możliwe. Oczywiście to nie prawda. Obecnie nie ma wyraźnego lidera wśród nich, każdy z nich jest bardziej odpowiedni dla niektórych projektów i mniej odpowiedni (lub wręcz nieodpowiedni) w innych sytuacjach. Dlatego nie ma uniwersalnego idealnego wyboru. </p>]]></content:encoded></item><item><title><![CDATA[GraphQL vs REST]]></title><description><![CDATA[GraphQL vs REST. Różnice w api, zastosowaniach, wzorcach projektowych. Wady i zalety.   ]]></description><link>https://blog.spaceout.pl/graphql-vs-rest/</link><guid isPermaLink="false">5e7f498a028743ff49f7ba7f</guid><category><![CDATA[graphql]]></category><category><![CDATA[rest]]></category><dc:creator><![CDATA[Spaceghost]]></dc:creator><pubDate>Sat, 21 Sep 2019 17:46:49 GMT</pubDate><media:content url="https://blog.spaceout.pl/content/images/2020/03/PIA21641_hires-2.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://blog.spaceout.pl/content/images/2020/03/PIA21641_hires-2.jpg" alt="GraphQL vs REST"><p>Zanim przejdę do dokładnego, subiektywnego omówienia różnic pomiędzy tymi dwoma podejściami zapytań serwera / backendu warto zaznaczyć, że żadna z tych technologii nie jest lepsza lub gorsza od drugiej. To są zupełnie 2 różne technologie i podejścia do budowy systemu aplikacji webowej.  </p><h2 id="pierwsze-r-nice-">Pierwsze różnice ... </h2><p><strong>REST</strong> to architektoniczny koncept budowy systemów internetowych, nie ma oficjalnych narzędzi oraz specyfikacji . Zaprojektowany z myślą aby rozłączyć (decouple) API od klienta (frontu). W przeciwieństwie do GraphQl może nie tylko posługiwać się HTTP, jego zadaniem jest budowa stabilnej i trwałej architektury systemu.</p><p>GraphQL to język zapytań  "<a href="http://graphql.org/learn/queries/">query language</a>", <a href="http://facebook.github.io/graphql/">spec</a>yfikacji i narzędzi zbudowanych z myślą o optymalizacji  dostarczania danych poprzez jeden endpoint HTTP<a href="https://github.com/graphql/">.</a></p><p>Jedną z głównych zasad konwencji REST, jest to aby używać wszystkich dostępnych protokołów. REST używa HTTP content-types, caching, status codes. GraphQL używa swoich własnych konwencji</p><p>W poście postaram się pokazać wam właśnie te różnice w podejściu do budowy aplikacji. Warto pamiętać, że pod koniec dnia jaka technologia jest lepsza zależy od tego co robicie ze swoją aplikacją, dla niektórych rzeczy GraphQL będzie lepszy, dla innych REST, dla jeszcze innych obydwa podejścia mogą okazać się tak samo frustrujące.</p><p><strong>Czy API to tylko transfer danych ?</strong></p><p>Jedną z podstawowych zadań REST API to tzw operacje <a href="https://pl.wikipedia.org/wiki/CRUD">CRUD (create, read, update, delete) </a>poprzez plik JSON. Jedną zalet REST jest łatwe i szybkie przesyłanie plików</p><p>Przykładowy przesył pliku jpeg</p><pre><code>POST /avatars HTTP/1.1
Host: localhost:3000
Content-Type: image/jpeg
Content-Length: 284

raw image content
</code></pre><p>Korzystając z protokołu HTTP (a zatem i REST), programiści mogą obsługiwać żądania aplikacji / json na tym samym punkcie końcowym, można także oferować przesyłanie na podstawie adresu URL:</p><pre><code>POST /avatars HTTP/1.1
Host: localhost:3000
Content-Type: application/json

{
  "image_url" : "https://spaceout.pl/pic.png"
}
</code></pre><p>Gdybyśmy mówili o przesyłaniu filmów lub innych dużych plików zaproponowałbym inne podejście i miałbym dedykowaną usługę, która obsługuje przesyłanie, pozostawiając główny interfejs API akceptujący tylko metadane; tytuł, opis, tagi itp.<br></p><p>W przypadku GraphQL takie podejście to nasz jedyny wybór, ponieważ możesz komunikować się z GraphQL tylko w zakresie pól:</p><pre><code>POST /graphql HTTP/1.1
Host: localhost:3000
Content-Type: application/graphql

mutation addAvatar {
  addProfileImageFromUrl(image_url: "https://spaceout.pl/pic.png") {
    id,
    image_url
  }
}
</code></pre><p>Niektórzy twierdzą, że jest to bardziej „czyste”, ale zmuszenie do stworzenia innej usługi jest przesadą w przypadku mniejszych obrazów, szczególnie na początku projektu. </p><p>Innym podejściem jest przesyłanie bezpośrednio np do Amazon S3, wymuszając zależność od klientów i potencjalnie pozwalając na wyciek tokenów. </p><p>Jednym z obszarów, w którym GraphQL wyróżnia się, jest niezwykle łatwe monitorowanie wykorzystania pola na poziomie technicznym. Klienci GraphQL są zmuszeni do określenia pól, które mają zostać zwrócone w zapytaniu:</p><pre><code>POST /graphql HTTP/1.1
Host: localhost:3000
Content-Type: application/graphql

{
  spaceships(id: "123") {
    length,
    width,
    power
  }
}
</code></pre><p>Śledzenie tego byłoby trywialne, ale interfejs API REST działa nieco inaczej. Podczas gdy wszystkie interfejsy API REST udostępniają podstawowy punkt końcowy za pośrednictwem<code>/spaceships/123</code>, nie wszystkie interfejsy API oferują rzadkie zestawy pól: <code>/spaceships/123?fields=length,width,intelligence</code>. </p><p><br>Jeśli klient interfejsu API REST wywołuje <code>/spaceships/123</code>, może używać dowolnego pola w tej odpowiedzi. Wyobraź sobie, że API planuje pozbyć się <code>power</code> , skąd programiści API wiedzą, którzy klienci używają tego pola?</p><p><br>Najczęściej rozwiązuje się ten problem przez utworzenie nowego punktu końcowego / <code>/getSpaceships2</code> (lub <code>/v2/spaceships/123</code>) i poleceniu innym użytkownikom korzystania z tego nowego.</p><p>Innym podejściem byłoby utworzenie nowej wersji zasobu, co oznacza, że ​​zamiast wywoływać  <code>GET</code> za pomocą  <code>Accept: application/vnd.spaceout.pl+v1+json</code>, teraz muszą używać <code>Accept: application/vnd.spaceout.pl+v1+json</code> </p><p>GraphQL stawia na wydajność<br>GraphQL jest zawsze najmniejszym możliwym żądaniem, podczas gdy REST zazwyczaj domyślnie zwraca cały endpoint.</p><blockquote>Kiedy aplikacja chce banana, REST zwraca Goryla z dżunglą, trzymającego banana"  </blockquote><p>Nawet jeśli interfejs API REST domyślnie zwraca tylko podstawowe częściowe, nadal domyślnie przesyłanych jest więcej bitów niż w przypadku metody GraphQL. Jeśli klient potrzebuje pola, zażąda go, a jeśli interfejs API doda nowe pole, klienci go nie otrzymają. </p><p>REST sprawia, że ​​buforowanie jest łatwiejsze na wszystkich poziomach</p><blockquote>W interfejsie API opartym na punkcie końcowym klienci mogą korzystać z buforowania HTTP, aby uniknąć ponownego pobierania zasobów oraz do  identyfikowania, kiedy dwa zasoby są identyczne. Jednak w GraphQL nie ma elementu podstawowego podobnego do adresu URL, który zapewnia ten globalnie unikalny identyfikator dla danego obiektu. Dlatego najlepszą praktyką dla API jest ujawnianie takiego identyfikatora do użycia przez klientów. - Źródło: graphql.org</blockquote><p><br>REST przez HTTP wykorzystuje cały stos konwencji HTTP, które sprawiają, że istniejący klienci HTTP, serwery proxy pamięci podręcznej HTTP itp. Działają łatwo, zapewniając korzyści zarówno klientom API, jak i serwerom API, ale z GraphQL… trudnym. Zreorganizuj swoje magazyny danych, użyj kilku Redis i mam nadzieję, że klienci też będą buforować.</p><h2 id="graphql-to-j-zyk-zapyta-"><br>GraphQL to język zapytań</h2><p>Bardzo podstawową różnicą jest tutaj to, że tylko jeden z nich jest językiem zapytań. Interfejsy API REST są często tworzone początkowo proste, a następnie z czasem wprowadzane są coraz więcej funkcji podobnych do języka zapytań.</p><p>Najbardziej rozsądnym sposobem dostarczenia argumentów dla zapytań w REST jest umieszczenie ich w ciągu zapytania. Może? <code>?status=active</code>, aby filtrować według statusu, a następnie prawdopodobnie <code>sort=created</code>, ale klient potrzebuje kierunku sortowania, więc dodaje się <code>sort-dir=desc</code>.<br>Niektóre używane interfejsy API kończą się także argumentami w ciągu zapytania, które nie są związane z filtrowaniem, a bardziej opcjami. </p><p>W przykładzie GraphQL określają jednostkę, w której mają być zwrócone <code>height</code>:</p><pre><code>{
  human(id: "1000") {
    name
    height(unit: FOOT)
  }
}
</code></pre><pre><code>{
  "data": {
    "human": {
      "name": "Luke Skywalker",
      "height": 5.6430448
    }
  }
}
</code></pre><p></p><p>Z REST przy takim zapytaniu mamy trochę bałagan; <code>?status=active</code> jako filtr, <code>?unit=foot</code> jako dodatkowa opcja wyświetlania danych. Nasze API <code>/unit=foot?status=active</code>, szybko korzystanie z takich rozwiązań kończy się bólem głowy bez dokumentacji czy jakieś konwencji w budowaniu naszego API.</p><p>GraphQL wyprzedza interfejsy API REST, które próbują ręcznie wprowadzić własną funkcjonalność języka zapytań. GraphQL zapewnia składnię języka zapytań oraz zestawy SDK, potrzebne front-end developerowi. Jeżeli planujesz wysoce konfigurowalny interfejs API, jest to kolejny powód do wybrania GraphQL.</p><h2 id="dostosowanie-api">Dostosowanie API</h2><p>Inną kwestią związaną z dostosowywaniem naszego API,  jest to, kiedy zaoferować uwzględnione relacje a kiedy użyć innego punktu końcowego. Może to być trudny wybór projektowy, interfejs API powinien być elastyczny i wydajny. </p><p>Zaczynasz od  <code>/users?include=comments,posts</code> a tu jeszcze profile, settings ...  i więcej informacji które potrzebuje klient. Tutaj znowu pojawia się problem banana z gorylem i dżungla. Czasami potrzebne są tylko szczątkowe informacje potrzebne z każdego obiektu. <br></p><p>GraphQL nie tylko usuwa to pytanie projektowe, ale wymusza podejście uwzględniające i zmusza do rozważenia wydajnych sposobów pobierania tych danych. Jest to duża wygrana dla GraphQL,  będzie on zarówno wydajny, jak i spójny. </p><p>GraphQL nie pomoże w zapytaniach do bazy danych, więc nadal musisz dostroić te indeksy i buforować fragmenty danych w inteligentny sposób. </p><h2 id="dlaczego-nie-skorzysta-z-obu">Dlaczego nie skorzystać z obu?</h2><p>Obydwa podejścia mają swoje wady i zalety, nie znaczy jednak, że musimy się decydować na tylko jedno z nich. REST API świetnie posłuży do przesyłania zdjęć, potwierdzania tokenów, resetu hasła ..., GraphQL jest wydajnym klientem dostarczającym treść i dane potrzebne dla każdego zaplanowanego widoku strony internetowej czy aplikacji.  <br></p>]]></content:encoded></item><item><title><![CDATA[Safari debug w windows 10]]></title><description><![CDATA[Krótki przewodnik jak debuggować strony WWW w windows 10, za pomocą chrome i telefonu iPhone.]]></description><link>https://blog.spaceout.pl/safari-debug-on-windows/</link><guid isPermaLink="false">5e7f498a028743ff49f7ba8a</guid><category><![CDATA[safari]]></category><category><![CDATA[windows10]]></category><category><![CDATA[windows]]></category><category><![CDATA[iOS]]></category><category><![CDATA[iPhone]]></category><category><![CDATA[Debug]]></category><category><![CDATA[chrome]]></category><category><![CDATA[firefox]]></category><category><![CDATA[cross-browser]]></category><dc:creator><![CDATA[Spaceghost]]></dc:creator><pubDate>Mon, 17 Jun 2019 00:55:00 GMT</pubDate><media:content url="https://blog.spaceout.pl/content/images/2020/03/tim-mossholder-191485-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://blog.spaceout.pl/content/images/2020/03/tim-mossholder-191485-unsplash.jpg" alt="Safari debug w windows 10"><p>Robiąc dobry Front End trzeba pamiętać o wszystkich przeglądarkach, pollyfilach i cross-browserowych sprawach. Jednym z najtrudniejszych zadań zawsze dla mnie było radzenie sobie z przeglądarką safari oraz system macOS. Nie jestem fanem maców, uważam, że trochę za bardzo cenią sobie swoje produkty,  nie można ukryć, że jest na wiele świecie wiele zadowolonych użytkowników iPhona, którzy nie zamierzają przerzucać się na andro. Warto zadbać aby nasza strona prezentowała się w safari tak jak powinna. </p><p>Safari mobile jak i jego desktopowa wersja, zawszę była w tyle do chrome czy nawet samego firefoxa, późniejsza implementacja flexboxa, grida, filtrów css jak i wiele bugów w samym odczycie css przyprawiało mnie o koszmary podczas finalnych oględzin stron do oddania. </p><p>Natrafiłem jednak na narzędzie, które pomogą w debugowaniu stron i aplikacji w chrome, firefox i vs code. Ciągle potrzebny jest nam telefon iPhone ale to wydaje mi się łatwiejsze do ogarnięcia niż nowy macbook z wystarczająca ilością ramu do odpalenia programu xcode i symulatora iOS. </p><p>Projekt jest trudny w konfiguracji, wymaga dostępu do powershella windowsa, instalacji scoop'a. Najlepiej postępować według oryginalnej dokumentacji projektu. </p><p><a href="https://github.com/RemoteDebug/remotedebug-ios-webkit-adapter">https://github.com/RemoteDebug/remotedebug-ios-webkit-adapter</a></p><p> Aby debugować iOS, po zmianach w 12 &gt;, projekt który chcecie ściągnąć to fork od  <a href="https://github.com/fishbone1/remotedebug-ios-webkit-adapter">https://github.com/fishbone1/remotedebug-ios-webkit-adapter</a>. </p><p>Musicie przejść przez kroki przygotowania systemu i instalacji samej paczki oraz libimobile, sklonować projekt oraz wykonać polecenia, npm install i start. Warto także pamiętać aby ustawić port w " Discover network targets" w opcjach chrome://inspect   </p><p>Wygląda na to, że nikt się zbytnio nie zajmuje projektem jednakże myślę, że to bardzo ciekawy projekt. Korzysta z websocetsów aby transportować dane między komputerem a telefonem. Uratował mnie już nie jeden raz przed notorycznymi problemami na telefonach iphone. </p><p></p>]]></content:encoded></item><item><title><![CDATA[Zmiany w 3rd party node modules bez bólu za pomocą yarn patch-package]]></title><description><![CDATA[Czy kiedykolwiek musieliście poprawiać zainstalowane biblioteki w swoim projekcie ? patch-package alternatywa do linkowania i "forkowania" 3rd party node modules. ]]></description><link>https://blog.spaceout.pl/zmiany-w-3rd-party-node-modules-bez-bolu-za-pomoca-yarn-patch-package/</link><guid isPermaLink="false">5e7f498a028743ff49f7ba89</guid><category><![CDATA[npm]]></category><category><![CDATA[yarn]]></category><category><![CDATA[automatyzacja pracy]]></category><category><![CDATA[github]]></category><category><![CDATA[node.js]]></category><category><![CDATA[patch-package]]></category><category><![CDATA[node_modules]]></category><dc:creator><![CDATA[Spaceghost]]></dc:creator><pubDate>Wed, 12 Jun 2019 17:14:31 GMT</pubDate><media:content url="https://blog.spaceout.pl/content/images/2020/03/harishan-kobalasingam-1491342-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://blog.spaceout.pl/content/images/2020/03/harishan-kobalasingam-1491342-unsplash.jpg" alt="Zmiany w 3rd party node modules bez bólu za pomocą yarn patch-package"><p>Czy zdarzyło się wam grzebać lub poprawiać coś w instalowanych paczkach na swoim projekcie ? Jeżeli tak to dobrze wiecie, że jakiekolwiek zmiany zapisane bezpośrednio w folderze node_modules nie maja prawa bytu ze względu na to, że zostaną nadpisane przy jakiekolwiek zmianie / instalacji projektu. Na szczęście przychodzi nam na ratunek moduł patch-package. </p><p>Normalnie gdy odkryjemy jakiś błąd lub chcielibyśmy dodać jakikolwiek feature do jednych z bibliotek, które znajdują się u nas w folderze node_modules, musimy z "forkować" oryginalną bibliotekę, nanieść zmiany i dać pr merge na githubie. Ale jeżeli poprawiamy jakiś błąd na dużym projekcie, takie rozwiązanie może trwać pare dni, jeżeli nie tygodni. Testy, review team itd. Co jak nie chcemy się w to bawić, albo porostu nie mamy na to czasu ?</p><h3 id="patch-package">patch-package</h3><p>Dla przykładu chcemy edytować paczkę <strong>przykład-lib</strong></p><ol><li>Instalacja patch-package</li></ol><!--kg-card-begin: markdown--><pre><code>yarn add --dev patch-package postinstall-prepare
</code></pre>
<!--kg-card-end: markdown--><p>instalacja postinstall-prepare musi zostać dołączona ze względu na to aby upewnić się, że patch-package zostanie uruchomiony nawet po komendzie yarn remove </p><p>2. Zmiana plików w <strong>przykład-lib</strong></p><p>Edytujemy i zapisujemy zmiany normalnie tak jakby by były częścią projektu. </p><p>3. Uruchomienie patch-package</p><!--kg-card-begin: markdown--><pre><code>yarn patch-package przykład-lib
</code></pre>
<!--kg-card-end: markdown--><p>Patch-package wychwyci zmiany w przykład-lib, da znać na terminalu, że zmiany zostały zapisane, dodatkowo dołoży nam folder do projektu "/patches", gdzie przechowuje nasze zmiany. </p><p>4. Edycja pliku package.json </p><p>Ostatnim krokiem instalacji patch-package jest dodanie skryptu "prepare" do naszego pliku package.json. Dzięki temu poleceniu nasz projekt zawsze będzie niezależnie i automatycznie dodawał nasze zmiany przy poleceniach yarn czy npm install. </p><!--kg-card-begin: markdown--><pre><code>&quot;scripts&quot;: {
  &quot;prepare&quot;: &quot;patch-package&quot;
}
</code></pre>
<!--kg-card-end: markdown--><p>To już wszystko co trzeba zrobić aby móc dowolnie patchować 3rd party libraries. Dla mnie ta opcja jest bardzo pomocna, jednakże nie wolno zapominać, że najlepszym rozwiązaniem jest ciągle "forkowanie" bibliotek i nanoszenie zmian dla nas wszystkich.  Open source górą. </p><p>Jak zwykle pozdrawiam serdecznie. </p>]]></content:encoded></item><item><title><![CDATA[Centos 7, przygotowanie środowiska developerskiego.]]></title><description><![CDATA[<p>Aplikacje, serwery, endpointy czy wszelkiego rodzaju instalacje webowe zazwyczaj kończą swój cykl developerski w chmurzę, dedykowanych serwerach czy vps-ach (virtual private server). Centos 7 to stabilny system operacyjny oparty o RHEL Red Hat Enterprise Linux (RHEL).  Jest to mój ulubiony system pod testowanie aplikacji webowych. Jakiś czas temu przerobiłem starego</p>]]></description><link>https://blog.spaceout.pl/centos-7-instalcja/</link><guid isPermaLink="false">5e7f498a028743ff49f7ba88</guid><category><![CDATA[centos7]]></category><category><![CDATA[docker]]></category><category><![CDATA[docker-compose]]></category><category><![CDATA[Linux]]></category><category><![CDATA[node.js]]></category><category><![CDATA[VPS]]></category><dc:creator><![CDATA[Spaceghost]]></dc:creator><pubDate>Sun, 19 May 2019 10:55:09 GMT</pubDate><media:content url="https://blog.spaceout.pl/content/images/2020/03/free-nature-stock-779107-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://blog.spaceout.pl/content/images/2020/03/free-nature-stock-779107-unsplash.jpg" alt="Centos 7, przygotowanie środowiska developerskiego."><p>Aplikacje, serwery, endpointy czy wszelkiego rodzaju instalacje webowe zazwyczaj kończą swój cykl developerski w chmurzę, dedykowanych serwerach czy vps-ach (virtual private server). Centos 7 to stabilny system operacyjny oparty o RHEL Red Hat Enterprise Linux (RHEL).  Jest to mój ulubiony system pod testowanie aplikacji webowych. Jakiś czas temu przerobiłem starego laptopa na serwer oparty o Centos 7. Dużo integruje w ten system, aby znaleźć optymalne ustawienia wydajności i bezpieczeństwa.  Ostatnio strasznie popsułem ustawienia, dlatego postanowiłem zainstalować Centosa od nowo oraz zapisać sobie proces instalacyjny, żebym nie musiał biegać po googlu jak szalony.</p><h2 id="centos-7">Centos 7  </h2><p>Centosa najlepiej się chyba ściga przez torrenty, można znaleźć plik torrent w każdym z oficjalnych <a href="http://isoredirect.centos.org/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-1810.iso">mirror'ów strony oficjalnej </a>. </p><p>Program <a href="https://rufus.ie/">Rufus</a> do robienia USB BOOT UEFI na Win</p><p>Linux, można od wersji centos 6 można kopiować obraz bezpośrednio na USB  </p><!--kg-card-begin: markdown--><p><code>dd if=CentOS-6.5-x86_64-bin-DVD1.iso of=/dev/sdb</code></p>
<!--kg-card-end: markdown--><h2 id="instalacja">Instalacja</h2><p>Wersja 7.4 DVD Iso posiada graficzny interfejs instalacyjny, ustawiamy ścieżkę do dysku oraz pakiety jakie chcemy zainstalować.  Centos 7 zawiera pakiety dla developerów, pod server, gnome desktop, itd. </p><p>Po instalacji systemu osobiście instaluje także: </p><h2 id="node-js">Node.js</h2><p>Centos 7, zależnie od pakietów wybranych przy instalacji systemu posiada, już node.js, jednakże jest to wersja 6. (Ostatnia poważna aktualizacja systemu Centos 7 była w 2014 roku). Aby zainstalować nowe wersje musimy dodać repo do bazy Centos 7.</p><p><strong>Najnowszy node(12)<strong>:</strong></strong></p><pre><code>yum install -y gcc-c++ make 
curl -sL https://rpm.nodesource.com/setup_12.x | sudo -E bash -
</code></pre><p><strong><strong>Stable</strong>: </strong></p><pre><code>yum install -y gcc-c++ make 
curl -sL https://rpm.nodesource.com/setup_10.x | sudo -E bash -
 </code></pre><p>*Możliwe są dalsze problemy instalacyjne node, najczęściej system wywala się podczas instalacji nowszej wersji node.js</p><p><strong>Workaround:</strong> </p><p>Instalujemy nowy node przez npm oraz podmieniamy ścieżki (system link do nowej wersji node)</p><pre><code>npm cache clean -f
npm install -g n
ln -sf /usr/local/n/versions/node/(wersja node, np:)10.15.3/bin/node /usr/bin/node
node -v (sprawdzamy wersje)
</code></pre><h2 id="yarn">Yarn</h2><p>Trzeba dodać repo yarn</p><pre><code>curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo
yum -y install yarn</code></pre><h2 id="git">Git</h2><p>Z git możemy mieć problem z dostępem do najnowszej wersji. Centos 7 może nam uparcie mówić, że wersja 1.8 to najnowsza wersja. W takim razie musimy usunąć gita, i zainstalować nowszą wersje od iuscommunity </p><pre><code>sudo yum remove git
sudo yum -y install  https://centos7.iuscommunity.org/ius-release.rpmsudo yum -y install  git2u-all
$ git --versiongit version 2.16.5</code></pre><h3 id="docker-i-docker-compose">Docker i Docker Compose</h3><p>Dodajemy odpowiednie repa do yum config, oraz instalujemy docker-ce</p><pre><code>sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce
sudo usermod -aG docker nazwa_użytkownika
sudo systemctl enable docker.service
sudo systemctl start docker.service</code></pre><p>Docker Compose</p><pre><code>sudo yum install epel-release
sudo yum install -y python-pip
sudo pip install --upgrade pip
sudo pip install docker-compose
sudo yum upgrade python*
docker-compose version</code></pre><p>*Problem GSSException przy sprawdzaniu wersji można rozwiązać przez usunięcie pakietu python-gssapi</p><pre><code>sudo yum remove python-gssapi
</code></pre><h2 id="google-chrome">Google Chrome</h2><p>Musimy stworzyć własny plik z info o repo Googla, w ten sposób będziemy mogli robić update Chrome przez komendy.</p><pre><code>cd /etc/yum.repos.d/
sudo nano google-chrome.repo</code></pre><p>Dodać plik o treści </p><pre><code>[google-chrome]
name=google-chrome
baseurl=http://dl.google.com/linux/chrome/rpm/stable/x86_64
enabled=1
gpgcheck=1
gpgkey=https://dl.google.com/linux/linux_signing_key.pub</code></pre><h2 id="visual-studio-code">Visual Studio Code</h2><p>Dodajemy repo, VS code</p><pre><code>sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
sudo sh -c 'echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com/yumrepos/vscode\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" &gt; /etc/yum.repos.d/vscode.repo'</code></pre><p>Sprawdzamy i instalujemy code</p><pre><code>yum check-update
sudo yum install code</code></pre><!--kg-card-begin: html--><style type="text/css">
.adsbygoogle { width: 320px; height: 100px; margin-bottom: 20px; margin-top: 20px }
@media (min-width:500px) { .adsbygoogle { width: 468px; height: 60px; margin-bottom: 20px; margin-top: 20px } }
@media (min-width:800px) { .adsbygoogle { width: 728px; height: 90px; margin-bottom: 20px; margin-top: 20px} }
</style>
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle" style="display:block; text-align:center;" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-6242359777372316" data-ad-slot="7582662731"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script><!--kg-card-end: html--><h2 id="konfiguracja-sieci">Konfiguracja Sieci</h2><p>Ostanie co musimy zrobić to ustawić naszą sieć lokalną oraz zasady firewall aby nasze aplikacje uruchomione na Centos 7 były dostępne z innych urządzeń. Zazwyczaj musimy otworzyć porty używane podczas cyklu developerskiego  (8000) i produkcyjnego (3000). </p><pre><code>firewall-cmd --zone=public --permenent --add-service=https
firewall-cmd --zone=public --permenent --add-service=http
firewall-cmd --zone=public --permenent --add-service=ssh
firewall-cmd --zone=public --permenent --add-port=(numerPortu)/tcp
firewall-cmd --reload
</code></pre><p>Teraz nasze apki już powinny być dostępne dla sieci lokalnych. </p><p>Centos oraz systemy linkusowe są o wiele bardziej dostosowane do współpracy z node niż Windows według mojej opinii, starszy komputer z i5 radzi sobie lepiej, szybciej buduje i serwuje pliki niż i7 z windowsem. Dodatkowo natywne mamy obsługę dockera, która przydaje się podczas końcowego etapu deweloperskiego aplikacji. </p><p>Pozdrawiam </p>]]></content:encoded></item><item><title><![CDATA[Gatsby WooCommerce Source Plugin]]></title><description><![CDATA[Gatsby.js plus Wordpress WooCommerce]]></description><link>https://blog.spaceout.pl/gatsby-woocommerce-source-plugin/</link><guid isPermaLink="false">5e7f498a028743ff49f7ba87</guid><category><![CDATA[woocommerce]]></category><category><![CDATA[Wordpress]]></category><category><![CDATA[Gatsby.js]]></category><dc:creator><![CDATA[Spaceghost]]></dc:creator><pubDate>Sun, 07 Apr 2019 19:02:08 GMT</pubDate><media:content url="https://blog.spaceout.pl/content/images/2020/03/ws_Blue_Zone_1920x1080.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://blog.spaceout.pl/content/images/2020/03/ws_Blue_Zone_1920x1080.jpg" alt="Gatsby WooCommerce Source Plugin"><p>O Zaletach <a href="https://blog.spaceout.pl/gatsby-js/">gatsby.js</a> rozpisywałem się już na swoim blogu wielokrotnie, to generator stron statycznych, w którym mamy możliwość zaciągania danych z dowolnego API.</p><p> Wordpress pomimo sowich wielu wad, to jednak stary i sprawdzony muł, jest idealnym kandydatem do systemu CMS. Wiele osób z niego korzysta, można dość szybko dostosować jego możliwości backendowe. </p><p>WooCommerce jest jedna z takich możliwości, w szybki i tani sposób mamy cały system sklepowy, który integruje się z system REST API wordpressa co oznacza, że nasza instalacja jest właściwie gotowa do przyjęcia dowolnego klienta. </p><p> Ja do frontu zazwyczaj korzystam z gatsby.js, jakby ktoś chciał skorzystać z takiego rozwiązania to mam własnego forka, <a href="https://github.com/MassivDash/gatsby-source-woocommerce">https://github.com/MassivDash/gatsby-source-woocommerce</a>. Dałem jakieś tam małe usprawnienia ale przedrzymskim dodałem funkcje kontroli zaciągania produktów jakiej brakuje głównemu repo. </p><p>Plugin korzysta z oficjalnego node api wordpressa, zaciąga dane o produktach następnie przetwarza je na graphql endpoint dla naszego gatsby.js. Podczas local developmentu mamy już pełny set danych i nic nam nie stoi na przeszkodzie zbudowania stron produktów czy głównej sklepu. </p><p>Dzięki takiemu rozdzieleniu instalacji, możemy zbudować nasz front w technologii react oraz wyrzuć nasz sklep na dowolny serwer. </p>]]></content:encoded></item></channel></rss>