Krótsze Nazwy Stylów w Next.js

Jeżeli przy pracy z frameworkiem Next.js zdarzyło Ci się użyć Component-Level CSS to zapewne rzucił Ci się w oczy fakt, że automatycznie generowane nazwy klas są kosmicznie grube. Wynika to z faktu, że Next musi zagwarantować unikalność nazw by uniknąć kolizji.

// Loading...

Czasem jednak zdarzy się strona internetowa, przykładowo Pusio.pl, gdzie w kodzie CSS nie nasrał słoń 🐘. W takim przypadku warto by skrócić te auto generowane nazwy, tak żeby zachować niski poziom kupy w kodzie.

Można to osiągnąć grzebiąc w pliku next.config.js, trzeba tam zmienić konfigurację webpack, wyszukać plugin css-loader i podmienić mu funkcję getLocalIdent na własną implementację. Poniższy wycinek kodu pokazuje jak się tam podpiąć.

// Loading...

W tej implementacji metoda podmienia się tylko w produkcyjnym buildzie => if(!dev) .

Musimy jedynie zaimplementować naszą własną funkcję customGetLocalIdent i nazwy klas się wygenerują inaczej.

Wersja z Dziadowym Hashem

Na podstawie tej dyskusji na stackoverflow.com możemy napisać kod losujący string (funkcja randomString). Funkcja ta została trochę zmodyfikowana, tak by generowała legalne nazwy klas CSS (pierwszy znak nie jest liczbą). W przypadku kolizji przelosowujemy ponownie string (funkcja uniqueRandomString).

// Loading...

Ta implementacja generuje losowe 4 znakowe nazwy klas.

// Loading...

Pełną implementację tego rozwiązania dla copypasty:

// Loading...

Wersja z Prawdziwym Hashem

Poprzednie rozwiązanie jest całkiem dobre, ale zawiera w sobie pętle while, która śmierdzi. Jeżeli nie przeszkadza Ci zainstalowanie zewnętrznej biblioteki to możemy podmienić naszą dziadową funkcję do generowania losowych ciągów znaków na porządniejszy hash.

Poniższe rozwiązanie jest oparte o ten snippet kodu znaleziony na GitHubie. Na start trzeba zainstalować bibliotekę loader-utils, z której wykorzystamy metodę getHashDigest.

npm i loader-utils --save-dev

Co prawda w NodeJS istnieje sposób na wygenerowanie hasha md5 bez udział zewnętrznych bibliotek. Niestety wbudowana biblioteka crypto generuje pełen 32 znakowy hash md5. A jest to trochę za dużo jak na nazwę klasy css. Dla porównania metoda z loader-utils pozwala jako ostatni parametr podać oczekiwaną długość hasha. Jest to bardzo przydatne w tym zastosowaniu. Poniższy kod generuje 4 znakowy md5 jako nazwę klasy css.

// Loading...

Oczywiście nic nie jest perfekcyjne. Zawsze istnieje ryzyko powstania kolizji, im mniej znaków przydzielisz na hash tym ryzyko jest większe.

Pełną implementację tego rozwiązania dla copypasty:

// Loading...

Na mojej stronie jest użyty 4 znakowy hash, bo lubie życie na krawędzi. Jeżeli jednak pracujesz nad komercyjnym rozwiązaniem, to może dla bezpieczeństwa podkręć hash do 6 znaków. Tak na wszelki wypadek. 🐈