Remix full-stack React framework

Kas yra Remix ir kodėl jis iššaukė tokį sąmyšį web development bendruomenėje?

Jei sekate React ekosistemą, tikriausiai pastebėjote, kad pastaraisiais metais full-stack framework’ų scena tapo itin įvairi. Next.js ilgai dominavo, bet staiga atsirado naujas žaidėjas – Remix. Ir ne bet koks žaidėjas, o toks, kuris iškart privertė susimąstyti net patį Next.js kūrėjus.

Remix yra full-stack React framework’as, kurį sukūrė Ryan Florence ir Michael Jackson – žmonės, kurie anksčiau davė mums React Router. Tai jau savaime turėtų sukelti susidomėjimą, nes šie vyrai tikrai žino, kaip veikia routing’as ir navigacija React aplikacijose. Bet Remix – tai ne tik routing’as. Tai visiškai kitoks požiūris į tai, kaip turėtų veikti modernios web aplikacijos.

Framework’as oficialiai pasirodė 2021 metų pabaigoje, ir nuo pat pradžių buvo aišku, kad čia kažkas yra kitaip. Vietoj to, kad sekti įprastais keliais, Remix kūrėjai nusprendė grįžti prie web fundamentals – standartinių web platformos galimybių, kurias dažnai ignoruojame bėgdami paskui naujausias JavaScript tendencijas.

Web fundamentals: kai senas tampa nauju

Vienas įdomiausių Remix aspektų yra jų filosofija – „use the platform”. Skamba paprasta, bet praktikoje tai reiškia radikalų požiūrio pasikeitimą. Remix maksimaliai remiasi standartinėmis web API, tokiomis kaip FormData, Headers, Request, Response ir kitomis Web Fetch API dalimis.

Pavyzdžiui, formos Remix aplikacijose veikia net be JavaScript. Taip, gerai perskaitėte – jūsų forma gali būti submit’inta ir duomenys apdoroti serverio pusėje net jei vartotojo naršyklėje JavaScript’as išjungtas arba dar nepakrovė. Tai ne kažkoks atgalinis žingsnis – tai progressive enhancement principas veikime.

Štai kaip atrodo paprasta forma Remix:

„`jsx
export async function action({ request }) {
const formData = await request.formData();
const email = formData.get(„email”);

await subscribeToNewsletter(email);

return redirect(„/success”);
}

export default function Subscribe() {
return (



);
}
„`

Matote tą `method=”post”`? Tai paprasta HTML forma. Kai JavaScript’as pakraunamas, Remix automatiškai interceptina formą ir daro fetch request’ą, bet jei JavaScript’o nėra – forma vis tiek veikia kaip įprasta HTML forma. Genialiai paprasta.

Loader’iai ir action’ai: duomenų valdymas be galvos skausmo

Vienas didžiausių skirtumų nuo tradicinių React aplikacijų yra tai, kaip Remix tvarko duomenis. Užuot naudoję `useEffect` su fetch’ais arba kokią nors state management biblioteką, Remix siūlo loader’ius ir action’us.

Loader’iai – tai funkcijos, kurios vykdomos serveryje prieš renderinant komponentą. Jos grąžina duomenis, kuriuos komponentas gali iškart naudoti. Nereikia jokių loading state’ų, nereikia rūpintis race condition’ais, nereikia galvoti apie cache invalidation (na, bent jau ne taip, kaip įpratę).

„`jsx
export async function loader({ params }) {
const user = await db.user.findUnique({
where: { id: params.userId }
});

if (!user) {
throw new Response(„Not Found”, { status: 404 });
}

return json(user);
}

export default function UserProfile() {
const user = useLoaderData();

return (

{user.name}

{user.bio}

);
}
„`

Action’ai – tai funkcijos, kurios apdoroja mutacijas. POST, PUT, DELETE request’ai eina per action’us. Ir štai kur prasideda magija: kai action’as baigia darbą, Remix automatiškai revaliduoja visus loader’ius puslapyje. Tai reiškia, kad jūsų UI automatiškai atsinaujina su naujausiais duomenimis, nereikia jokio papildomo kodo.

Nested routing’as ir duomenų pakrovimas

Remix routing’as yra pagrįstas file-system principu, panašiai kaip Next.js, bet su vienu svarbiausiu skirtumu – nested routes yra first-class citizen. Ir tai ne tik routing’o klausimas, tai keičia visą duomenų pakrovimo logiką.

Kai turite nested route’us, kiekvienas route gali turėti savo loader’į. Ir kai vartotojas naršo tarp puslapių, Remix pakrauna tik tuos duomenis, kurie pasikeitė. Jei parent route duomenys nepasikeitė – jie neperkraunami. Tai drastiškai sumažina duomenų kiekį, kurį reikia perkelti tinklu.

