20 Lis 2019

Jak usunąć nadmiarowy css, tailwindcss, purgecss oraz postcss

Każdy wie, że największą bolączką obecnych stron jest nadmiarowość wszelakiego kodu. Często same style dochodzą do 1MB a gdzie reszta, DOM, obrazki, skrypty, analityka google, reklamy? Do tego wszystkie te pliki css, js itd. ładowane są za jednym razem.

Większość z nas aby przyspieszyć sobie pracę korzysta z css frameworków. Czy to będzie bootstrap, semantic ui, materialize css, fundation i mógłbym jeszcze tak wymieniać i wymieniać. Najlepiej sami zobaczcie ile tego jest - awesome-css-frameworks, ale czy na pewno potrzebny nam jest cały kod np. takiego bootstrapa, no raczej nie?

Frameworki te mają też jedną poważną wadę, przynajmniej dla mnie, składają się z komponentów które jeżeli chcemy zmodyfikować to musimy nieźle się nagimnastykować z !important. Wszystko trzeba nadpisywać!.

A może by tak użyć frameworka, który nie będzie posiadał komponentów ale czyste style. Wiąże się to oczywiście z pisaniem wszystkie we własnym zakresie, ale tak możemy użyć Tailwindcss, poniżej informacja ze strony czym dokładnie jest ten framework.

Tailwind CSS to wysoce konfigurowalna, niskopoziomowa platforma CSS, która zapewnia wszystkie elementy potrzebne do tworzenia projektów na zamówienie, bez denerwujących, opiniotwórczych stylów, z którymi musisz walczyć, aby je zastąpić.

Np. aby stworzyć jakiś button musimy dodać wiele class, na początku jest to dość przerażające zobaczcie sami poniżej.

<div class="inline-block">
  <button class="hover:bg-red-400 bg-blue-600 mt-5 text-white font-bold py-2 px-4 rounded shadow">Button</button>
  <button class="hover:bg-blue-600 bg-green-600 mt-5 text-white font-bold py-2 px-4 rounded shadow">Button</button>
  <button class="bg-white hover:bg-gray-100 text-gray-800 font-semibold py-2 px-4 border border-gray-400 rounded shadow">Button</button>
</div>

Niestety ale sam Tailwindcss jest bardzo obszerny, bo cały kod po skompilowaniu waży aż 863KB. Ale możemy temu zaradzić za pomocą biblioteki purgecss oraz postcss i jeszcze kilku innych użytecznych pluginów.

Inicjalizacja package.json

Najpierw tworzymy package.json a że ja używam wszędzie yarna więc cały opis będzie na nim się opierał.

yarn init -y

Teraz instalujemy wszystkie zależności.

yarn add -D postcss-cli @fullhuman/postcss-purgecss autoprefixer cssnano tailwindcss chokidar-cli

Małe wytłumaczenie powyższych bibliotek:

  • postcss-cli, klient postcss innymi słowy narzędzie do przekształcania CSS w JavaScript
  • @fullhuman/postcss-purgecss, plugin usuwający zbędny kod css
  • autoprefixer, plugin który sam dodaje prefixy do styli, np. display: flex; zamienia na [display: -webkit-box; display: -ms-flexbox; display: flex]
  • cssnano, usuwa komentarze, nowe linie, itd. wszystko co jest zbędne w css
  • tailwindcss, nasz css framework
  • chokidar-cli, to nic innego ja biblioteka która nasłuchuje zmiana na plikach i jeżeli będzie zmiana to uruchomi nam skrypt
{
  "name": "tailwindcss",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "start": "tailwind build src/tailwind.css -o docs/style.css",
    "dev": "postcss src/tailwind.css -o docs/style.css",
    "prod": "postcss src/tailwind.css -o docs/style.css --env=production",
    "watch": "chokidar \"./docs/**/*.html\" -c \"yarn dev\""
  },
  "devDependencies": {
    "@fullhuman/postcss-purgecss": "^1.3.0",
    "autoprefixer": "^9.7.2",
    "chokidar-cli": "^2.1.0",
    "cssnano": "^4.1.10",
    "postcss-cli": "^6.1.3",
    "tailwindcss": "^1.1.3"
  }
}

