typeofweb x michalczukm #23 | server-driven UI wraca oknem
Siema!
Poniżej to ja podczas próby napisania newslettera we wtorek wieczorem. Jak widzicie - nie udało się, zostałem pokonany przez grawitację.
Zatem z 1 dniową obsuwą zapraszam was na kolejne wydanie newslettera gdzie piszę o tym jak server-driven UI wraca na tapet, kolejni bad-actors chcą dobrać się do naszych danych przez npm supply chain ataki a szaleni ludzie uruchamiają JS w Pythonie. Enjoy!
🧑💻 Michał Michalczuk | michalczukm.xyz
Kolejny npm supply chain atak prze Lazarus Group
Ostatnio pisałem o serii artykułów “State Of Npm 2023” popełnionych przez Sandworm z którego wynikało że ok 500 000 nowych pakietów to spam.
Spam to jedno. Część z nich to złośliwy kod, który chce się dobrać do waszych danych. Nihil novi, ale schemat ataku grupy Lazarus odkryty przez badaczy jest błyskotliwy (niech będzie - złowieszczo błyszczący). A opis znajdziecie na blogu Socket.
Targetem byli badacze bezpieczeństwa, oraz ludzie pracujący z krypto i blockchainem.
A jak to wyglądało.
1. Socjotechnika
Klasyczek. Atakujący podszywali się pod rekruterów, badaczy security, lub developerów szukających pomocy lub chcących pomóc przy projektach.
Kontaktowali się przez GitHub, LinkedIn, Slack czy Telegram a celem było zaproszenie do pracy nad projektem na GitHub’ie, który zawierał w zależnościach pakiety npm z malware.
2. Uruchomienie kodu
Gdy cel pobrał repo i zainstalował zależności podczas uruchomienia projektu złośliwe pakiety działały w tandemie.
Pierwsza z zależności pobierała token potrzebny do uruchomienia drugiej. Dobrym przykładem jest pakiet tslib-reac
Następnie ta sama paczka (lub inna w zależności od schematu) odczytywała zapisany wcześniej token i z jego pomocą pobierała skrypt i wykonywała go.
Makao i po makale.
Artykuł wymienia 24 pakiety npm które brały udział w atakach. Najbardziej urzekła mnie paczka snykaudit-helper, która podszywa się pod kod pracujący z narzędziem security jakim jest snyk 🥲
Przy okazji Socket dostał ostatnio $20M finansowania serii A od Andreessen Horowitz. Brawo oni!
Server-driven UI, znowu czuje się jak w 2010
Zawsze jak słyszę hasło server-driven UI mam przed oczami bardziej deklaratywną wersję Vaadin 😀 To chyba PTSD, chociaż sam miałem okazję pracować z takimi rozwiązaniami również w JS i działało to bardzo rozsądnie.
Ale ale, o co chodzi. Server-driven UI to dynamiczny sposób sterowania UI, który dostaje użytkownik dosłownie z poziomu back-end’u.
💻 Klient dostaje obiekt JSON z drzewem komponentów do zbudowania i wyświetlenia. Brzmi jak mieszanie odpowiedzialności i zbędne budowanie complexity w aplikacjach webowych, ale zanim z krzykiem zamkniecie ten newsletter pomyślcie o zastosowaniu tego w aplikacjach mobilnych. Wykorzystuje to między innymi Instagram, Lyft, Airbnb czy Allegro (mają własny rendering tool MBox, pozdrawiam!)
Aplikacje mobilne mają o wiele dłuższy release cycle niż klienci web, ponieważ użytkownik musi pobrać naszą aktualizację z AppStore/PlayStore/InnyStore.
I krytyczny bug który uniemożliwia zarabianie lub użytkowanie naszej aplikacji musi grzecznie poczekać na to aż user zaktualizuję aplikacje. W między czasie może zdążyć ją odinstalować z “co to za 💩” na ustach.
Wprowadzając takie rozwiązania jak server-driven UI skracamy ten loop do minimum, bo klient dostaje na bierząco kształt UI do wyświetlenia.
🛣️ Nie jest to lekka droga. Poza zmianą mental modelu wytwarzania aplikacji i rozwiązania tego technicznie mamy jeszcze guidelines sklepów z aplikacjami które musimy spełniać które nie przepadają za takimi dynamicznymi rozwiązaniami podczas audytów.
W artykule znajdziecie więcej szczegółów oraz live z inżynierem Instagram (wł. Meta), który opowiada jak oni to robią.
Odszyfrowując payload React Server Components
Poprzedni wpis o server-driven UI to idealny wstęp do tego newsa. Jeśli mieliście okazję korzystać już z RSC (React Server Components) i zaglądaliście w zakładkę network
aby sprawdzić czy wasz komponent został poprawnie ze-streamowany do klienta to mogła was uderzyć hmm … niska czytelność “wire format”.
Jeśli otworzycie DevToolsy i network
na podlinkowanym blogu → przenawigujcie na inną stronę a dostaniecie stream komponentu jak poniżej.
Alternatywnie tutaj możecie się pobawić innym przykładem - demo na Stackblitz.
Jak narazie brak toolingu który wspomógłby nam w debugowaniu i optymalizacji RSC nie pomaga. Ale Alvar Lagerlöf stworzył
i pracuje nad rozszerzeniem do chroma, które oszczędzi nam copy-paste i zwiększy DX pracy z RSC ❤️
Trzymam kciuki! W artykule znajdziecie więcej szczegółów o tym jak autor odszyfrował “wire format”.
Przed Next13 Masters
Michał Miszczyszyn i Jakuba "Zaiste" Neander w ramach startu NEXT13 MASTERS odpalają kolejne live.
Nie jeden, nie dwa, a trzy (to brzmi cheesy, ale wiecie o co chodzi 😀 )
- 17 SIERPNIA | 20:00-21:30 - Zoptymalizuj wydajność, popraw SEO i zwiększ konwersję
- 22 SIERPNIA | 20:00-21:30 - Dlaczego Next.js wyprzedza swoją epokę? 5 najważniejszych różnic między Next.js 13 a innymi narzędziami
- 29 SIERPNIA | 20:00-21:30 - Czego nauczyliśmy się przez 10+ lat jako full stack developerzy?
Na wszystkie wydarzenia możecie zapisać się na stronie. Do zobaczenia!
Omijanie blokad anti-debugging
Jeśli mieliście kiedyś okazję debugować w przeglądarce kod 3rd party, do którego nie macie dostępu wiecie jak wspaniała to zabawa.
Być może próbowaliście robić reverse engineering [which is potential illegal 💩] i wpadliście na zabezpieczenia przeciwko debuggowaniu jak ciągłe zatrzymywanie się na debugger;
Dlaczego do ominięcia tego autor zbudował customową wersję Firefox’a 😮 - szczegóły w tekście.
PythonMonkey 🐍 ❤️ 🐵
🌴 Kącik egzotyczny na dzisiaj.
PythonMonkey to kolejne podejście (w artykule znajdziecie pokrewne projekty) na stworzenie interop’u pomiędzy Python’em a JavaScript.
Zatem możemy uruchomić kod JavaScript w Python’ie
async def someAsyncStuff():
two_sec_promise = pythonmonkey.eval("""
new Promise((resolve, reject) => {
setTimeout(resolve, 2000);
});
""")
print("before calling the 2 second timer")
await two_sec_promise
print("two seconds have now passed")
To rozwiązanie jest unikatowe z paru powodów:
- Działamy w event-loop, mamy mikrotaski więc można używać Promises w kodzie JS ❤️
- Wykorzystuje SpiderMonkey, silnik JS od Mozilla
- Z pythona można odpalić kod kod w WebAssembly wykonywany z SpiderMonkey (i to jeszcze z Promises!)
Poza uruchamianiem JS w Pythonie, możemy też uruchomić kod Python w JS. PythonMonkey przychodzi z PMJS który to umożliwia.
const { getStringLength } = require('./my-python-module');
function printStringLength(s) {
console.log(`String: "${s}" has a length of ${getStringLength(s)}`);
}
module.exports = { printStringLength, };
Jakie mamy zastosowania? You name it - oba środowiska mają swoje unikatowe zalety oraz ekosystem pakietów który może nam pomóc.
Autorzy wskazują jeszcze inny case - jeśli chcemy aby nasze rozwiązało działało zarówno w Pythonie jak i JS (SDK, biblioteka, etc) zamiast tworzyć adaptery lub implementować to samo rozwiązanie w wielu językach możemy wykorzystać PythonMonkey i napisać binding.
🌴 Koniec kącika egzotycznego na dzisiaj.
CFP na 4Developers Gdańsk do 14.08
Wydłużyliśmy o tydzień termin CFP na gdańską edycje 4Developers.
Ja (Michał Michalczuk) wraz z Bartkiem Cytrowskim opiekujemy się ścieżką JavaScript, nie krępujcie się i nawrzucajcie nam … tematów 😎 Więcej - o tym kogo szukamy na stronie.
Oraz wpadajcie na konferencje! Do zobaczenia 👋
dnt - Deno to Node transform
Aby opublikować pakiet na npm który będzie szeroko używany powinien być opublikowany jako ESM, CommonJS, z typami TypeScript, działać w Node.js, Deno i przeglądarce (jeśli zasadne).
Dodaje to 👷♂️ pracy i złożoności do procesu budowania.
Deno możemy wydało dnt
który zrobi za nas tą robotę jeśli napiszemy kod w… Deno. To kolejna cegiełka do zwiększenia adopcji Deno przez możliwość połączenia go z ekosystemem Node.js i npm.
react-tweet = 16kb bez layout shift
Embeddowanie tweetów (chyba wciąż się tak nazywają 🤔) na stronie wiązało się z pobraniem ~550kb JavaScript’u w iframe który ładujemy na stronę. Dodatkowo dostawaliśmy layout shift, który nie poprawiał wrażenia. Sprawdźcie na https://publish.twitter.com.
Vercel wydał react-tweet
, który rozwiązuje te problemy dostarczając własne komponenty UI do wyświetlenia treści oraz fetchuje zawartość tweeta bez logowania się do ich API.
Aby pobrać treść tweeta korzystają z CDN twittera - https://github.com/vercel/react-tweet/blob/main/packages/react-tweet/src/api/get-tweet.ts
Doceniam to obejście 🙂
Tailwind connect
W lipcu Tailwind zorganizował pierwsze spotkanie in-person, które miało być małym meetupem a wyszło z tego spotkanie na 200 osób i poziom realizacji którego nie powstydziła by się poważna konferencja. Tak wyszło.
Jak na “ot taki meetup” padło tam sporo konkretnych ogłoszeń.
- Oxide to nowy silnik Tailwind CSS, który wykorzystuje Lightning CSS - all-in-one parser/bundler/minifikator w Rust’cie stworzony i wykorzystywany w Parcel’u. Oxide ma wyjść w Tailwind v3.4 i poza uproszczeniem konfiguracji ma przynieść skrócenie czasu budowania projektu o 50%
- Catalyst to zestaw komponentów React, który chce się porozpychać na rynku bibliotek komponentów. Jego przewagą ma być pełna komponowalność
Spotkanie otwiera keynote Adama Watchman’a, który opowiada jak Tailwind z małego projektu urósł do rozwiązania które zjadło rynek i aktualnie ma 25M pobrań miesięcznie 😲
Generator palet kolorów do Tailwind
Pozostając w temacie Tailwind’a. Małe i przydatne narzędzie do wygenerowania palet kolorów.
To tyle na dzisiaj, do przeczytania za 2 tygodnie 👋
Stopka
Podobało się? Nie podobało się? Daj mi znać. Jeśli coś z wrzuconych tu materiałów Ci się przydało, to daj lajka, udostępniaj, albo po prostu powiedz znajomym. Chętnie przyjmuję też wszelkie sugestie. Dzięki!