Pavyzdžiui, jei turite dashboard’ą su sidebar’u ir keičiate tik content area, sidebar’o duomenys neperkraunami. Remix yra pakankamai protingas, kad suprastų, kurie loader’iai turi būti iškviesti, o kurie ne.

Failų struktūra gali atrodyti taip:

„`
app/
routes/
dashboard.tsx (parent layout su sidebar)
dashboard.projects.tsx (projektų sąrašas)
dashboard.projects.$id.tsx (konkretus projektas)
dashboard.settings.tsx (nustatymai)
„`

Kiekvienas iš šių failų gali turėti savo loader’į, ir visi jie veikia kartu, bet nepriklausomai vienas nuo kito.

Error handling’as, kuris iš tiesų veikia

Vienas dalykas, kurį dažnai ignoruojame kuriant aplikacijas – tai tinkamas error handling’as. Remix daro tai labai elegantiškai su ErrorBoundary ir CatchBoundary konceptais.

ErrorBoundary sugauna JavaScript klaidas, o CatchBoundary sugauna HTTP response’us su error status kodais. Ir gražiausia dalis – galite turėti boundary kiekvienam route’ui. Tai reiškia, kad jei klaida įvyksta nested route’e, tik ta dalis puslapio parodys error, o ne visas puslapis subyrės.

„`jsx
export function ErrorBoundary({ error }) {
return (

Oops, kažkas nutiko

{error.message}

);
}

export function CatchBoundary() {
const caught = useCatch();

if (caught.status === 404) {
return

Puslapis nerastas

;
}

throw new Error(`Unexpected caught response: ${caught.status}`);
}
„`

Tai labai praktiškas dalykas production aplikacijose. Vietoj to, kad visas puslapis taptų tuščiu ekranu su console error’u, vartotojas mato prasmingą pranešimą ir gali toliau naudotis aplikacija.

Performance optimizacijos iš dėžės

Remix yra suprojektuotas taip, kad būtų greitas be jūsų pastangų. Tai nereiškia, kad negalite padaryti lėtos aplikacijos (visada galima), bet default’ai yra labai geri.

Pirma, Remix automatiškai daro code splitting pagal route’us. Kiekvienas route’as yra atskiras bundle, kuris pakraunamas tik tada, kai reikia. Bet skirtingai nuo kai kurių kitų sprendimų, Remix taip pat prefetch’ina route’us, kai vartotojas užveda pelę ant nuorodos. Tai reiškia, kad kai vartotojas paspaudžia, puslapis jau yra pakrautas.

Antra, Remix turi labai protingą caching strategiją. Jie naudoja HTTP cache headers, o ne kažkokį custom cache layer’į. Tai reiškia, kad jūsų aplikacija veikia gerai su CDN, browser cache ir kitais standartiniais web infrastructure komponentais.

Trečia, serverio pusės rendering’as (SSR) yra default’as. Tai reiškia, kad vartotojas mato content’ą iškart, net jei JavaScript dar nepakrovė. Ir kai JavaScript pakrauna, Remix daro hydration’ą be viso puslapio re-render’inimo.

Praktinis patarimas: naudokite Remix developer tools, kad pamatytumėte, kokie loader’iai vykdomi ir kiek laiko jie užtrunka. Tai padės identifikuoti bottleneck’us jūsų aplikacijoje.

Deployment ir hosting galimybės

Vienas iš Remix privalumų yra tai, kad jis gali būti deploy’intas praktiškai bet kur. Jie turi adapterius daugeliui platformų: Vercel, Netlify, Cloudflare Workers, AWS Lambda, Express serveris, ir net tiesiog Node.js serveris.

Ypač įdomus yra Cloudflare Workers deployment’as. Kadangi Remix remiasi Web Fetch API, jis puikiai veikia edge runtime’uose. Tai reiškia, kad jūsų aplikacija gali veikti geografiškai arti jūsų vartotojų, drastiškai sumažinant latency.

Deployment’as į Vercel yra paprastas kaip:

„`bash
npm install @remix-run/vercel
„`

Ir package.json:

„`json
{
„scripts”: {
„build”: „remix build”,
„dev”: „remix dev”
}
}
„`

Vercel automatiškai atpažįsta Remix projektą ir sukonfigūruoja viską, ko reikia. Panašiai veikia ir su kitomis platformomis.

Svarbus momentas: jei planuojate naudoti edge deployment’ą (Cloudflare Workers ar Vercel Edge Functions), įsitikinkite, kad jūsų database ir kiti servisai taip pat yra geografiškai paskirstyti, kitaip prarasite visus edge privalumus laukdami atsakymo iš vieno datacenter’io.

Remix vs Next.js: ar verta keisti?

