Browserslist: užitečný nástroj, který funguje jinak, než jste si možná mysleli
Jako frontendoví vývojáři se u každého projektu rozhodujeme, které prohlížeče (a v kterých verzích) budeme podporovat a jaké technologie tím pádem můžeme použít. Dohoda se vytesá do kamene zvaného Browserslist. Ten ale možná funguje jinak, než jste čekali.
Diskuze o podpoře prohlížečů se zpravidla vede mezi dvěma tábory. Obchodníci a product owneři se dožadují co nejširší podpory, aby s produktem oslovili co nejširší publikum. Vývojáři zase bývají lačni moderních technologií, které jim sice zjednoduší život, ale budou pravděpodobně fungovat jen v nejnovějších prohlížečích. Jak už to bývá, výsledek dohody nakonec bude někde uprostřed. Kompromis mezi pokrytím uživatelů a nákladností vývoje se vytesá do kamene zvaného Browserslist.
Nejznámějším nástrojem, který Browserslist využívá, je pro webové kodéry bezpochyby Autoprefixer. Ten podle požadované kompatibility automaticky ošetřuje CSS tak, že bude fungovat ve všech cílových prohlížečích, pokud si s tím Autoprefixer umí poradit. Ošetření historicky spočívá zejména v doplnění tzv. vendor prefixů k těm CSS vlastnostem, které prohlížeče začaly iniciativně podporovat ještě předtím, než byla schválena jejich finální specifikace. Dnes Autoprefixer zvládá nejen prefixy CSS vlastností a hodnot, ale i zajištění kompatibility pokročilejších media queries nebo dokonce dovede za určitých podmínek zprovoznit CSS grid v IE 11.
Nástroje využívající Browserslist
Autoprefixer není zdaleka jediným nástrojem, který Browserslist využívá. Čím je PostCSS pro CSS, tím je Babel je pro JavaScript. Javascriptovým Autoprefixerem je pak @babel/preset-env
(k němu existuje analogicky bližší projekt PostCSS Preset Env). Transformace javascriptového kódu je řádově složitější než kosmetické úpravy CSS, ale právě díky Babelu si můžeme užívat krásy a syntaktické vymoženosti nejnovější verze ECMAScriptu (což je specifikace jazyka, kterou JavaScript implementuje).
Specialitou Babelu je něco, co CSS z principu neumí: možnost cestovat do budoucnosti. S Babelem je možné používat i syntaxi, která v prohlížečích a javascriptových enginech teprve bude implementovaná, neboť kód bývá možné převést do méně elegantní, ale strojům široce srozumitelné podoby. A pokud nestačí transformace kódu do formy čitelné starším prohlížečům, Babel umí doplnit i potřebné polyfilly, o nichž se sám rozhodne právě díky zadání od Browserslistu.
Zatímco Babel a Autoprefixer se starají o zpětnou kompatibilitu již napsaného kódu, existují i nástroje, které vás budou varovat ještě předtím, než nekompatibilní kód napíšete (nebo přesněji ihned poté). Pokud používáte Stylelint nebo ESlint (měli byste), můžete sáhnout po pluginech eslint-plugin-compat
a stylelint-no-unsupported-browser-features
. Ty vás upozorní, pokud napíšete kód, který nebude fungovat v prohlížečích, na které cílíte.
Pozoruhodným nástrojem je PostCSS Normalize. Používáte-li ve svém projektu populární normalize.css, tento PostCSS plugin z něj vytáhne jen takové fragmenty, které jsou pro vaše cílové prohlížeče potřeba, a ušetří tak nějaké ty bajty výsledného kódu.
Ti z vás, kdo testují automatizovaně na BrowserStacku, ocení npm modul browserslist-browserstack
. Ten umí spustit automatizované vizuální testy na BrowserStacku ve všech prohlížečích, které definuje Browserslist. Nastavení je možné dále filtrovat i rozšiřovat podle prohlížečů nebo operačního systému, takže své zakoupené testovací minuty budete mít pod kontrolou.
Je vidět, že nástrojů řešících kompatibilitu s cílovými prohlížeči je celá řada. Ačkoli každý z nich lze konfigurovat samostatně, Browserslist je logickým vyústěním snahy udržovat konfiguraci cílových prohlížečů (nebo verzí Node) na jediném místě.
Možnosti konfigurace
A jak vlastně taková sdílená konfigurace vypadá? Správná otázka. Cílové prohlížeče vašeho projektu můžete popsat jednoduchými dotazy:
last 2 years
> 1%
not dead
Browserslist na toto zadání odpoví vrácením seznamu všech prohlížečů a jejich verzí, které:
- byly vydány v posledních dvou letech,
- dále těch, které mají alespoň 1% zastoupení mezi uživateli,
- a vyloučí takové prohlížeče nebo jejich verze, které již nejsou udržované.
Konfiguraci můžete uložit dle svých preferencí do souboru .browserslistrc
nebo, máte-li raději všechna nastavení nástrojů na jednom místě, do package.json
. Pokud ji potřebujete sdílet mezi více projekty, můžete namísto kopírování vytvořit vlastní npm balíček, třeba tak, jako to má WordPress. Zápis se pak logicky liší podle formátu uložení: jednoduchý textový formát .browserslistrc
, JSON pole v package.json
nebo javascriptové pole v index.js
ve vašem sdíleném npm balíčku.
Pokročilé projekty mohou využít strukturování konfigurace do sekcí podle cílového prostředí nebo účelu. To je užitečné třeba v případech, kdy generujete více verzí CSS nebo JS balíků podle toho, pro jaké prohlížeče jsou určeny: lehká a rychle se načítající varianta pro moderní prohlížeče, důkladně ošetřená a polyfilly doplněná objemnější verze pro starší prostředí. Nebo rozdělit nastavení na mobilní a desktopové prohlížeče. Anebo vyžadovat rozdílnou podporu na vývojovém, testovacím a produkčním prostředí – záleží jen na vás. Browserslistu pak stačí předat zvolené prostředí pomocí environment variable BROWSERSLIST_ENV
nebo NODE_ENV
(není-li definováno, hledá se prostředí production
, a pokud nelze nalézt ani to, volí se defaults
).
[production]
> 1%
ie 10
[modern]
last 1 chrome version
last 1 firefox version
Vzhledem k tomu, že nástroje podporující Browserslist si jej samy instalují jako svoji závislost, není třeba Browserslist jako takový do projektu explicitně instalovat – stačí pouze udržovat jeho konfiguraci.
Které prohlížeče mám vlastně podporovat?
Otázkou je, podle čeho se rozhodnout, které z prohlížečů – a v jakých verzích – vlastně podporovat. Přece podle toho, co používají naši uživatelé, chtělo by se říci. To zní rozumně, ale jak na to?
U nového projektu ještě patrně nemáme k dispozici statistiky návštěvnosti, z kterých bychom mohli takovou informaci čerpat. Můžeme tedy vystřelit od boku a zeptat se Browserslistu, jaké prohlížeče se používají v našem cílovém geografickém regionu:
>= 0.5% in CZ
>= 1% in alt-EU
Browserslist vrátí seznam těch prohlížečů a jejich verzí, které mají v Česku alespoň 0,5% zastoupení a dále těch, které používá v EU alespoň 1 % uživatelů (pozor, k datu vydání článku zahrnuje IE 11).
Pokud statistiku návštěvnosti k dispozici máme, můžeme si dovolit být mnohem přesnější a cílit na ty prohlížeče, které naše publikum skutečně používá. Trik spočívá v poskytnutí souboru se statistikami browserslist-stats.json
, nejsnadněji na úrovni souboru .browserslistrc
, kde si jej Browserslist sám najde. Vlastní statistiky i nadále můžete kombinovat s obecnými dotazy:
cover 99.5% in my stats
>= 1% in CZ
A jak statistiku vygenerovat? Používáte-li Google Analytics, možnosti jsou dvě:
- Bezpečnou volbou je vytvořit v Google Analytics vlastní přehled (custom report), stáhnout jeho výstup ve formátu CSV a takto získaná tabulková data konvertovat do JSON pomocí nástroje
browserslist-ga-export
. - Snadnější je využít nástroj
browserslist-ga
, s kterým odpadá nutnost vytváření vlastního přehledu a manipulace s CSV, ovšem za cenu toho, že nástroji předáte heslo ke svému Google účtu.
Pro integraci s Adobe Analytics existuje browserslist-adobe-analytics
.
Na co si dát pozor
Konfigurace Browserslistu má svá úskalí.
Pouze jednoduché dotazy. Výrazy není možné sdružovat do závorek, např. lákavé (>= 0.5% in CZ or >= 2%) and last 2 versions
nebude fungovat.
Z čárky není cesty zpět. Čárka (nebo nový řádek) v konfiguraci Browserslistu má význam nebo (or
). Jakmile ji jednou použijete, není možné použít operátor and
na začátku následujícího dotazu. Proto => 0.5% [čárka nebo nový řádek] and last 2 versions
nebude fungovat. Jediným univerzálně použitelným logickým operátorem je not
, který má stejný význam ve spojení s or
i s and
: > 0.5% and not last 2 versions
i > 0.5% or not last 2 versions
vedou ke stejnému výsledku. Také díky tomu umíme vyloučit používané, ale nepohodlné exponáty dotazem typu >= 0.5%, not ie <= 11
. Možnosti logických výrazů pěkně ilustruje dokumentace:
Pravidelně aktualizujte. Nové verze prohlížečů vychází často, a proto je dobré udržovat svoji lokální databázi aktuální, aby odrážela skutečný stav tržních podílů jednotlivých prohlížečů. Jednou za několik týdnů (nebo alespoň měsíců) byste měli aktualizovat databázi Can I Use na nejnovější verzi:
npx browserslist@latest --update-db
Pokud jste v konzoli někdy zahlédli hlášku Browserslist: caniuse-lite is outdated, je to právě proto, abyste s dotazem last 1 Chrome version
a tři roky starou databází necílili na Chrome 70 ve chvíli, kdy je aktuální verze 90. Méně izolovanou alternativou je plošná aktualizace všech npm závislostí pomocí npm update
či yarn upgrade
. I tak je ale vhodné spustit příkaz výše, pokud používáte víc než jeden nástroj závisející na Browserslistu, abyste sjednotili jejich databáze, které mohly být nainstalovány v různých verzích. Míříte-li na své publikum pomocí vlastních statistik v browserslist-stats.json
, měli byste je čas od času rovněž aktualizovat.
A nakonec to nejzásadnější:
Testujte svoji konfiguraci. Pokud všechno ostatní z tohoto článku zapomenete, toto si zapamatujte:
npx browserslist
Tímto příkazem Browserslist (prostřednictvím npx) vypíše seznam podporovaných prohlížečů podle konfigurace v .browserslistrc
nebo package.json
v aktuálním adresáři. Není-li nalezena, je to totéž, jako byste volali npx browserslist 'defaults'
.
(Pro úplnost: kdysi existoval web browsersl.ist, kde bylo konfiguraci možné otestovat online. Ten je však aktuálně mimo provoz a hledá finance k obnovení.)
Prohlížečů je v dnešní době tolik, že se možná budete divit, jaké všechny exotické kousky jste nevědomky prohlásili za vámi podporované. A to ještě Browserslist nerozeznává zdaleka vše, co je na trhu s prohlížeči k dispozici, ale sdružuje mnohé „obálkové“ prohlížeče podle jejich technologického jádra (což nakonec nevadí, pokud se chovají stejně).
Zaprášená, kdysi automatizovaná a dávno zapomenutá podpora dnes již nepoužívaných nebo archaických prohlížečů může mít za následek znatelný nárůst velikosti vašeho CSS a JS, na který doplatí všichni uživatelé, pokud jim neservírujete různě sestavené verze kódu podle cílových zařízení. To je přinejmenším znepokojivé, ne-li rovnou děsivé.
V tomto světle je dobré vědět, že na pohled rozumná a banální konfigurace:
>= 0.5%
last 2 versions
Firefox ESR
not dead
# … mimochodem totéž jako:
defaults
… vás mj. zavazuje k podporování prohlížeče Baidu, Opery Mini a Internet Exploreru 11:
npx browserslist '>= 0.5%, last 2 versions, Firefox ESR, not dead'
and_chr 92
and_ff 90
and_qq 10.4
and_uc 12.12
android 92
baidu 7.12
chrome 92
chrome 91
chrome 90
edge 92
edge 91
firefox 90
firefox 89
firefox 78
ie 11
ios_saf 14.5-14.7
ios_saf 14.0-14.4
ios_saf 13.4-13.7
kaios 2.5
op_mini all
op_mob 64
opera 77
opera 76
safari 14.1
safari 14
samsung 14.0
samsung 13.0
Sebelepší definice podporovaných prohlížečů mají omezenou časovou platnost a měli byste je čas od času revidovat. Také nastavení defaults
je ošemetné, protože se jednou může změnit a vy nebudete vědět jak. Minimalismus v tomto případě není namístě. Nebo je libo servírovat prefixy a polyfilly pro IE 11, 10 a 9?
last 3 versions
Možná ano, pravdpodobně ne. Jak se tomu vyhnout? npx browserslist
!
Související odkazy
- Browserslist is a Good Idea (Chris Coyier, CSS Tricks, 2017)
- Speed up with Browserslist (Dan Onoshko, dev.to, 2020)
- Smart Bundling: How To Serve Legacy Code Only To Legacy Browsers (Shubham Kanodia, Smashing Magazine, 2018)
Další články od autora:
Sdílejte
Líbí se vám článek? Podpořte jej sdílením!
Komentujte
Chcete k článku něco doplnit? Našli jste chybu? Napište e-mail.