React aplikacija s javnim dijelom i pretpreglednim ekranima iza zastavice okruženja. Zastavica na produkciji isključena, ekrani nedostupni — a u build izlazu svejedno stoji chunk od 375 kB s cijelim pretpregledom. Nije bug u Viteu. Bug je u tome kako smo napisali provjeru.
Kako bundler uklanja mrtvi kod
Vite pri buildu doslovno zamjenjuje import.meta.env.VITE_NEŠTO vrijednošću iz okruženja. Ako u kodu piše import.meta.env.VITE_PREVIEW !== ‘true’, nakon zamjene ostaje ‘false’ !== ‘true’ — izraz koji je uvijek false. Bundler to vidi, granu proglasi mrtvom, a dinamički import unutar nje nikad ne postane zaseban chunk. To je jedini mehanizam kojim zastavica stvarno izbacuje kod iz builda.
Gdje smo ga slomili
Iz najboljih namjera izdvojili smo sve zastavice u jedan modul: const FEATURES = { previewMocks: import.meta.env.VITE_PREVIEW === ‘true’ }, pa u rutama pisali if (FEATURES.previewMocks). Čitljivije, na jednom mjestu — i neuklonjivo. Vrijednost sada dolazi kroz svojstvo objekta iz drugog modula, a bundler u trenutku kad odlučuje o chunkovima tu granu više ne može dokazati mrtvom. Ruta ostaje, lazy import ostaje, chunk se generira i deploya.
Pravilo koje smo usvojili
Zastavica koja odlučuje hoće li kod uopće postojati u buildu piše se inline, točno na mjestu grananja, kao import.meta.env izraz. Centralizirani modul ostaje za zastavice koje mijenjaju ponašanje već uključenog koda. Razlika je u pitanju koje postavljate: „treba li ovo raditi?” naspram „treba li ovo uopće biti ovdje?”
Kako to provjeriti, a ne vjerovati
Popis chunkova na kraju builda je jedini dokaz. Ako nakon isključene zastavice tamo i dalje stoji datoteka s imenom pretpreglednog modula, grana nije mrtva, ma što kod „govorio”. Tu provjeru vrijedi ugraditi u deploy skriptu: build koji proizvede chunk koji ne smije postojati trebao bi pasti, ne proći.
Zastavica koju bundler ne može pročitati kao konstantu nije zastavica — samo je uvjet koji se provjerava na produkciji.