Tai klausimas, kurį klausia visi. Ir atsakymas, kaip visada – depends. Next.js yra brandus, turi didžiulę bendruomenę, daugybę tutorialų ir sprendimų įvairioms problemoms. Remix yra naujesnis, bet su labai stipriomis idėjomis.

Remix privalumai:
– Geresnis data mutation handling su action’ais
– Natūralesnis nested routing’as
– Stipresnis progressive enhancement
– Paprastesnis mental model (nereikia galvoti apie getServerSideProps, getStaticProps, etc.)

Next.js privalumai:
– Didesné bendruomenė ir ecosystem’a
– Daugiau tutorialų ir learning resources
– Image optimization iš dėžės
– Incremental Static Regeneration (ISR)

Jei kuriate naują projektą ir jums patinka Remix filosofija – drąsiai naudokite. Jei turite egzistuojantį Next.js projektą, kuris veikia gerai – tikriausiai nėra prasmės migruoti tik dėl to, kad Remix yra „naujas ir šaunus”.

Bet jei jūsų Next.js aplikacija turi daug formų, sudėtingą data mutation logiką, ar jums nuolat tenka kovoti su cache invalidation – Remix gali būti atsakymas į jūsų maldas.

Praktiniai patarimai pradedantiesiems su Remix

Jei nusprendėte išbandyti Remix, štai keletas patarimų, kurie padės išvengti įprastų klaidų:

**Pradėkite nuo oficialių tutorialų.** Remix dokumentacija yra puiki, o jų „Jokes App” tutorialas tikrai veda per visus svarbiausius konceptus. Neskubėkite, išbandykite viską patys.

**Pamirškite useEffect duomenų pakrovimui.** Tai sunkiausia dalis daugeliui React developerių. Remix aplikacijose duomenys turėtų būti pakraunami per loader’ius, ne per useEffect. Jei pradedate rašyti `useEffect(() => { fetch(…) }, [])` – sustokite ir pagalvokite, ar tai tikrai reikalinga.

**Naudokite FormData.** Remix formos dirba su FormData API, ne su controlled inputs ir state. Pradžioje tai gali atrodyti keista, bet greitai suprasite, kad tai daug paprasčiau. Jūsų formos veiks net be JavaScript, o validacija gali vykti serveryje.

**Išmokite nested routing’ą.** Tai viena stipriausių Remix pusių, bet reikia laiko suprasti, kaip tai veikia. Eksperimentuokite su skirtingomis layout’ų struktūromis, bandykite sukurti nested route’us su savo loader’iais.

**Nebijokit throw’inti Response objektų.** Remix error handling’as yra suprojektuotas taip, kad galėtumėte throw’inti Response objektus iš loader’ių ar action’ų. Tai ne klaida – tai feature. `throw new Response(„Not found”, { status: 404 })` yra normalus būdas grąžinti 404.

**Optimistic UI yra paprastas.** Remix turi `useFetcher` hook’ą, kuris leidžia lengvai implementuoti optimistic updates. Jei jūsų aplikacija turi daug interaktyvių elementų (like buttons, todo checkboxes, etc.), išnagrinėkite šį hook’ą.

**Deployment’as nėra afterthought.** Nuo pat pradžių pagalvokite, kur deploy’insite aplikaciją. Skirtingos platformos turi skirtingus limitacijos ir galimybes. Cloudflare Workers turi execution time limit’us, Vercel turi serverless function limitacijos, etc.

Ką Remix reiškia web development ateičiai

Remix atėjimas į sceną yra svarbus ne tik dėl to, kad tai dar vienas framework’as. Jis reprezentuoja filosofijos pasikeitimą – grįžimą prie web fundamentals, bet su moderniomis developer experience pagerinimais.

Įdomu tai, kad daugelis Remix idėjų jau pradeda atsirasti kituose framework’uose. Next.js 13 versijoje pristatė Server Components ir naują app directory, kuris turi panašumų su Remix požiūriu. SvelteKit taip pat turi loader’ius ir action’us. Tai rodo, kad Remix idėjos rezonuoja su bendruomene.

Ar Remix taps dominuojančiu framework’u? Sunku pasakyti. Bet viena aišku – jis jau pakeitė diskusiją apie tai, kaip turėtų veikti full-stack React aplikacijos. Ir tai yra geras dalykas visiems mums.

Jei esate React developeris ir dar neišbandėte Remix – rekomenduoju skirti savaitgalį ir sukurti kokį nors mažą projektą. Net jei nuspręsite nenaudoti jo production’e, patirtis ir idėjos, kurias gausite, tikrai pagerins jūsų supratimą apie web development’ą apskritai. O kas žino – galbūt Remix taps jūsų nauju favorite tool’u.

Daugiau

OVHcloud Europos debesų sprendimai