• parcel
  • vite
  • js
  • esbuild
  • bundler
  • monorepo

Parcelista Viteen: Tarina 100K LOC siirtymästä

Olemme siirtäneet kolme frontend-projektiamme Parcelista Viteen, ja prosessi oli... sujuva.

Gao
Gao
Founder

Tausta

Meillä on kolme pääasiallista frontend-projektia Logtossa: kirjautumiskokemus, Console ja live-esikatselu. Nämä projektit ovat kaikki TypeScriptillä, Reactilla ja SASS-moduuleilla; yhteensä niissä on noin 100 000 koodiriviä.

Rakastimme Parcelia sen yksinkertaisuuden ja nolla-asetuksen vuoksi. Muistan vieläkin päivän, jolloin hämmästyin siitä, kuinka helppoa oli perustaa uusi projekti Parcelilla. Voit vain suorittaa parcel index.html ja boom, kaikki tarvittavat riippuvuudet asennetaan ja projekti toimii. Jos olet "kokeneempi" kehittäjä, saatat tuntea samoin verratessasi sitä vanhoihin päiviin Gul-pilla ja Webpackilla. Parcel on kuin taikasauva.

Parcelin yksinkertaisuus oli pääsyy siihen, miksi pysyttäydyimme siinä niin pitkään, vaikka se saattoi olla joskus oikukas. Esimerkiksi:

  • Parcel epäonnistui joskus niputtamaan projektin, koska se ei löytänyt joitain chunk-tiedostoja, jotka olivat todella siellä.
  • Se vaati joitain korjaustoimenpiteitä toimiakseen monorepo-asetuksellamme.
  • Se ei tue MDX 3:ta natiivisti, joten meidän piti luoda sille mukautettu muunnin.
  • Se ei tue manuaalisia konteja (kirjoitushetkellä manuaalinen chunks-ominaisuus on yhä kokeiluvaiheessa), mikä on ok useimmissa tilanteissa, mutta joskus tarvitset sitä.

Miksi päätimme siirtyä muuhun?

  1. Olimme jumissa Parcelin versiossa 2.9.3, joka julkaistiin kesäkuussa 2023. Joka kerta kun uusi versio julkaistiin sen jälkeen, yritimme päivittää, mutta se epäonnistui aina rakennusvirheisiin.
  2. Parcelin uusin versio oli 2.12.0, julkaistu helmikuussa 2024. Vaikka sillä on lähes päivittäiset commitit, uusia julkaisuja ei ole tehty siitä lähtien.

Joku jopa avasi keskustelun kysyäkseen onko Parcel kuollut. Virallinen vastaus on että ei, Parcel on yhä elossa, mutta se on tilassa jossa "meillä on käynnissä suuri refaktori eikä aikaa pienille julkaisuille". Meille se on kuin "ankan kuolema": viimeisin versio, jota voimme käyttää, on yli vuoden takainen, emmekä tiedä milloin seuraava versio julkaistaan. Se näyttää kuolleelta, se käyttäytyy kuin kuollut, joten se on kuollut meille.

Parcel upgrade pull requests

Usko pois, olemme yrittäneet.

Miksi Vite?

Tunsimme Viten Vitestistä. Useita kuukausia sitten olimme väsyneitä Jestin ESM-tukeen (testauksessa) ja halusimme kokeilla jotain uutta. Vitest voitti sydämemme natiivilla ESM-tuellaan ja Jest-yhteensopivuudellaan. Sillä on loistava kehittäjäkokemus, ja se on Viten voimanlähde.

Nykytilanne

Sinulla saattaa olla erilaiset asetukset projektissasi, mutta yleensä löydät korvaavia plugineja, kun Vite-ekosysteemi kukoistaa. Tässä ovat asetuksemme siirtymähetkellä:

  • Monorepo: Käytämme PNPM (v9) työtiloja hallitaksemme monorepoamme.
  • Moduuli: Käytämme ESM -moduuleita kaikissa projekteissamme.
  • TypeScript: Käytämme TypeScriptiä (v5.5.3) kaikissa projekteissamme polkualiasilla.
  • React: Käytämme Reactia (v18.3.1) kaikissa frontend-projekteissamme.
  • Tyylit: Käytämme SASS-moduuleita tyylityksessä.
  • SVG: Käytämme SVG:tä React-komponentteina.
  • MDX: Meillä on MDX GitHub Flavored Markdownilla ja Mermaidi-tuella.
  • Lataamisen viivästys: Tarvitsemme viivästettyä latausta joillakin sivuillamme ja komponenteissamme.
  • Pakkaus: Tuotamme pakattuja resursseja (gzip ja brotli) tuotantorakennuksiimme.

