{"id":13696,"date":"2023-01-12T20:24:08","date_gmt":"2023-01-12T19:24:08","guid":{"rendered":"https:\/\/vived.io\/?p=13696"},"modified":"2023-01-14T10:36:31","modified_gmt":"2023-01-14T09:36:31","slug":"co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120","status":"publish","type":"post","link":"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/","title":{"rendered":"Co takiego dostarczy\u0142 nam Angular 15.1? | Frontend Weekly vol. 120"},"content":{"rendered":"\n<h2 id=\"1-angular-15-1\" data-num=1>1. Angular 15.1<\/h2>\n\n\n\n<p>W minionym tygodniu wydany zosta\u0142 Angular 15.1. Wi\u0119kszo\u015b\u0107 zmian i nowo\u015bci dotyczy funkcjonalno\u015bci, kt\u00f3re dodane zosta\u0142y w Anuglarze 14 i 15. Bez zb\u0119dnego przed\u0142u\u017cania przejd\u017amy do rzeczy.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Self Closing Tags<\/h3>\n\n\n\n<p>Frameworki takie jak Vue czy React, traktuj\u0105 komponenty jako czysto abstrakcyjne byty mapowane do struktury DOM. Je\u015bli zobaczycie sobie plik HTML wygenerowany przez jeden z tych framework\u00f3w, to nie znajdziecie tam w\u0142a\u015bciwie \u017cadnego \u015bladu po abstrakcji jak\u0105 s\u0105 kompoenenty. Angular podchodzi do tematu zupe\u0142nie inaczej i ka\u017cdemu komponentowi przypisuje Custom HTML Tag. Dzi\u0119ki temu kiedy spojrzycie na stron\u0119 wygenerowan\u0105 przez Angulara, od razu b\u0119dziecie w stanie powi\u0105za\u0107 odpowiednie fragmenty HTML z komponentami.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-xml\">&lt;!-- The HTML code of a simple application rendered by Angular --&gt;\n&lt;!-- You can clearly see how source code is devided into components --&gt;\n&lt;!DOCTYPE html&gt;\n&lt;html lang=&quot;en&quot;&gt;\n  &lt;head&gt;\n    &lt;meta charset=&quot;utf-8&quot;&gt;\n    &lt;title&gt;Simple App&lt;\/title&gt;\n    &lt;script src=&quot;script.js&quot;&gt;&lt;\/script&gt;\n  &lt;\/head&gt;\n  &lt;body&gt;\n    &lt;app-root&gt;\n      &lt;h1&gt;Welcome to my application!&lt;\/h1&gt;\n      &lt;app-navigation-link&gt;\n        &lt;a href=&quot;\/home&quot;&gt;Home&lt;\/a&gt;\n      &lt;app-navigation-link&gt;\n      &lt;app-navigation-link&gt;\n        &lt;a href=&quot;\/about&quot;&gt;About&lt;\/a&gt;\n      &lt;app-navigation-link&gt;\n    &lt;app-root&gt;\n  &lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-xml\">&lt;!-- The same application as above but this time rendered with react --&gt;\n&lt;!-- It&#039;s really hard to say source how code have been devided into componets --&gt;\n&lt;!DOCTYPE html&gt;\n&lt;html lang=&quot;en&quot;&gt;\n  &lt;head&gt;\n    &lt;meta charset=&quot;utf-8&quot;&gt;\n    &lt;title&gt;Simple App&lt;\/title&gt;\n    &lt;script src=&quot;script.js&quot;&gt;&lt;\/script&gt;\n  &lt;\/head&gt;\n  &lt;body&gt;\n    &lt;div&gt;\n      &lt;h1&gt;Welcome to my application!&lt;\/h1&gt;\n      &lt;a href=&quot;\/home&quot;&gt;Home&lt;\/a&gt;\n      &lt;a href=&quot;\/about&quot;&gt;About&lt;\/a&gt;\n    &lt;div&gt;\n  &lt;\/body&gt;\n&lt;\/html&gt;\n<\/code><\/pre>\n\n\n\n<p>Specyfikacja Custom HTML Tag zak\u0142ada kilka ogranicze\u0144. Mi\u0119dzy innymi nazwa tagu musi zawiera\u0107 znak <code>-<\/code>. To w\u0142a\u015bnie dlatego Angular domy\u015blnie do selektor\u00f3w dodaje prefix <code>app<\/code>. Ograniczenie to nie wi\u0119\u0142o si\u0119 znik\u0105d &#8211; przestrze\u0144 nazw nie zawieraj\u0105cych <code>-<\/code> zarezewowana jest dla przysz\u0142ego wykorzystania w standardzie HTML.<\/p>\n\n\n\n<p>Wed\u0142ug standardu HTML, tylko wybrane tagi mog\u0105 zamyka\u0107 same siebie. Ich lista jest stosunkowo kr\u00f3tka i zawiera takie elementy jak <code>&lt;link \/&gt;<\/code>, <code>&lt;br \/&gt;<\/code>  czy  <code>&lt;img \/&gt;<\/code> (pe\u0142n\u0105 list\u0119 mo\u017cecie znale\u017a\u0107 mi\u0119dzy innymi <a href=\"http:\/\/xahlee.info\/js\/html5_non-closing_tag.html\" target=\"_blank\" rel=\"noreferrer noopener\">tutaj<\/a>). Niestety na li\u015bcie tej na pr\u00f3\u017cno szuka\u0107 Custom HTML Tags. Oznacza to, \u017ce je\u015bli chcemy pozosta\u0107 zgodni ze standardem HTML, to skazani jeste\u015bmy na r\u0119czne zamykanie Custom HTML Tags. Chc\u0105c pozosta\u0107 w zgodzie ze standarderm, Angular musia\u0142 pozosta\u0107 za konkurencj\u0105, kt\u00f3ra od dawna umo\u017cliwia\u0142 takie praktyki (m.in. JSX&#8217;a i <code>&lt;App \/&gt;<\/code>).<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-xml\">&lt;!-- Below declarations are incorrect --&gt;\n&lt;div \/&gt;                    &lt;!-- \u274c div is not a self closing tag --&gt;\n&lt;approot&gt;&lt;\/approot&gt;        &lt;!-- \u274c custom tags must contain - --&gt;\n&lt;app-root \/&gt;               &lt;!-- \u274c custom tags are not self closing --&gt;\n\n&lt;!-- Below declarations are correct --&gt;\n&lt;div&gt;&lt;\/div                 &lt;!-- \u2705 this is correct syntax --&gt;\n&lt;app-root&gt;&lt;\/app-root&gt;      &lt;!-- \u2705 this is correct syntax --&gt;<\/code><\/pre>\n\n\n\n<p>W Angularze 15.1 deweloperom uda\u0142o si\u0119 w ko\u0144cu znale\u017a\u0107 panaceum na zaistnia\u0142y problem. Pisane przez nas templates nie trafiaj\u0105 w ko\u0144cu bezpo\u015brednio do u\u017cytkownika, ale s\u0105  jeszcze transpilowane (jak inaczej mog\u0142oby dzia\u0142a\u0107 <code>*ngFor<\/code>, <code>*ngIf<\/code> czy <code>&lt;ng-template&gt;<\/code>). To w\u0142a\u015bnie podczas tej transpilacji Angular podmienia\u0142 b\u0119dzie samo zamykaj\u0105ce si\u0119 tagi do formatu zgodnego ze standardem. W ten spos\u00f3b, pomimo \u017ce pisane przez nas templates nie b\u0119d\u0105 zgodne ze standardem, to HTML wysy\u0142any do klienta ju\u017c jak najbardziej.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-xml\">&lt;!-- Angular 15.0 --&gt;\n&lt;app-button\n  text=&quot;Click me!&quot;\n  variant=&quot;filled&quot;\n  (onClick)=&quot;handleClick($event)&quot;\n&gt;&lt;\/app-button&gt;\n&lt;app-button\n  text=&quot;Don&#039;t click me!&quot;\n  variant=&quot;outline&quot;\n  (onClick)=&quot;handleClick($event)&quot;\n&gt;&lt;\/app-button&gt;\n\n&lt;!-- Angular 15.1 --&gt;\n&lt;app-button text=&quot;Click me!&quot; variant=&quot;filled&quot; (onClick)=&quot;handleClick($event)&quot; \/&gt;\n&lt;app-button text=&quot;Don&#039;t click me!&quot; variant=&quot;outline&quot; (onClick)=&quot;handleClick($event)&quot; \/&gt;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Deprekacja <code>CanLoad<\/code> na rzecz <code>CanMatch<\/code><\/h3>\n\n\n\n<p>Przed Angularem 15 do dyspozycji deweloper\u00f3w by\u0142y dwa guardy <code>CanLoad<\/code> i <code>CanActivate<\/code>. W przypadku zastosowania lazy-loadingu <code>CanLoad<\/code> decydowa\u0142 czy dany fragment kodu mo\u017ce zosta\u0107 za\u0142adowany przez przegl\u0105dark\u0119. Je\u015bli kod zosta\u0142 ju\u017c raz za\u0142adowany, to Guard ten nie jest uruchamiany ponownie. Z tego wzgl\u0119du, je\u015bli chcemy ograniczy\u0107 dost\u0119p do danej strony (na przyk\u0142ad dla nie zalogowanych u\u017cytkownik\u00f3w), to musimy dodatkowo zabzpieczy\u0107 go dodatkow <code>CanActivate<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\">const routes: Route[] = [{\n  path: &#039;\/me&#039;,\n  canLoad: [() =&gt; inject(UserService).isLoggedIn()],\n  canActivate: [() =&gt; inject(UserService).isLoggedIn()],\n  loadComponent: () =&gt; import(&#039;.\/user-page\/user-page.component&#039;)\n}];<\/code><\/pre>\n\n\n\n<p>Do Angulara 15 trafi\u0142 nowy Guard <code>CanMatch<\/code>, kt\u00f3ry wywo\u0142ywany jest przy ka\u017cdej pr\u00f3bie dopsowania \u015bcie\u017cki niezale\u017cnie od tego czy kod danego modu\u0142u zosta\u0142 ju\u017c za\u0142adowany. Dzi\u0119ki temu podw\u00f3jn\u0105 definicj\u0119 <code>CanLoad<\/code> i <code>CanActivate<\/code> zast\u0105pi\u0107 mo\u017cemy jednym zgrabnym <code>CanMatch<\/code>. <\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\">const routes: Route[] = [{\n  path: &#039;\/me&#039;,\n  canMatch: [() =&gt; inject(UserService).isLoggedIn()],\n  loadComponent: () =&gt; import(&#039;.\/user-page\/user-page.component&#039;)\n}];<\/code><\/pre>\n\n\n\n<p><code>CanMatch<\/code> r\u00f3\u017cni si\u0119 od <code>CanLoad<\/code> jeszcze jednym aspektem. W przypadku dopasowania do \u015bcie\u017cki zabezpieczonej zar\u00f3wno <code>CanLoad<\/code> jak i <code>CanActivate<\/code>, to programista odpowiedzialny jest za obs\u0142ug\u0119 redirect\u00f3w. Je\u015bli z <code>CanMatch<\/code> zwr\u00f3cone zostanie <code>false<\/code>, to Angular kontynuowa\u0142 b\u0119dzie iterowanie po tablicy zdefiniowanych route. Dzi\u0119ki temu w prosty spos\u00f3b mo\u017cemy pod tym samym urlem hostowa\u0107 stron\u0119 dla administratora i zwyk\u0142ego u\u017cytkownika, czy fallbackowa\u0107 do domy\u015blnej strony je\u015bli u\u017cytkownik nie ma dost\u0119pu do aktualnie requestowanej. <\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\">const routes: Route[] = [\n  {\n    path: &#039;\/me&#039;,\n    canMatch: [() =&gt; inject(UserService).isAdmin()],\n    loadComponent: () =&gt; import(&#039;.\/admin-page\/admin-page.component&#039;)\n  },\n  {\n    path: &#039;\/me&#039;,\n    canMatch: [() =&gt; inject(UserService).isLoggedIn()],\n    loadComponent: () =&gt; import(&#039;.\/user-page\/user-page.component&#039;)\n  },\n  {\n    path: &#039;**&#039;,\n    loadComponent: () =&gt; import(&#039;.\/not-logged-page\/not-logged-page.component&#039;)\n  }\n];<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><code>TestBed.runInInjectionContext<\/code><\/h3>\n\n\n\n<p>Funkcja <code>inject()<\/code>, to pot\u0119\u017cne narz\u0119dzie dodane w Angularze 14, kt\u00f3re mo\u017ce uczyni\u0107 nasz kod znacznie czytelniejszym. To dzi\u0119ki niej mo\u017clwie jest mi\u0119dzy innymi pisane functional guards takich jak ten poni\u017cej.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\">function onlyLoggedInGuard(): boolean {\n  return inject(UserService).isLoggedIn();\n}\n\nconst routes: Route[] = [{\n  path: &#039;\/me&#039;,\n  canMatch: [onlyLoggedInGuard],\n  loadComponent: () =&gt; import(&#039;.\/user-page\/user-page.component&#039;)\n}];<\/code><\/pre>\n\n\n\n<p>Do tej pory, aby przetestowa\u0107 guarda takiego jak ten powy\u017cej musieli\u015bmy odpowiednio wsztrzykn\u0105\u0107 do niego kontekst Dependency Injection. Tajemniczy <code>EnvironmentInjector<\/code> mocno psu\u0142 abstrakcj\u0119 <code>TestBed<\/code>, kt\u00f3ra pozwala\u0142a programistom zapomnie\u0107 o szczeg\u00f3\u0142ach implementacyjnych Dependency Injection.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-\">describe(&#039;onlyLoggedInGuard&#039;, () =&gt; {\n  \/* ... *\/\n  it(&#039;should not allow not logged in users&#039;, () =&gt; {\n    \/* ... *\/\n    expect(\n      TestBed.inject(EnvironmentInjector).runInContext(onlyLoggedInGuard)\n    ).toEqual(expectedValue);\n  })\n});<\/code><\/pre>\n\n\n\n<p>W Angulara 15.1 TestBed rozszerzony zosta\u0142 o <code>runInInjectionContext<\/code>, kt\u00f3ry troch\u0119 upraszcza powy\u017csz\u0105 konfiguracj\u0119.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\">describe(&#039;onlyLoggedInGuard&#039;, () =&gt; {\n  \/* ... *\/\n  it(&#039;should not allow not logged in users&#039;, () =&gt; {\n    \/* ... *\/\n    expect(\n      TestBed.runInInjectionContext(onlyLoggedInGuard)\n    ).toEqual(expectedValue);\n  })\n});<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><code>isStandalone()<\/code><\/h3>\n\n\n\n<p>Je\u015bli kiedykolwiek potrzebowali\u015bcie dowiedzie\u0107 si\u0119 z poziomu API czy dany komponent, piepe lub dyrektywa zosta\u0142a zdediniowana w tradycyjny spos\u00f3b z modu\u0142ami, czy te\u017c jako Standalone Componet, to od teraz b\u0119dzie to mo\u017cliwe. <\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\">@Component({\n  selector: &#039;app-standalone-component&#039;,\n  standalone: true\n})\nclass StandaloneComponent {}\n\n\/* ... *\/\nif(isStandalone(StandaloneComponent)) {\n  console.log(`StandaloneComponent is a standalone component`)\n}<\/code><\/pre>\n\n\n\n<p>Zastanawia\u0142em si\u0119 chwil\u0119, do czego m\u00f3g\u0142bym u\u017cy\u0107 nowego API, ale niestety nic nie przysz\u0142o mi do g\u0142owy. Je\u015bli Wy czekali\u015bcie na t\u0105 funkcjonalno\u015b\u0107 i macie dla niej jakie\u015b ciekawe zastosowanie, to koniecznie podzielcie si\u0119 nimi z nami na Twitterze.<\/p>\n\n\n\n<h2 id=\"2-state-of-js-2022\" data-num=2>2. State of JS 2022<\/h2>\n\n\n\n<p>State of JS to najwi\u0119ksza ankieta dotycz\u0105ca JavaScript. W minionym tygodniu opublikowane zosta\u0142y jej wyniki. Jak co roku, ka\u017cdemu polecam zapoznanie si\u0119 z nimi samodzielnie, a ja poni\u017cej dziel\u0119 si\u0119 kilkoma moimi spostrze\u017ceniami:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"350\" height=\"149\" src=\"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/giphy-33-1.gif\" alt=\"\" class=\"wp-image-13746\"\/><figcaption class=\"wp-element-caption\">Tak si\u0119 czuj\u0119 w tym momencie &#8211; autor<\/figcaption><\/figure><\/div>\n\n\n<ul class=\"wp-block-list\">\n<li>70% respondent\u00f3w to m\u0119\u017cczy\u017ani i tylko 2.4% respondendt\u00f3w to kobiety. Mam nadziej\u0119, \u017ce tajemnica tej dysproporcji kryje si\u0119 w opcji <code>Brak odpowiedzi<\/code>, kt\u00f3r\u0105 zaznaczy\u0142o a\u017c 24% respondent\u00f3w. Je\u015bli nie, to mamy spory problem&#8230;<\/li>\n\n\n\n<li>W\u015br\u00f3d frontendowych framework\u00f3w pod wzgl\u0119dem satysfakcji nowym kr\u00f3lem jest Solid. Poprzedni kr\u00f3l w postaci Svelte wci\u0105\u017c depcze mu jednak po plecach, bo r\u00f3\u017cnica wynosi zaledwie jeden punkt procentowy (90,9% vs 89,7%). Najwy\u017cszy czas, \u017ceby frameworki te w ko\u0144cu zacz\u0119\u0142y skraca\u0107 dystans w stosunku do wielkiej tr\u00f3jki.<\/li>\n\n\n\n<li>W\u015br\u00f3d frontendowych framework\u00f3w pod wzgl\u0119dem wykorzystania bez zmian &#8211; wci\u0105\u017c kr\u00f3luje wielka tr\u00f3jka (React, Angular i Vue). Warto jednak zauwa\u017cy\u0107, \u017ce Angular i Vue zaliczy\u0142y spadki o kilka punkt\u00f3w procentowych. W przypadku tego pierwszego, moze to by\u0107 spowodowane niskimi wynikami je\u015bli chodzi o satysfakcj\u0119. W przypadku tego drugiego, g\u0142ownego sprawcy doszukiwa\u0142bym si\u0119 w Vue 3, kt\u00f3re wprowadzi\u0142 sporo breaking changes i tym samym da\u0142o deweloperom \u015bwietny pretekst do migracji. <\/li>\n\n\n\n<li>Astro wbi\u0142o sie na pierwsze miejsce pod wzgl\u0119dem satysfakcji z framework\u00f3w do rendrowania po stronie serwera. To kolejny artgument za tym, \u017ceby\u015bcie zainteresowali si\u0119 tym frameworkiem i koncpecj\u0105 Dynamic Islands.<\/li>\n\n\n\n<li>Spadek zar\u00f3wno satysfakcji jak i wykorzystania webpacka mo\u017ce sugerowa\u0107, \u017ce technologia ta powoli zaczyna ust\u0119powa\u0107 ju\u017c miejsca m\u0142odszej technologii. Natomiast wynik 98% satysfakcji z Vite robi piorunuj\u0105ce wra\u017cenie i pozwala wnioskowa\u0107 kto zajmie miejsce wys\u0142u\u017conego webpacka.<\/li>\n\n\n\n<li> Tylko 27% respondent\u00f3w po\u015bwi\u0119ca wi\u0119cej swojego czasu na pisanie w JavaScript ni\u017c w TypeScript i tylko 11% respondent\u00f3 nie korzysta z TypeScript wcale. <\/li>\n\n\n\n<li><\/li>\n<\/ul>\n\n\n\n<p class=\"has-text-align-center\"><a href=\"https:\/\/2022.stateofjs.com\/en-US\/\" target=\"_blank\" rel=\"noreferrer noopener\">State of JS 2022<\/a><\/p>\n\n\n\n<h2 id=\"3-javascript-raising-stars\" data-num=3>3. JavaScript Raising Stars<\/h2>\n\n\n\n<p>Po przeczytaniu State of JS 2022 wci\u0105\u017c ma\u0142o Wam statystyk i podsumowa\u0144? W minionym tygodniu opublikowany zosta\u0142 r\u00f3wnie\u017c raport 2022 JavaScript Rising Stars, kt\u00f3ry zestawia ze sob\u0105 przyrost GitHubowych gwiazdek r\u00f3\u017cnych narz\u0119dzi zwi\u0105zanych z JavaScript. D\u0142ugo mo\u017cnaby dystkutowa\u0107, czy gwiazdki na GithHubie s\u0105 dobrym \u017ar\u00f3d\u0142em danych o popularno\u015bci bibliotek, ale w raporcie na pewno natraficie na kilka ciekawych narz\u0119dzi, kt\u00f3re uciek\u0142y poza Waszymi radarami. Dodatkowo ka\u017cda sekcja okraszona komentarzem ekspert\u00f3w, kt\u00f3rzy zazwyczaj maj\u0105 szerszy pogl\u0105d na ca\u0142\u0105 sytuacj\u0119. <\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"480\" height=\"360\" src=\"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/giphy-31-1.gif\" alt=\"\" class=\"wp-image-13748\"\/><\/figure><\/div>\n\n\n<p class=\"has-text-align-center\"><a href=\"https:\/\/risingstars.js.org\/2022\/en\" target=\"_blank\" rel=\"noreferrer noopener\">2022 JavaScript Rising Stars<\/a><\/p>\n\n\n\n<p>Dla wszystkich, kt\u00f3rzy nie maj\u0105 czasu, si\u0142y lub ochoty na przeczytanie raportu, uchyl\u0119 tajemnicy. W tym roku zestawienie zosta\u0142o zdominowane przez Bun &#8211; szybsz\u0105 alternatyw\u0119 typu drop-in dla Node.js i Deno &#8211; kt\u00f3ra mia\u0142a premier\u0119 w po\u0142owie tego roku. Zesp\u00f3\u0142 rozwijaj\u0105cy to \u015brodowisko uruchomieniowe zebra\u0142 ju\u017c 7M$ na jego dalszy rozw\u00f3j, tak\u017ce naprawd\u0119 warto obserwowa\u0107, co b\u0119dzie dzia\u0142o si\u0119 z nim w przysz\u0142o\u015bci.<\/p>\n\n\n\n<h2 id=\"bonus-javascript-wrapped-2022\" data-num=4>Bonus: JavaScript Wrapped 2022<\/h2>\n\n\n\n<p>Je\u015bli jakim\u015b cudem jeszcze nie do\u015b\u0107 Wam podsumowa\u0144, to w minionym tygodniu pope\u0142ni\u0142em ca\u0142kiem obszerne podsumowanie minionego roku z perspektywy redaktora Frontend Weekly. Je\u015bli jeszcze go nie czytali\u015bcie, a chcieliby\u015bcie przekona\u0107 si\u0119 co mog\u0142o Was omin\u0105\u0107 w 2022 roku, to gor\u0105co zapraszam do lektury.<\/p>\n\n\n\n<figure class=\"wp-block-embed aligncenter is-type-wp-embed is-provider-vived wp-block-embed-vived\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"EdpNtdVnJh\"><a href=\"https:\/\/vived.io\/pl\/frontend-weekly-vol-119\/\">JavaScript Wrapped 2022 | Frontend Weekly vol. 119<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; clip: rect(1px, 1px, 1px, 1px);\" title=\"&#8222;JavaScript Wrapped 2022 | Frontend Weekly vol. 119&#8221; &#8212; Vived\" src=\"https:\/\/vived.io\/pl\/frontend-weekly-vol-119\/embed\/#?secret=eOZ6iRkQdQ#?secret=EdpNtdVnJh\" data-secret=\"EdpNtdVnJh\" width=\"500\" height=\"282\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>W minionym tygodniu wydany zosta\u0142 Angular 15.1. Wraz z nim do Angulara trafi\u0142y od dawna wyczekiwane Self Closing Tags. To jednak nie koniec nowo\u015bci. <\/p>\n","protected":false},"author":12,"featured_media":13784,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[273,1],"tags":[],"class_list":["post-13696","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-frontend-pl","category-no-category"],"acf":{"feature_image_visible":false,"weekly_summary":true,"push_notification_image":"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/frontend-120en.png","feature_image_blog":{"ID":13752,"id":13752,"title":"pexels-kevin-ku-577585","filename":"pexels-kevin-ku-577585.jpg","filesize":174156,"url":"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/pexels-kevin-ku-577585.jpg","link":"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/pexels-kevin-ku-577585\/","alt":"","author":"12","description":"","caption":"","name":"pexels-kevin-ku-577585","status":"inherit","uploaded_to":13696,"date":"2023-01-12 14:03:41","modified":"2023-01-12 14:03:41","menu_order":0,"mime_type":"image\/jpeg","type":"image","subtype":"jpeg","icon":"https:\/\/vived.io\/wp-includes\/images\/media\/default.png","width":1280,"height":960,"sizes":{"thumbnail":"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/pexels-kevin-ku-577585-150x150.jpg","thumbnail-width":150,"thumbnail-height":150,"medium":"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/pexels-kevin-ku-577585-300x225.jpg","medium-width":300,"medium-height":225,"medium_large":"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/pexels-kevin-ku-577585-768x576.jpg","medium_large-width":768,"medium_large-height":576,"large":"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/pexels-kevin-ku-577585-1024x768.jpg","large-width":1024,"large-height":768,"1536x1536":"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/pexels-kevin-ku-577585.jpg","1536x1536-width":1280,"1536x1536-height":960,"2048x2048":"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/pexels-kevin-ku-577585.jpg","2048x2048-width":1280,"2048x2048-height":960,"gform-image-choice-sm":"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/pexels-kevin-ku-577585.jpg","gform-image-choice-sm-width":300,"gform-image-choice-sm-height":225,"gform-image-choice-md":"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/pexels-kevin-ku-577585.jpg","gform-image-choice-md-width":400,"gform-image-choice-md-height":300,"gform-image-choice-lg":"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/pexels-kevin-ku-577585.jpg","gform-image-choice-lg-width":600,"gform-image-choice-lg-height":450}},"estimated_reading_time":"8"},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Co takiego dostarczy\u0142 nam Angular 15.1? | Frontend Weekly vol. 120 - Vived<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/\" \/>\n<meta property=\"og:locale\" content=\"pl_PL\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Co takiego dostarczy\u0142 nam Angular 15.1? | Frontend Weekly vol. 120 - Vived\" \/>\n<meta property=\"og:description\" content=\"W minionym tygodniu wydany zosta\u0142 Angular 15.1. Wraz z nim do Angulara trafi\u0142y od dawna wyczekiwane Self Closing Tags. To jednak nie koniec nowo\u015bci.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/\" \/>\n<meta property=\"og:site_name\" content=\"Vived\" \/>\n<meta property=\"article:published_time\" content=\"2023-01-12T19:24:08+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-01-14T09:36:31+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/frontend-120en.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"628\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Tomasz Borowicz\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/\"},\"author\":{\"name\":\"Tomasz Borowicz\",\"@id\":\"https:\/\/vived.io\/pl\/#\/schema\/person\/9d2a72fe7d0dfbb4092675afbab742bb\"},\"headline\":\"Co takiego dostarczy\u0142 nam Angular 15.1? | Frontend Weekly vol. 120\",\"datePublished\":\"2023-01-12T19:24:08+00:00\",\"dateModified\":\"2023-01-14T09:36:31+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/\"},\"wordCount\":1292,\"publisher\":{\"@id\":\"https:\/\/vived.io\/pl\/#organization\"},\"image\":{\"@id\":\"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/frontend-120en.png\",\"articleSection\":[\"Frontend\",\"No category\"],\"inLanguage\":\"pl-PL\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/\",\"url\":\"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/\",\"name\":\"Co takiego dostarczy\u0142 nam Angular 15.1? | Frontend Weekly vol. 120 - Vived\",\"isPartOf\":{\"@id\":\"https:\/\/vived.io\/pl\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/frontend-120en.png\",\"datePublished\":\"2023-01-12T19:24:08+00:00\",\"dateModified\":\"2023-01-14T09:36:31+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/#breadcrumb\"},\"inLanguage\":\"pl-PL\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pl-PL\",\"@id\":\"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/#primaryimage\",\"url\":\"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/frontend-120en.png\",\"contentUrl\":\"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/frontend-120en.png\",\"width\":1200,\"height\":628},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Strona g\u0142\u00f3wna\",\"item\":\"https:\/\/vived.io\/pl\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Co takiego dostarczy\u0142 nam Angular 15.1? | Frontend Weekly vol. 120\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/vived.io\/pl\/#website\",\"url\":\"https:\/\/vived.io\/pl\/\",\"name\":\"Vived\",\"description\":\"platform empowering IT people and technology companies to synergic growth\",\"publisher\":{\"@id\":\"https:\/\/vived.io\/pl\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/vived.io\/pl\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pl-PL\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/vived.io\/pl\/#organization\",\"name\":\"Vived\",\"url\":\"https:\/\/vived.io\/pl\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pl-PL\",\"@id\":\"https:\/\/vived.io\/pl\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/vived.io\/wp-content\/uploads\/2020\/03\/logo_vived_color.png\",\"contentUrl\":\"https:\/\/vived.io\/wp-content\/uploads\/2020\/03\/logo_vived_color.png\",\"width\":136,\"height\":45,\"caption\":\"Vived\"},\"image\":{\"@id\":\"https:\/\/vived.io\/pl\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/vived.io\/pl\/#\/schema\/person\/9d2a72fe7d0dfbb4092675afbab742bb\",\"name\":\"Tomasz Borowicz\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pl-PL\",\"@id\":\"https:\/\/vived.io\/pl\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/804536d2672538508d43f60ad2108e5aaea76c192653eaf95d4c3934b7d1dbb6?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/804536d2672538508d43f60ad2108e5aaea76c192653eaf95d4c3934b7d1dbb6?s=96&d=mm&r=g\",\"caption\":\"Tomasz Borowicz\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Co takiego dostarczy\u0142 nam Angular 15.1? | Frontend Weekly vol. 120 - Vived","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/","og_locale":"pl_PL","og_type":"article","og_title":"Co takiego dostarczy\u0142 nam Angular 15.1? | Frontend Weekly vol. 120 - Vived","og_description":"W minionym tygodniu wydany zosta\u0142 Angular 15.1. Wraz z nim do Angulara trafi\u0142y od dawna wyczekiwane Self Closing Tags. To jednak nie koniec nowo\u015bci.","og_url":"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/","og_site_name":"Vived","article_published_time":"2023-01-12T19:24:08+00:00","article_modified_time":"2023-01-14T09:36:31+00:00","og_image":[{"width":1200,"height":628,"url":"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/frontend-120en.png","type":"image\/png"}],"author":"Tomasz Borowicz","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/#article","isPartOf":{"@id":"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/"},"author":{"name":"Tomasz Borowicz","@id":"https:\/\/vived.io\/pl\/#\/schema\/person\/9d2a72fe7d0dfbb4092675afbab742bb"},"headline":"Co takiego dostarczy\u0142 nam Angular 15.1? | Frontend Weekly vol. 120","datePublished":"2023-01-12T19:24:08+00:00","dateModified":"2023-01-14T09:36:31+00:00","mainEntityOfPage":{"@id":"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/"},"wordCount":1292,"publisher":{"@id":"https:\/\/vived.io\/pl\/#organization"},"image":{"@id":"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/#primaryimage"},"thumbnailUrl":"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/frontend-120en.png","articleSection":["Frontend","No category"],"inLanguage":"pl-PL"},{"@type":"WebPage","@id":"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/","url":"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/","name":"Co takiego dostarczy\u0142 nam Angular 15.1? | Frontend Weekly vol. 120 - Vived","isPartOf":{"@id":"https:\/\/vived.io\/pl\/#website"},"primaryImageOfPage":{"@id":"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/#primaryimage"},"image":{"@id":"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/#primaryimage"},"thumbnailUrl":"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/frontend-120en.png","datePublished":"2023-01-12T19:24:08+00:00","dateModified":"2023-01-14T09:36:31+00:00","breadcrumb":{"@id":"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/#breadcrumb"},"inLanguage":"pl-PL","potentialAction":[{"@type":"ReadAction","target":["https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/"]}]},{"@type":"ImageObject","inLanguage":"pl-PL","@id":"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/#primaryimage","url":"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/frontend-120en.png","contentUrl":"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/frontend-120en.png","width":1200,"height":628},{"@type":"BreadcrumbList","@id":"https:\/\/vived.io\/pl\/co-takiego-dostarczyl-nam-angular-15-1-frontend-weekly-vol-120\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Strona g\u0142\u00f3wna","item":"https:\/\/vived.io\/pl\/"},{"@type":"ListItem","position":2,"name":"Co takiego dostarczy\u0142 nam Angular 15.1? | Frontend Weekly vol. 120"}]},{"@type":"WebSite","@id":"https:\/\/vived.io\/pl\/#website","url":"https:\/\/vived.io\/pl\/","name":"Vived","description":"platform empowering IT people and technology companies to synergic growth","publisher":{"@id":"https:\/\/vived.io\/pl\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/vived.io\/pl\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pl-PL"},{"@type":"Organization","@id":"https:\/\/vived.io\/pl\/#organization","name":"Vived","url":"https:\/\/vived.io\/pl\/","logo":{"@type":"ImageObject","inLanguage":"pl-PL","@id":"https:\/\/vived.io\/pl\/#\/schema\/logo\/image\/","url":"https:\/\/vived.io\/wp-content\/uploads\/2020\/03\/logo_vived_color.png","contentUrl":"https:\/\/vived.io\/wp-content\/uploads\/2020\/03\/logo_vived_color.png","width":136,"height":45,"caption":"Vived"},"image":{"@id":"https:\/\/vived.io\/pl\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/vived.io\/pl\/#\/schema\/person\/9d2a72fe7d0dfbb4092675afbab742bb","name":"Tomasz Borowicz","image":{"@type":"ImageObject","inLanguage":"pl-PL","@id":"https:\/\/vived.io\/pl\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/804536d2672538508d43f60ad2108e5aaea76c192653eaf95d4c3934b7d1dbb6?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/804536d2672538508d43f60ad2108e5aaea76c192653eaf95d4c3934b7d1dbb6?s=96&d=mm&r=g","caption":"Tomasz Borowicz"}}]}},"blocks_vived":[{"blockName":"core\/heading","attrs":[],"innerBlocks":[],"innerHTML":"\n<h2>1. Angular 15.1<\/h2>\n","innerContent":["\n<h2>1. Angular 15.1<\/h2>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>W minionym tygodniu wydany zosta\u0142 Angular 15.1. Wi\u0119kszo\u015b\u0107 zmian i nowo\u015bci dotyczy funkcjonalno\u015bci, kt\u00f3re dodane zosta\u0142y w Anuglarze 14 i 15. Bez zb\u0119dnego przed\u0142u\u017cania przejd\u017amy do rzeczy.<\/p>\n","innerContent":["\n<p>W minionym tygodniu wydany zosta\u0142 Angular 15.1. Wi\u0119kszo\u015b\u0107 zmian i nowo\u015bci dotyczy funkcjonalno\u015bci, kt\u00f3re dodane zosta\u0142y w Anuglarze 14 i 15. Bez zb\u0119dnego przed\u0142u\u017cania przejd\u017amy do rzeczy.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/heading","attrs":{"level":3},"innerBlocks":[],"innerHTML":"\n<h3>Self Closing Tags<\/h3>\n","innerContent":["\n<h3>Self Closing Tags<\/h3>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Frameworki takie jak Vue czy React, traktuj\u0105 komponenty jako czysto abstrakcyjne byty mapowane do struktury DOM. Je\u015bli zobaczycie sobie plik HTML wygenerowany przez jeden z tych framework\u00f3w, to nie znajdziecie tam w\u0142a\u015bciwie \u017cadnego \u015bladu po abstrakcji jak\u0105 s\u0105 kompoenenty. Angular podchodzi do tematu zupe\u0142nie inaczej i ka\u017cdemu komponentowi przypisuje Custom HTML Tag. Dzi\u0119ki temu kiedy spojrzycie na stron\u0119 wygenerowan\u0105 przez Angulara, od razu b\u0119dziecie w stanie powi\u0105za\u0107 odpowiednie fragmenty HTML z komponentami.<\/p>\n","innerContent":["\n<p>Frameworki takie jak Vue czy React, traktuj\u0105 komponenty jako czysto abstrakcyjne byty mapowane do struktury DOM. Je\u015bli zobaczycie sobie plik HTML wygenerowany przez jeden z tych framework\u00f3w, to nie znajdziecie tam w\u0142a\u015bciwie \u017cadnego \u015bladu po abstrakcji jak\u0105 s\u0105 kompoenenty. Angular podchodzi do tematu zupe\u0142nie inaczej i ka\u017cdemu komponentowi przypisuje Custom HTML Tag. Dzi\u0119ki temu kiedy spojrzycie na stron\u0119 wygenerowan\u0105 przez Angulara, od razu b\u0119dziecie w stanie powi\u0105za\u0107 odpowiednie fragmenty HTML z komponentami.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"prismatic\/blocks","attrs":{"language":"xml"},"innerBlocks":[],"innerHTML":"\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-xml\">&lt;!-- The HTML code of a simple application rendered by Angular -->\n&lt;!-- You can clearly see how source code is devided into components -->\n&lt;!DOCTYPE html>\n&lt;html lang=\"en\">\n  &lt;head>\n    &lt;meta charset=\"utf-8\">\n    &lt;title>Simple App&lt;\/title>\n    &lt;script src=\"script.js\">&lt;\/script>\n  &lt;\/head>\n  &lt;body>\n    &lt;app-root>\n      &lt;h1>Welcome to my application!&lt;\/h1>\n      &lt;app-navigation-link>\n        &lt;a href=\"\/home\">Home&lt;\/a>\n      &lt;app-navigation-link>\n      &lt;app-navigation-link>\n        &lt;a href=\"\/about\">About&lt;\/a>\n      &lt;app-navigation-link>\n    &lt;app-root>\n  &lt;\/body>\n&lt;\/html><\/code><\/pre>\n","innerContent":["\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-xml\">&lt;!-- The HTML code of a simple application rendered by Angular -->\n&lt;!-- You can clearly see how source code is devided into components -->\n&lt;!DOCTYPE html>\n&lt;html lang=\"en\">\n  &lt;head>\n    &lt;meta charset=\"utf-8\">\n    &lt;title>Simple App&lt;\/title>\n    &lt;script src=\"script.js\">&lt;\/script>\n  &lt;\/head>\n  &lt;body>\n    &lt;app-root>\n      &lt;h1>Welcome to my application!&lt;\/h1>\n      &lt;app-navigation-link>\n        &lt;a href=\"\/home\">Home&lt;\/a>\n      &lt;app-navigation-link>\n      &lt;app-navigation-link>\n        &lt;a href=\"\/about\">About&lt;\/a>\n      &lt;app-navigation-link>\n    &lt;app-root>\n  &lt;\/body>\n&lt;\/html><\/code><\/pre>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"prismatic\/blocks","attrs":{"language":"xml"},"innerBlocks":[],"innerHTML":"\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-xml\">&lt;!-- The same application as above but this time rendered with react -->\n&lt;!-- It's really hard to say source how code have been devided into componets -->\n&lt;!DOCTYPE html>\n&lt;html lang=\"en\">\n  &lt;head>\n    &lt;meta charset=\"utf-8\">\n    &lt;title>Simple App&lt;\/title>\n    &lt;script src=\"script.js\">&lt;\/script>\n  &lt;\/head>\n  &lt;body>\n    &lt;div>\n      &lt;h1>Welcome to my application!&lt;\/h1>\n      &lt;a href=\"\/home\">Home&lt;\/a>\n      &lt;a href=\"\/about\">About&lt;\/a>\n    &lt;div>\n  &lt;\/body>\n&lt;\/html>\n<\/code><\/pre>\n","innerContent":["\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-xml\">&lt;!-- The same application as above but this time rendered with react -->\n&lt;!-- It's really hard to say source how code have been devided into componets -->\n&lt;!DOCTYPE html>\n&lt;html lang=\"en\">\n  &lt;head>\n    &lt;meta charset=\"utf-8\">\n    &lt;title>Simple App&lt;\/title>\n    &lt;script src=\"script.js\">&lt;\/script>\n  &lt;\/head>\n  &lt;body>\n    &lt;div>\n      &lt;h1>Welcome to my application!&lt;\/h1>\n      &lt;a href=\"\/home\">Home&lt;\/a>\n      &lt;a href=\"\/about\">About&lt;\/a>\n    &lt;div>\n  &lt;\/body>\n&lt;\/html>\n<\/code><\/pre>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Specyfikacja Custom HTML Tag zak\u0142ada kilka ogranicze\u0144. Mi\u0119dzy innymi nazwa tagu musi zawiera\u0107 znak <code>-<\/code>. To w\u0142a\u015bnie dlatego Angular domy\u015blnie do selektor\u00f3w dodaje prefix <code>app<\/code>. Ograniczenie to nie wi\u0119\u0142o si\u0119 znik\u0105d - przestrze\u0144 nazw nie zawieraj\u0105cych <code>-<\/code> zarezewowana jest dla przysz\u0142ego wykorzystania w standardzie HTML.<\/p>\n","innerContent":["\n<p>Specyfikacja Custom HTML Tag zak\u0142ada kilka ogranicze\u0144. Mi\u0119dzy innymi nazwa tagu musi zawiera\u0107 znak <code>-<\/code>. To w\u0142a\u015bnie dlatego Angular domy\u015blnie do selektor\u00f3w dodaje prefix <code>app<\/code>. Ograniczenie to nie wi\u0119\u0142o si\u0119 znik\u0105d - przestrze\u0144 nazw nie zawieraj\u0105cych <code>-<\/code> zarezewowana jest dla przysz\u0142ego wykorzystania w standardzie HTML.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Wed\u0142ug standardu HTML, tylko wybrane tagi mog\u0105 zamyka\u0107 same siebie. Ich lista jest stosunkowo kr\u00f3tka i zawiera takie elementy jak <code>&lt;link \/&gt;<\/code>, <code>&lt;br \/&gt;<\/code>  czy  <code>&lt;img \/&gt;<\/code> (pe\u0142n\u0105 list\u0119 mo\u017cecie znale\u017a\u0107 mi\u0119dzy innymi <a href=\"http:\/\/xahlee.info\/js\/html5_non-closing_tag.html\" target=\"_blank\" rel=\"noreferrer noopener\">tutaj<\/a>). Niestety na li\u015bcie tej na pr\u00f3\u017cno szuka\u0107 Custom HTML Tags. Oznacza to, \u017ce je\u015bli chcemy pozosta\u0107 zgodni ze standardem HTML, to skazani jeste\u015bmy na r\u0119czne zamykanie Custom HTML Tags. Chc\u0105c pozosta\u0107 w zgodzie ze standarderm, Angular musia\u0142 pozosta\u0107 za konkurencj\u0105, kt\u00f3ra od dawna umo\u017cliwia\u0142 takie praktyki (m.in. JSX'a i <code>&lt;App \/&gt;<\/code>).<\/p>\n","innerContent":["\n<p>Wed\u0142ug standardu HTML, tylko wybrane tagi mog\u0105 zamyka\u0107 same siebie. Ich lista jest stosunkowo kr\u00f3tka i zawiera takie elementy jak <code>&lt;link \/&gt;<\/code>, <code>&lt;br \/&gt;<\/code>  czy  <code>&lt;img \/&gt;<\/code> (pe\u0142n\u0105 list\u0119 mo\u017cecie znale\u017a\u0107 mi\u0119dzy innymi <a href=\"http:\/\/xahlee.info\/js\/html5_non-closing_tag.html\" target=\"_blank\" rel=\"noreferrer noopener\">tutaj<\/a>). Niestety na li\u015bcie tej na pr\u00f3\u017cno szuka\u0107 Custom HTML Tags. Oznacza to, \u017ce je\u015bli chcemy pozosta\u0107 zgodni ze standardem HTML, to skazani jeste\u015bmy na r\u0119czne zamykanie Custom HTML Tags. Chc\u0105c pozosta\u0107 w zgodzie ze standarderm, Angular musia\u0142 pozosta\u0107 za konkurencj\u0105, kt\u00f3ra od dawna umo\u017cliwia\u0142 takie praktyki (m.in. JSX'a i <code>&lt;App \/&gt;<\/code>).<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"prismatic\/blocks","attrs":{"language":"xml"},"innerBlocks":[],"innerHTML":"\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-xml\">&lt;!-- Below declarations are incorrect -->\n&lt;div \/>                    &lt;!-- \u274c div is not a self closing tag -->\n&lt;approot>&lt;\/approot>        &lt;!-- \u274c custom tags must contain - -->\n&lt;app-root \/>               &lt;!-- \u274c custom tags are not self closing -->\n\n&lt;!-- Below declarations are correct -->\n&lt;div>&lt;\/div                 &lt;!-- \u2705 this is correct syntax -->\n&lt;app-root>&lt;\/app-root>      &lt;!-- \u2705 this is correct syntax --><\/code><\/pre>\n","innerContent":["\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-xml\">&lt;!-- Below declarations are incorrect -->\n&lt;div \/>                    &lt;!-- \u274c div is not a self closing tag -->\n&lt;approot>&lt;\/approot>        &lt;!-- \u274c custom tags must contain - -->\n&lt;app-root \/>               &lt;!-- \u274c custom tags are not self closing -->\n\n&lt;!-- Below declarations are correct -->\n&lt;div>&lt;\/div                 &lt;!-- \u2705 this is correct syntax -->\n&lt;app-root>&lt;\/app-root>      &lt;!-- \u2705 this is correct syntax --><\/code><\/pre>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>W Angularze 15.1 deweloperom uda\u0142o si\u0119 w ko\u0144cu znale\u017a\u0107 panaceum na zaistnia\u0142y problem. Pisane przez nas templates nie trafiaj\u0105 w ko\u0144cu bezpo\u015brednio do u\u017cytkownika, ale s\u0105  jeszcze transpilowane (jak inaczej mog\u0142oby dzia\u0142a\u0107 <code>*ngFor<\/code>, <code>*ngIf<\/code> czy <code>&lt;ng-template&gt;<\/code>). To w\u0142a\u015bnie podczas tej transpilacji Angular podmienia\u0142 b\u0119dzie samo zamykaj\u0105ce si\u0119 tagi do formatu zgodnego ze standardem. W ten spos\u00f3b, pomimo \u017ce pisane przez nas templates nie b\u0119d\u0105 zgodne ze standardem, to HTML wysy\u0142any do klienta ju\u017c jak najbardziej.<\/p>\n","innerContent":["\n<p>W Angularze 15.1 deweloperom uda\u0142o si\u0119 w ko\u0144cu znale\u017a\u0107 panaceum na zaistnia\u0142y problem. Pisane przez nas templates nie trafiaj\u0105 w ko\u0144cu bezpo\u015brednio do u\u017cytkownika, ale s\u0105  jeszcze transpilowane (jak inaczej mog\u0142oby dzia\u0142a\u0107 <code>*ngFor<\/code>, <code>*ngIf<\/code> czy <code>&lt;ng-template&gt;<\/code>). To w\u0142a\u015bnie podczas tej transpilacji Angular podmienia\u0142 b\u0119dzie samo zamykaj\u0105ce si\u0119 tagi do formatu zgodnego ze standardem. W ten spos\u00f3b, pomimo \u017ce pisane przez nas templates nie b\u0119d\u0105 zgodne ze standardem, to HTML wysy\u0142any do klienta ju\u017c jak najbardziej.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"prismatic\/blocks","attrs":{"language":"xml"},"innerBlocks":[],"innerHTML":"\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-xml\">&lt;!-- Angular 15.0 -->\n&lt;app-button\n  text=\"Click me!\"\n  variant=\"filled\"\n  (onClick)=\"handleClick($event)\"\n>&lt;\/app-button>\n&lt;app-button\n  text=\"Don't click me!\"\n  variant=\"outline\"\n  (onClick)=\"handleClick($event)\"\n>&lt;\/app-button>\n\n&lt;!-- Angular 15.1 -->\n&lt;app-button text=\"Click me!\" variant=\"filled\" (onClick)=\"handleClick($event)\" \/>\n&lt;app-button text=\"Don't click me!\" variant=\"outline\" (onClick)=\"handleClick($event)\" \/><\/code><\/pre>\n","innerContent":["\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-xml\">&lt;!-- Angular 15.0 -->\n&lt;app-button\n  text=\"Click me!\"\n  variant=\"filled\"\n  (onClick)=\"handleClick($event)\"\n>&lt;\/app-button>\n&lt;app-button\n  text=\"Don't click me!\"\n  variant=\"outline\"\n  (onClick)=\"handleClick($event)\"\n>&lt;\/app-button>\n\n&lt;!-- Angular 15.1 -->\n&lt;app-button text=\"Click me!\" variant=\"filled\" (onClick)=\"handleClick($event)\" \/>\n&lt;app-button text=\"Don't click me!\" variant=\"outline\" (onClick)=\"handleClick($event)\" \/><\/code><\/pre>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/heading","attrs":{"level":3},"innerBlocks":[],"innerHTML":"\n<h3>Deprekacja <code>CanLoad<\/code> na rzecz <code>CanMatch<\/code><\/h3>\n","innerContent":["\n<h3>Deprekacja <code>CanLoad<\/code> na rzecz <code>CanMatch<\/code><\/h3>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Przed Angularem 15 do dyspozycji deweloper\u00f3w by\u0142y dwa guardy <code>CanLoad<\/code> i <code>CanActivate<\/code>. W przypadku zastosowania lazy-loadingu <code>CanLoad<\/code> decydowa\u0142 czy dany fragment kodu mo\u017ce zosta\u0107 za\u0142adowany przez przegl\u0105dark\u0119. Je\u015bli kod zosta\u0142 ju\u017c raz za\u0142adowany, to Guard ten nie jest uruchamiany ponownie. Z tego wzgl\u0119du, je\u015bli chcemy ograniczy\u0107 dost\u0119p do danej strony (na przyk\u0142ad dla nie zalogowanych u\u017cytkownik\u00f3w), to musimy dodatkowo zabzpieczy\u0107 go dodatkow <code>CanActivate<\/code>.<\/p>\n","innerContent":["\n<p>Przed Angularem 15 do dyspozycji deweloper\u00f3w by\u0142y dwa guardy <code>CanLoad<\/code> i <code>CanActivate<\/code>. W przypadku zastosowania lazy-loadingu <code>CanLoad<\/code> decydowa\u0142 czy dany fragment kodu mo\u017ce zosta\u0107 za\u0142adowany przez przegl\u0105dark\u0119. Je\u015bli kod zosta\u0142 ju\u017c raz za\u0142adowany, to Guard ten nie jest uruchamiany ponownie. Z tego wzgl\u0119du, je\u015bli chcemy ograniczy\u0107 dost\u0119p do danej strony (na przyk\u0142ad dla nie zalogowanych u\u017cytkownik\u00f3w), to musimy dodatkowo zabzpieczy\u0107 go dodatkow <code>CanActivate<\/code>.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"prismatic\/blocks","attrs":{"language":"typescript"},"innerBlocks":[],"innerHTML":"\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\">const routes: Route[] = [{\n  path: '\/me',\n  canLoad: [() => inject(UserService).isLoggedIn()],\n  canActivate: [() => inject(UserService).isLoggedIn()],\n  loadComponent: () => import('.\/user-page\/user-page.component')\n}];<\/code><\/pre>\n","innerContent":["\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\">const routes: Route[] = [{\n  path: '\/me',\n  canLoad: [() => inject(UserService).isLoggedIn()],\n  canActivate: [() => inject(UserService).isLoggedIn()],\n  loadComponent: () => import('.\/user-page\/user-page.component')\n}];<\/code><\/pre>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Do Angulara 15 trafi\u0142 nowy Guard <code>CanMatch<\/code>, kt\u00f3ry wywo\u0142ywany jest przy ka\u017cdej pr\u00f3bie dopsowania \u015bcie\u017cki niezale\u017cnie od tego czy kod danego modu\u0142u zosta\u0142 ju\u017c za\u0142adowany. Dzi\u0119ki temu podw\u00f3jn\u0105 definicj\u0119 <code>CanLoad<\/code> i <code>CanActivate<\/code> zast\u0105pi\u0107 mo\u017cemy jednym zgrabnym <code>CanMatch<\/code>. <\/p>\n","innerContent":["\n<p>Do Angulara 15 trafi\u0142 nowy Guard <code>CanMatch<\/code>, kt\u00f3ry wywo\u0142ywany jest przy ka\u017cdej pr\u00f3bie dopsowania \u015bcie\u017cki niezale\u017cnie od tego czy kod danego modu\u0142u zosta\u0142 ju\u017c za\u0142adowany. Dzi\u0119ki temu podw\u00f3jn\u0105 definicj\u0119 <code>CanLoad<\/code> i <code>CanActivate<\/code> zast\u0105pi\u0107 mo\u017cemy jednym zgrabnym <code>CanMatch<\/code>. <\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"prismatic\/blocks","attrs":{"language":"typescript"},"innerBlocks":[],"innerHTML":"\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\">const routes: Route[] = [{\n  path: '\/me',\n  canMatch: [() => inject(UserService).isLoggedIn()],\n  loadComponent: () => import('.\/user-page\/user-page.component')\n}];<\/code><\/pre>\n","innerContent":["\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\">const routes: Route[] = [{\n  path: '\/me',\n  canMatch: [() => inject(UserService).isLoggedIn()],\n  loadComponent: () => import('.\/user-page\/user-page.component')\n}];<\/code><\/pre>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p><code>CanMatch<\/code> r\u00f3\u017cni si\u0119 od <code>CanLoad<\/code> jeszcze jednym aspektem. W przypadku dopasowania do \u015bcie\u017cki zabezpieczonej zar\u00f3wno <code>CanLoad<\/code> jak i <code>CanActivate<\/code>, to programista odpowiedzialny jest za obs\u0142ug\u0119 redirect\u00f3w. Je\u015bli z <code>CanMatch<\/code> zwr\u00f3cone zostanie <code>false<\/code>, to Angular kontynuowa\u0142 b\u0119dzie iterowanie po tablicy zdefiniowanych route. Dzi\u0119ki temu w prosty spos\u00f3b mo\u017cemy pod tym samym urlem hostowa\u0107 stron\u0119 dla administratora i zwyk\u0142ego u\u017cytkownika, czy fallbackowa\u0107 do domy\u015blnej strony je\u015bli u\u017cytkownik nie ma dost\u0119pu do aktualnie requestowanej. <\/p>\n","innerContent":["\n<p><code>CanMatch<\/code> r\u00f3\u017cni si\u0119 od <code>CanLoad<\/code> jeszcze jednym aspektem. W przypadku dopasowania do \u015bcie\u017cki zabezpieczonej zar\u00f3wno <code>CanLoad<\/code> jak i <code>CanActivate<\/code>, to programista odpowiedzialny jest za obs\u0142ug\u0119 redirect\u00f3w. Je\u015bli z <code>CanMatch<\/code> zwr\u00f3cone zostanie <code>false<\/code>, to Angular kontynuowa\u0142 b\u0119dzie iterowanie po tablicy zdefiniowanych route. Dzi\u0119ki temu w prosty spos\u00f3b mo\u017cemy pod tym samym urlem hostowa\u0107 stron\u0119 dla administratora i zwyk\u0142ego u\u017cytkownika, czy fallbackowa\u0107 do domy\u015blnej strony je\u015bli u\u017cytkownik nie ma dost\u0119pu do aktualnie requestowanej. <\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"prismatic\/blocks","attrs":{"language":"typescript"},"innerBlocks":[],"innerHTML":"\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\">const routes: Route[] = [\n  {\n    path: '\/me',\n    canMatch: [() => inject(UserService).isAdmin()],\n    loadComponent: () => import('.\/admin-page\/admin-page.component')\n  },\n  {\n    path: '\/me',\n    canMatch: [() => inject(UserService).isLoggedIn()],\n    loadComponent: () => import('.\/user-page\/user-page.component')\n  },\n  {\n    path: '**',\n    loadComponent: () => import('.\/not-logged-page\/not-logged-page.component')\n  }\n];<\/code><\/pre>\n","innerContent":["\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\">const routes: Route[] = [\n  {\n    path: '\/me',\n    canMatch: [() => inject(UserService).isAdmin()],\n    loadComponent: () => import('.\/admin-page\/admin-page.component')\n  },\n  {\n    path: '\/me',\n    canMatch: [() => inject(UserService).isLoggedIn()],\n    loadComponent: () => import('.\/user-page\/user-page.component')\n  },\n  {\n    path: '**',\n    loadComponent: () => import('.\/not-logged-page\/not-logged-page.component')\n  }\n];<\/code><\/pre>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/heading","attrs":{"level":3},"innerBlocks":[],"innerHTML":"\n<h3><code>TestBed.runInInjectionContext<\/code><\/h3>\n","innerContent":["\n<h3><code>TestBed.runInInjectionContext<\/code><\/h3>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Funkcja <code>inject()<\/code>, to pot\u0119\u017cne narz\u0119dzie dodane w Angularze 14, kt\u00f3re mo\u017ce uczyni\u0107 nasz kod znacznie czytelniejszym. To dzi\u0119ki niej mo\u017clwie jest mi\u0119dzy innymi pisane functional guards takich jak ten poni\u017cej.<\/p>\n","innerContent":["\n<p>Funkcja <code>inject()<\/code>, to pot\u0119\u017cne narz\u0119dzie dodane w Angularze 14, kt\u00f3re mo\u017ce uczyni\u0107 nasz kod znacznie czytelniejszym. To dzi\u0119ki niej mo\u017clwie jest mi\u0119dzy innymi pisane functional guards takich jak ten poni\u017cej.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"prismatic\/blocks","attrs":{"language":"typescript"},"innerBlocks":[],"innerHTML":"\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\">function onlyLoggedInGuard(): boolean {\n  return inject(UserService).isLoggedIn();\n}\n\nconst routes: Route[] = [{\n  path: '\/me',\n  canMatch: [onlyLoggedInGuard],\n  loadComponent: () => import('.\/user-page\/user-page.component')\n}];<\/code><\/pre>\n","innerContent":["\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\">function onlyLoggedInGuard(): boolean {\n  return inject(UserService).isLoggedIn();\n}\n\nconst routes: Route[] = [{\n  path: '\/me',\n  canMatch: [onlyLoggedInGuard],\n  loadComponent: () => import('.\/user-page\/user-page.component')\n}];<\/code><\/pre>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Do tej pory, aby przetestowa\u0107 guarda takiego jak ten powy\u017cej musieli\u015bmy odpowiednio wsztrzykn\u0105\u0107 do niego kontekst Dependency Injection. Tajemniczy <code>EnvironmentInjector<\/code> mocno psu\u0142 abstrakcj\u0119 <code>TestBed<\/code>, kt\u00f3ra pozwala\u0142a programistom zapomnie\u0107 o szczeg\u00f3\u0142ach implementacyjnych Dependency Injection.<\/p>\n","innerContent":["\n<p>Do tej pory, aby przetestowa\u0107 guarda takiego jak ten powy\u017cej musieli\u015bmy odpowiednio wsztrzykn\u0105\u0107 do niego kontekst Dependency Injection. Tajemniczy <code>EnvironmentInjector<\/code> mocno psu\u0142 abstrakcj\u0119 <code>TestBed<\/code>, kt\u00f3ra pozwala\u0142a programistom zapomnie\u0107 o szczeg\u00f3\u0142ach implementacyjnych Dependency Injection.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"prismatic\/blocks","attrs":[],"innerBlocks":[],"innerHTML":"\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-\">describe('onlyLoggedInGuard', () => {\n  \/* ... *\/\n  it('should not allow not logged in users', () => {\n    \/* ... *\/\n    expect(\n      TestBed.inject(EnvironmentInjector).runInContext(onlyLoggedInGuard)\n    ).toEqual(expectedValue);\n  })\n});<\/code><\/pre>\n","innerContent":["\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-\">describe('onlyLoggedInGuard', () => {\n  \/* ... *\/\n  it('should not allow not logged in users', () => {\n    \/* ... *\/\n    expect(\n      TestBed.inject(EnvironmentInjector).runInContext(onlyLoggedInGuard)\n    ).toEqual(expectedValue);\n  })\n});<\/code><\/pre>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>W Angulara 15.1 TestBed rozszerzony zosta\u0142 o <code>runInInjectionContext<\/code>, kt\u00f3ry troch\u0119 upraszcza powy\u017csz\u0105 konfiguracj\u0119.<\/p>\n","innerContent":["\n<p>W Angulara 15.1 TestBed rozszerzony zosta\u0142 o <code>runInInjectionContext<\/code>, kt\u00f3ry troch\u0119 upraszcza powy\u017csz\u0105 konfiguracj\u0119.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"prismatic\/blocks","attrs":{"language":"typescript"},"innerBlocks":[],"innerHTML":"\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\">describe('onlyLoggedInGuard', () => {\n  \/* ... *\/\n  it('should not allow not logged in users', () => {\n    \/* ... *\/\n    expect(\n      TestBed.runInInjectionContext(onlyLoggedInGuard)\n    ).toEqual(expectedValue);\n  })\n});<\/code><\/pre>\n","innerContent":["\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\">describe('onlyLoggedInGuard', () => {\n  \/* ... *\/\n  it('should not allow not logged in users', () => {\n    \/* ... *\/\n    expect(\n      TestBed.runInInjectionContext(onlyLoggedInGuard)\n    ).toEqual(expectedValue);\n  })\n});<\/code><\/pre>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/heading","attrs":{"level":3},"innerBlocks":[],"innerHTML":"\n<h3><code>isStandalone()<\/code><\/h3>\n","innerContent":["\n<h3><code>isStandalone()<\/code><\/h3>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Je\u015bli kiedykolwiek potrzebowali\u015bcie dowiedzie\u0107 si\u0119 z poziomu API czy dany komponent, piepe lub dyrektywa zosta\u0142a zdediniowana w tradycyjny spos\u00f3b z modu\u0142ami, czy te\u017c jako Standalone Componet, to od teraz b\u0119dzie to mo\u017cliwe. <\/p>\n","innerContent":["\n<p>Je\u015bli kiedykolwiek potrzebowali\u015bcie dowiedzie\u0107 si\u0119 z poziomu API czy dany komponent, piepe lub dyrektywa zosta\u0142a zdediniowana w tradycyjny spos\u00f3b z modu\u0142ami, czy te\u017c jako Standalone Componet, to od teraz b\u0119dzie to mo\u017cliwe. <\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"prismatic\/blocks","attrs":{"language":"typescript"},"innerBlocks":[],"innerHTML":"\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\">@Component({\n  selector: 'app-standalone-component',\n  standalone: true\n})\nclass StandaloneComponent {}\n\n\/* ... *\/\nif(isStandalone(StandaloneComponent)) {\n  console.log(`StandaloneComponent is a standalone component`)\n}<\/code><\/pre>\n","innerContent":["\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\">@Component({\n  selector: 'app-standalone-component',\n  standalone: true\n})\nclass StandaloneComponent {}\n\n\/* ... *\/\nif(isStandalone(StandaloneComponent)) {\n  console.log(`StandaloneComponent is a standalone component`)\n}<\/code><\/pre>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Zastanawia\u0142em si\u0119 chwil\u0119, do czego m\u00f3g\u0142bym u\u017cy\u0107 nowego API, ale niestety nic nie przysz\u0142o mi do g\u0142owy. Je\u015bli Wy czekali\u015bcie na t\u0105 funkcjonalno\u015b\u0107 i macie dla niej jakie\u015b ciekawe zastosowanie, to koniecznie podzielcie si\u0119 nimi z nami na Twitterze.<\/p>\n","innerContent":["\n<p>Zastanawia\u0142em si\u0119 chwil\u0119, do czego m\u00f3g\u0142bym u\u017cy\u0107 nowego API, ale niestety nic nie przysz\u0142o mi do g\u0142owy. Je\u015bli Wy czekali\u015bcie na t\u0105 funkcjonalno\u015b\u0107 i macie dla niej jakie\u015b ciekawe zastosowanie, to koniecznie podzielcie si\u0119 nimi z nami na Twitterze.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/heading","attrs":[],"innerBlocks":[],"innerHTML":"\n<h2>2. State of JS 2022<\/h2>\n","innerContent":["\n<h2>2. State of JS 2022<\/h2>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>State of JS to najwi\u0119ksza ankieta dotycz\u0105ca JavaScript. W minionym tygodniu opublikowane zosta\u0142y jej wyniki. Jak co roku, ka\u017cdemu polecam zapoznanie si\u0119 z nimi samodzielnie, a ja poni\u017cej dziel\u0119 si\u0119 kilkoma moimi spostrze\u017ceniami:<\/p>\n","innerContent":["\n<p>State of JS to najwi\u0119ksza ankieta dotycz\u0105ca JavaScript. W minionym tygodniu opublikowane zosta\u0142y jej wyniki. Jak co roku, ka\u017cdemu polecam zapoznanie si\u0119 z nimi samodzielnie, a ja poni\u017cej dziel\u0119 si\u0119 kilkoma moimi spostrze\u017ceniami:<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/image","attrs":{"align":"center","id":13746,"sizeSlug":"full","linkDestination":"none"},"innerBlocks":[],"innerHTML":"\n<figure class=\"wp-block-image aligncenter size-full\"><img src=\"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/giphy-33-1.gif\" alt=\"\" class=\"wp-image-13746\"\/><figcaption class=\"wp-element-caption\">Tak si\u0119 czuj\u0119 w tym momencie - autor<\/figcaption><\/figure>\n","innerContent":["\n<figure class=\"wp-block-image aligncenter size-full\"><img src=\"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/giphy-33-1.gif\" alt=\"\" class=\"wp-image-13746\"\/><figcaption class=\"wp-element-caption\">Tak si\u0119 czuj\u0119 w tym momencie - autor<\/figcaption><\/figure>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/list","attrs":[],"innerBlocks":[{"blockName":"core\/list-item","attrs":[],"innerBlocks":[],"innerHTML":"\n<li>70% respondent\u00f3w to m\u0119\u017cczy\u017ani i tylko 2.4% respondendt\u00f3w to kobiety. Mam nadziej\u0119, \u017ce tajemnica tej dysproporcji kryje si\u0119 w opcji <code>Brak odpowiedzi<\/code>, kt\u00f3r\u0105 zaznaczy\u0142o a\u017c 24% respondent\u00f3w. Je\u015bli nie, to mamy spory problem...<\/li>\n","innerContent":["\n<li>70% respondent\u00f3w to m\u0119\u017cczy\u017ani i tylko 2.4% respondendt\u00f3w to kobiety. Mam nadziej\u0119, \u017ce tajemnica tej dysproporcji kryje si\u0119 w opcji <code>Brak odpowiedzi<\/code>, kt\u00f3r\u0105 zaznaczy\u0142o a\u017c 24% respondent\u00f3w. Je\u015bli nie, to mamy spory problem...<\/li>\n"]},{"blockName":"core\/list-item","attrs":[],"innerBlocks":[],"innerHTML":"\n<li>W\u015br\u00f3d frontendowych framework\u00f3w pod wzgl\u0119dem satysfakcji nowym kr\u00f3lem jest Solid. Poprzedni kr\u00f3l w postaci Svelte wci\u0105\u017c depcze mu jednak po plecach, bo r\u00f3\u017cnica wynosi zaledwie jeden punkt procentowy (90,9% vs 89,7%). Najwy\u017cszy czas, \u017ceby frameworki te w ko\u0144cu zacz\u0119\u0142y skraca\u0107 dystans w stosunku do wielkiej tr\u00f3jki.<\/li>\n","innerContent":["\n<li>W\u015br\u00f3d frontendowych framework\u00f3w pod wzgl\u0119dem satysfakcji nowym kr\u00f3lem jest Solid. Poprzedni kr\u00f3l w postaci Svelte wci\u0105\u017c depcze mu jednak po plecach, bo r\u00f3\u017cnica wynosi zaledwie jeden punkt procentowy (90,9% vs 89,7%). Najwy\u017cszy czas, \u017ceby frameworki te w ko\u0144cu zacz\u0119\u0142y skraca\u0107 dystans w stosunku do wielkiej tr\u00f3jki.<\/li>\n"]},{"blockName":"core\/list-item","attrs":[],"innerBlocks":[],"innerHTML":"\n<li>W\u015br\u00f3d frontendowych framework\u00f3w pod wzgl\u0119dem wykorzystania bez zmian - wci\u0105\u017c kr\u00f3luje wielka tr\u00f3jka (React, Angular i Vue). Warto jednak zauwa\u017cy\u0107, \u017ce Angular i Vue zaliczy\u0142y spadki o kilka punkt\u00f3w procentowych. W przypadku tego pierwszego, moze to by\u0107 spowodowane niskimi wynikami je\u015bli chodzi o satysfakcj\u0119. W przypadku tego drugiego, g\u0142ownego sprawcy doszukiwa\u0142bym si\u0119 w Vue 3, kt\u00f3re wprowadzi\u0142 sporo breaking changes i tym samym da\u0142o deweloperom \u015bwietny pretekst do migracji. <\/li>\n","innerContent":["\n<li>W\u015br\u00f3d frontendowych framework\u00f3w pod wzgl\u0119dem wykorzystania bez zmian - wci\u0105\u017c kr\u00f3luje wielka tr\u00f3jka (React, Angular i Vue). Warto jednak zauwa\u017cy\u0107, \u017ce Angular i Vue zaliczy\u0142y spadki o kilka punkt\u00f3w procentowych. W przypadku tego pierwszego, moze to by\u0107 spowodowane niskimi wynikami je\u015bli chodzi o satysfakcj\u0119. W przypadku tego drugiego, g\u0142ownego sprawcy doszukiwa\u0142bym si\u0119 w Vue 3, kt\u00f3re wprowadzi\u0142 sporo breaking changes i tym samym da\u0142o deweloperom \u015bwietny pretekst do migracji. <\/li>\n"]},{"blockName":"core\/list-item","attrs":[],"innerBlocks":[],"innerHTML":"\n<li>Astro wbi\u0142o sie na pierwsze miejsce pod wzgl\u0119dem satysfakcji z framework\u00f3w do rendrowania po stronie serwera. To kolejny artgument za tym, \u017ceby\u015bcie zainteresowali si\u0119 tym frameworkiem i koncpecj\u0105 Dynamic Islands.<\/li>\n","innerContent":["\n<li>Astro wbi\u0142o sie na pierwsze miejsce pod wzgl\u0119dem satysfakcji z framework\u00f3w do rendrowania po stronie serwera. To kolejny artgument za tym, \u017ceby\u015bcie zainteresowali si\u0119 tym frameworkiem i koncpecj\u0105 Dynamic Islands.<\/li>\n"]},{"blockName":"core\/list-item","attrs":[],"innerBlocks":[],"innerHTML":"\n<li>Spadek zar\u00f3wno satysfakcji jak i wykorzystania webpacka mo\u017ce sugerowa\u0107, \u017ce technologia ta powoli zaczyna ust\u0119powa\u0107 ju\u017c miejsca m\u0142odszej technologii. Natomiast wynik 98% satysfakcji z Vite robi piorunuj\u0105ce wra\u017cenie i pozwala wnioskowa\u0107 kto zajmie miejsce wys\u0142u\u017conego webpacka.<\/li>\n","innerContent":["\n<li>Spadek zar\u00f3wno satysfakcji jak i wykorzystania webpacka mo\u017ce sugerowa\u0107, \u017ce technologia ta powoli zaczyna ust\u0119powa\u0107 ju\u017c miejsca m\u0142odszej technologii. Natomiast wynik 98% satysfakcji z Vite robi piorunuj\u0105ce wra\u017cenie i pozwala wnioskowa\u0107 kto zajmie miejsce wys\u0142u\u017conego webpacka.<\/li>\n"]},{"blockName":"core\/list-item","attrs":[],"innerBlocks":[],"innerHTML":"\n<li> Tylko 27% respondent\u00f3w po\u015bwi\u0119ca wi\u0119cej swojego czasu na pisanie w JavaScript ni\u017c w TypeScript i tylko 11% respondent\u00f3 nie korzysta z TypeScript wcale. <\/li>\n","innerContent":["\n<li> Tylko 27% respondent\u00f3w po\u015bwi\u0119ca wi\u0119cej swojego czasu na pisanie w JavaScript ni\u017c w TypeScript i tylko 11% respondent\u00f3 nie korzysta z TypeScript wcale. <\/li>\n"]},{"blockName":"core\/list-item","attrs":[],"innerBlocks":[],"innerHTML":"\n<li><\/li>\n","innerContent":["\n<li><\/li>\n"]}],"innerHTML":"\n<ul>\n\n\n\n\n\n\n\n\n\n\n\n<\/ul>\n","innerContent":["\n<ul>",null,"\n\n",null,"\n\n",null,"\n\n",null,"\n\n",null,"\n\n",null,"\n\n",null,"<\/ul>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":{"align":"center"},"innerBlocks":[],"innerHTML":"\n<p class=\"has-text-align-center\"><a href=\"https:\/\/2022.stateofjs.com\/en-US\/\" target=\"_blank\" rel=\"noreferrer noopener\">State of JS 2022<\/a><\/p>\n","innerContent":["\n<p class=\"has-text-align-center\"><a href=\"https:\/\/2022.stateofjs.com\/en-US\/\" target=\"_blank\" rel=\"noreferrer noopener\">State of JS 2022<\/a><\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/heading","attrs":[],"innerBlocks":[],"innerHTML":"\n<h2>3. JavaScript Raising Stars<\/h2>\n","innerContent":["\n<h2>3. JavaScript Raising Stars<\/h2>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Po przeczytaniu State of JS 2022 wci\u0105\u017c ma\u0142o Wam statystyk i podsumowa\u0144? W minionym tygodniu opublikowany zosta\u0142 r\u00f3wnie\u017c raport 2022 JavaScript Rising Stars, kt\u00f3ry zestawia ze sob\u0105 przyrost GitHubowych gwiazdek r\u00f3\u017cnych narz\u0119dzi zwi\u0105zanych z JavaScript. D\u0142ugo mo\u017cnaby dystkutowa\u0107, czy gwiazdki na GithHubie s\u0105 dobrym \u017ar\u00f3d\u0142em danych o popularno\u015bci bibliotek, ale w raporcie na pewno natraficie na kilka ciekawych narz\u0119dzi, kt\u00f3re uciek\u0142y poza Waszymi radarami. Dodatkowo ka\u017cda sekcja okraszona komentarzem ekspert\u00f3w, kt\u00f3rzy zazwyczaj maj\u0105 szerszy pogl\u0105d na ca\u0142\u0105 sytuacj\u0119. <\/p>\n","innerContent":["\n<p>Po przeczytaniu State of JS 2022 wci\u0105\u017c ma\u0142o Wam statystyk i podsumowa\u0144? W minionym tygodniu opublikowany zosta\u0142 r\u00f3wnie\u017c raport 2022 JavaScript Rising Stars, kt\u00f3ry zestawia ze sob\u0105 przyrost GitHubowych gwiazdek r\u00f3\u017cnych narz\u0119dzi zwi\u0105zanych z JavaScript. D\u0142ugo mo\u017cnaby dystkutowa\u0107, czy gwiazdki na GithHubie s\u0105 dobrym \u017ar\u00f3d\u0142em danych o popularno\u015bci bibliotek, ale w raporcie na pewno natraficie na kilka ciekawych narz\u0119dzi, kt\u00f3re uciek\u0142y poza Waszymi radarami. Dodatkowo ka\u017cda sekcja okraszona komentarzem ekspert\u00f3w, kt\u00f3rzy zazwyczaj maj\u0105 szerszy pogl\u0105d na ca\u0142\u0105 sytuacj\u0119. <\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/image","attrs":{"align":"center","id":13748,"sizeSlug":"full","linkDestination":"none"},"innerBlocks":[],"innerHTML":"\n<figure class=\"wp-block-image aligncenter size-full\"><img src=\"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/giphy-31-1.gif\" alt=\"\" class=\"wp-image-13748\"\/><\/figure>\n","innerContent":["\n<figure class=\"wp-block-image aligncenter size-full\"><img src=\"https:\/\/vived.io\/wp-content\/uploads\/2023\/01\/giphy-31-1.gif\" alt=\"\" class=\"wp-image-13748\"\/><\/figure>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":{"align":"center"},"innerBlocks":[],"innerHTML":"\n<p class=\"has-text-align-center\"><a href=\"https:\/\/risingstars.js.org\/2022\/en\" target=\"_blank\" rel=\"noreferrer noopener\">2022 JavaScript Rising Stars<\/a><\/p>\n","innerContent":["\n<p class=\"has-text-align-center\"><a href=\"https:\/\/risingstars.js.org\/2022\/en\" target=\"_blank\" rel=\"noreferrer noopener\">2022 JavaScript Rising Stars<\/a><\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Dla wszystkich, kt\u00f3rzy nie maj\u0105 czasu, si\u0142y lub ochoty na przeczytanie raportu, uchyl\u0119 tajemnicy. W tym roku zestawienie zosta\u0142o zdominowane przez Bun - szybsz\u0105 alternatyw\u0119 typu drop-in dla Node.js i Deno - kt\u00f3ra mia\u0142a premier\u0119 w po\u0142owie tego roku. Zesp\u00f3\u0142 rozwijaj\u0105cy to \u015brodowisko uruchomieniowe zebra\u0142 ju\u017c 7M$ na jego dalszy rozw\u00f3j, tak\u017ce naprawd\u0119 warto obserwowa\u0107, co b\u0119dzie dzia\u0142o si\u0119 z nim w przysz\u0142o\u015bci.<\/p>\n","innerContent":["\n<p>Dla wszystkich, kt\u00f3rzy nie maj\u0105 czasu, si\u0142y lub ochoty na przeczytanie raportu, uchyl\u0119 tajemnicy. W tym roku zestawienie zosta\u0142o zdominowane przez Bun - szybsz\u0105 alternatyw\u0119 typu drop-in dla Node.js i Deno - kt\u00f3ra mia\u0142a premier\u0119 w po\u0142owie tego roku. Zesp\u00f3\u0142 rozwijaj\u0105cy to \u015brodowisko uruchomieniowe zebra\u0142 ju\u017c 7M$ na jego dalszy rozw\u00f3j, tak\u017ce naprawd\u0119 warto obserwowa\u0107, co b\u0119dzie dzia\u0142o si\u0119 z nim w przysz\u0142o\u015bci.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/heading","attrs":[],"innerBlocks":[],"innerHTML":"\n<h2>Bonus: JavaScript Wrapped 2022<\/h2>\n","innerContent":["\n<h2>Bonus: JavaScript Wrapped 2022<\/h2>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/paragraph","attrs":[],"innerBlocks":[],"innerHTML":"\n<p>Je\u015bli jakim\u015b cudem jeszcze nie do\u015b\u0107 Wam podsumowa\u0144, to w minionym tygodniu pope\u0142ni\u0142em ca\u0142kiem obszerne podsumowanie minionego roku z perspektywy redaktora Frontend Weekly. Je\u015bli jeszcze go nie czytali\u015bcie, a chcieliby\u015bcie przekona\u0107 si\u0119 co mog\u0142o Was omin\u0105\u0107 w 2022 roku, to gor\u0105co zapraszam do lektury.<\/p>\n","innerContent":["\n<p>Je\u015bli jakim\u015b cudem jeszcze nie do\u015b\u0107 Wam podsumowa\u0144, to w minionym tygodniu pope\u0142ni\u0142em ca\u0142kiem obszerne podsumowanie minionego roku z perspektywy redaktora Frontend Weekly. Je\u015bli jeszcze go nie czytali\u015bcie, a chcieliby\u015bcie przekona\u0107 si\u0119 co mog\u0142o Was omin\u0105\u0107 w 2022 roku, to gor\u0105co zapraszam do lektury.<\/p>\n"]},{"blockName":null,"attrs":[],"innerBlocks":[],"innerHTML":"\n\n","innerContent":["\n\n"]},{"blockName":"core\/embed","attrs":{"url":"https:\/\/vived.io\/pl\/frontend-weekly-vol-119\/","type":"wp-embed","providerNameSlug":"vived","align":"center"},"innerBlocks":[],"innerHTML":"\n<figure class=\"wp-block-embed aligncenter is-type-wp-embed is-provider-vived wp-block-embed-vived\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/vived.io\/pl\/frontend-weekly-vol-119\/\n<\/div><\/figure>\n","innerContent":["\n<figure class=\"wp-block-embed aligncenter is-type-wp-embed is-provider-vived wp-block-embed-vived\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/vived.io\/pl\/frontend-weekly-vol-119\/\n<\/div><\/figure>\n"]}],"_links":{"self":[{"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/posts\/13696","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/comments?post=13696"}],"version-history":[{"count":18,"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/posts\/13696\/revisions"}],"predecessor-version":[{"id":13788,"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/posts\/13696\/revisions\/13788"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/media\/13784"}],"wp:attachment":[{"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/media?parent=13696"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/categories?post=13696"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vived.io\/pl\/wp-json\/wp\/v2\/tags?post=13696"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}