Najważniejszą częścią tego jsona jest sekcja scripts. Z pomocą tej sekcji uruchamiamy różne procesy. Tak jak na początku wspominałem używam yarn więc aby wywołać jakiś proces w konsoli wystarczy wpisać:

yarn start
yarn dev
yarn prod
yarn watch

Plik z deklaracją @tailwind

W folderze src stworzyłem plik tailwind.css, poniższy plik jest niezbędny do pracy z tym frameworkiem.

@tailwind base;
@tailwind components;
@tailwind utilities;

postcss - plik konfiguracyjny

Tworzymy plik postcss.config.js który zbierze nam wszystkie niezbędne pluginy do "kupy"

// środowisko prod czy dev
const modeENV = process.env.NODE_ENV;

// funkcja do odpalania pluginów w zależności od środowiska
const prodPlugin = (plugin, argv) => {
  return argv === 'production' ? plugin : () => { };
}

// configure Cssnano
const configureCssnano = () => {
  return {
    preset: 'default'
  }
}

// configure Purgecss
const configPurgecss = () => {
  return {
    content: [
      './docs/**/*.html'
    ],
    defaultExtractor: content => content.match(/[A-Za-z0-9-_:/]+/g) || []
  }
}

module.exports = {
  plugins: [
    require('tailwindcss'),
    // autoprefixer
    prodPlugin(require('autoprefixer'), modeENV),
    // cssnano
    prodPlugin(require('cssnano')(
      configureCssnano()
    ), modeENV),
    // purgecss
    prodPlugin(
      require('@fullhuman/postcss-purgecss')(
        configPurgecss()
      ), modeENV)
  ]
}

Folder docs

W tym folderze będziemy trzymać *.html, zdjęcia itd., ale także niezbędny plik css który, będzie generowany na podstawie użytych klas w plikach html, pug, vue, jsx itd.

Tailwind konfiguracja

Oczywiście tailwind jest w pełni konfigurowalny, wystarczy że w konsoli wpiszemy:

npx tailwind init

A zostanie nam wygenerowany plik - tailwind.config.js

// tailwind.config.js
module.exports = {
  theme: {},
  variants: {},
  plugins: [],
}

W tym pliku można skonfigurować dosłownie wszystko, od marginesu przez kolory, centrowanie elementów itd. sami zobaczcie, jest to defaultConfig
Na potrzeby tego przykładu aby wycentrować container dodałem w configu poniższy kod:

module.exports = {
  theme: {
    container: {
      center: true,
      padding: '2rem'
    }
  },
  variants: {},
  plugins: []
}

Dobra mamy już wszystko co jest nam niezbędne do pracy. Do testów w package.json dodałem linijkę tailwind build src/tailwind.css -o docs/style.css wystarczy że w konsoli uruchomimy yarn start i w docs pojawi się olbrzymi plik style.css
Tą linijkę dodałem na potrzeby tego wpisu abyście sami się przekonali jak olbrzymi jest ten plik. Są to wszystkie dostępne klasy css.

Do podstawowej pracy wystarczy że uruchomimy yarn watch, jakiekolwiek zmiany w obserwowanych plikach w naszym wypadku html będą skutkowały wygenerowaniem nowego kodu style.css w folderze docs.

Jeżeli chcemy już ostatecznie wygenerować nasz kod na produkcję uruchamiamy yarn prod, zostaną uruchomione wszystkie pluginy postcss które skonfigurowaliśmy w postcss.config.js w wyniku otrzymamy mały plik tylko z niezbędnym kodem + normalize (4KB)

Oczywiście nie tylko html jest obsługiwany ale chyba wszystko co nam przyjdzie do głowy wystarczy zerknąć w dokumentację pluginu FullHuman/postcss-purgecss, możemy dodać vue, jsx, pug i wiele innych plików.

Wszystko opisałem pobieżnie bo można by było małą książkę napisać na ten tema, np. użyć do tego gulpa, webpack czy czego tam używacie.

I chyba najważniejsza rzecz że za pomocą biblioteki purgecss możemy także optymalizować inne frameworki css, ale to już temat na następny wpis jeżeli taki powstanie 😉

Ostateczny kod znajdziecie tutaj tailwind-purgecss