Siirtymä

Aloitimme siirtymän luomalla uuden Vite-projektin ja leikkimällä sillä nähdäksemme, miten se toimii. Prosessi oli sujuva ja varsinainen siirtymä kesti vain muutaman päivän.

Valmiiksi tuettu tuki

Vite tukee valmiiksi monorepoja, ESM:ää, TypeScriptiä, Reactia ja SASS:ia. Meidän tarvitsi vain asentaa tarvittavat pluginit ja konfiguraatiot saadaksemme sen toimimaan.

Polkualias

Vite tukee valmiiksi polkualiasia, esimerkiksi tsconfig.json-tiedostossamme:

Meidän tarvitsi vain lisätä sama resoluutio vite.config.ts-tiedostoossa:

Huomaa, että korvauspolun tulisi olla absoluuttinen polku, vaikka se on suhteellinen projektin juureen nähden. Vaihtoehtoisesti voit käyttää vite-tsconfig-paths pluginia lukeaksesi polkualiasit tsconfig.json-tiedostosta.

React Fast Refresh ja HMR

Vaikka Vite tukee valmiiksi HMR:ää, se vaatii pluginin asentamisen React Fast Refreshin ottamiseksi käyttöön. Käytimme @vitejs/plugin-react-pluginia, joka on Vite-tiimin tarjoama ja sisältää loistavan tuen React-ominaisuuksille, kuten Fast Refresh:

SVG React-komponenttina

Käytämme vite-plugin-svgr-pluginia muuntaaksemme SVG:t React-komponenteiksi. Se on niin yksinkertaista kuin pluginin lisääminen Vite-konfiguraatioon:

Emme kuitenkaan määrittäneet, millä ehdolla SVG:t tulisi muuntaa React-komponenteiksi, joten kaikki tuonnit muunnettiin. Plugin tarjoaa paremman oletuskonfiguraation: muunna vain SVG:t, jotka tuodaan .svg?react-laajennuksella. Päivitimme tuontimme vastaavasti.

SASS-moduulit

Vaikka Vite tukee valmiiksi SASS-moduuleita, on yksi asia, josta meidän on huolehdittava: kuinka luokkien nimet muotoillaan. Se voi olla vaivalloista käyttäjille ja integraatiotesteillemme, jos luokkien nimet eivät ole yhdenmukaisesti muotoiltuja. Yksinkertainen määritys vite.config.ts-tiedostossa voi ratkaista ongelman:

Muuten, Parcel ja Vite käyttävät erilaisia makuja tuontia varten SASS-tiedostoissa:

* as-syntaksi toimii kuitenkin Vitessä, mutta se aiheuttaa modulaaristen luokkien nimien menetyksen, kun käytät dynaamisia avaimia tietorakenteen styles objektiin. Esimerkiksi:

MDX-tuki

Koska Vite käyttää Rollupia taustalla, voimme käyttää virallista @mdx-js/rollup-pluginia tukemaan MDX:ää sekä sen plugineja. Määritys näyttää tältä:

remarkGfm-plugini tukee GitHub Flavored Markdownia, ja rehypeMdxCodeProps-plugini välittää rekvisiitat MDX-tiedostojen koodilohkoihin kuten Docusaurus tekee.

Mermaidi-tuki MDX-tiedostojen sisällä

Haluaisimme käyttää Mermaid-kaavioita MDX-tiedostoissamme muiden ohjelmointikielten tavoin. Käytön pitäisi olla yhtä yksinkertaista kuin muiden koodilohkojen:

Pitäisi näyttää tältä:

Koska sovelluksemme tukee valo- ja tummateemoja, koodasimme hieman saadaksemme Mermaid-kaaviot toimimaan tummalla teemalla. React-komponentti on luotu:

useTheme on räätälöity hook, joka hakee nykyisen teeman kontekstista. mermaid-kirjasto tuodaan asynkronisesti latauskokoon pienentämiseksi alkuperäisessä sivulatauksessa.

MDX-tiedoston koodilohkoa varten meillä on yhtenäinen komponentti työn suorittamiseksi:

Lopuksi määrittelimme MDX-tarjoajan seuraavasti:

Latauksen viivästys

Tämä ei ole Vite-spesifi asia, mutta se on silti mainitsemisen arvoinen, sillä päivitimme sivumme käyttämään latauksen viivästystä siirtymän aikana, eikä mikään rikkonut sen jälkeen.

Reactin sisäänrakennettu React.lazy-funktio viivästettyjen komponenttien lataamiseksi kuitenkin saattaa aiheuttaa joitain ongelmia nopean iteroinnin aikana. Loimme pienen kirjaston nimeltä react-safe-lazy ongelmien ratkaisemiseksi. Se on pudotusvaihtoehto React.lazylle, ja yksityiskohtainen selitys löytyy tästä blogikirjoituksesta.

Pakkaus

On olemassa kätevä plugin nimeltä vite-plugin-compression pakattujen resurssien tuottamiseksi. Se tukee sekä gzip- että brotli-pakkausta. Määritys on yksinkertainen:

Manuaaliset kontit

Yksi hieno ominaisuus Viteessa (tai taustalla olevassa Rollupissa) on manuaaliset kontit. Vaikka React.lazy käytetään komponenttien laiskaan lataamiseen, meillä on enemmän hallintaa kontteihin määrittämällä manuaaliset kontit päättääksemme, mitkä komponentit tai moduulit pitäisi niputtaa yhteen.

Esimerkiksi voimme ensin käyttää vite-bundle-visualizer analysoidaksemme paketin kokoa ja riippuvuuksia. Sitten voimme kirjoittaa asianmukaisen funktion lohkojen jakamiseksi:

Kehityspalvelin

Toisin kuin tuotantorakenne, Vite EI niputa lähdekoodiasi kehitystilassa (mukaan lukien linkitetyt riippuvuudet samassa monorepossa) ja käsittelee jokaista moduulia tiedostona. Meille selain lataa satoja moduuleja ensimmäisellä kerralla, mikä näyttää hullulta, mutta se on oikeastaan fine useimmissa tapauksissa. Voit nähdä keskustelun tässä.

Jos tämä on sinulle ongelma, vaihtoehtoinen mutta epätäydellinen ratkaisu on listata linkitetyt riippuvuudet optimizeDeps-vaihtoehtoon vite.config.ts-tiedostoossa:

Tämä "ennakkoniputtaa" linkitetyt riippuvuudet ja nopeuttaa kehityspalvelinta. Haittapuoli on, että HMR ei välttämättä toimi odotetusti linkitetyillä riippuvuuksilla.

Lisäksi käytämme välityspalvelinta, joka palvelee staattisia tiedostoja tuotannossa ja välittää pyynnöt Vite-palvelimeen kehityksessä. Meillä on joitain määritettyjä portteja konfliktien välttämiseksi, ja se on myös helppo määrittää vite.config.ts-tiedostoossa:

Ympäristömuuttujat

Toisin kuin Parcel, Vite käyttää modernia lähestymistapaa ympäristömuuttujien käsittelyyn käyttämällä import.meta.env. Se lataa automaattisesti .env-tiedostot ja korvaa muuttujat koodissa. Se vaatii kuitenkin, että kaikilla ympäristömuuttujilla on VITE_-etuliite (määritettävissä).

Kun käytimme Parcelia, se yksinkertaisesti korvasi process.env-muuttujat ilman etuliitteen tarkistamista. Joten olemme keksineet kiertotavan käyttämällä define-kenttää helpottamaan siirtymää:

Tämä sallii meidän lisätä vähitellen etuliitteen ympäristömuuttujille ja poistaa define-kentän.

Yhteenveto

Siinä se! Olemme onnistuneesti siirtäneet kolme frontend-projektiamme Parcelista Viteen, ja toivomme, että tämä lyhyt tarina voi auttaa sinua omassa siirtymässäsi. Tässä miltä konfiguraatio näyttää lopussa: