IlmHamroh
JavaScript Full-stack/16-qism. Frontend asboblari: npm, bundlerlar, config22/48-dars16 daqiqa
Mundarija (26)

Polyfill, browserslist va Baseline: build.target, core-js va plugin-legacy

Qisqacha: Loyiha qaysi brauzerlarda ishlashi kerakligini bir joyda yozish kerak. browserslist buni so'rov bilan (defaults, last 2 versions, baseline widely available) yozadi va Babel, Autoprefixer, plugin-legacy uni o'qiydi. Vite esa o'z sozlamasidan — build.target dan foydalanadi. Muhim farq: transpiler sintaksisni eski brauzerga moslaydi (#private → WeakMap), lekin yetishmagan API'ni (Object.groupBy) qo'shmaydi — buning uchun polyfill (core-js) kerak. vazifalar da polyfill o'rniga build.target ni kodimiz ishlatadigan eng yangi API'ga moslab yozamiz.

Bu darsda

  • browserslist so'rovlarini yozasiz va ular qamrovini o'lchaysiz.
  • Baseline va Vite'ning "baseline-widely-available" sukutini solishtirasiz.
  • build.target sintaksisni qanday o'zgartirishini, API'ni esa o'zgartirmasligini haqiqiy build'da ko'rasiz.
  • @vitejs/plugin-legacy nima qilishini va uning narxini (hajm, vaqt, CSP) bilasiz.
  • vazifalar ga to'g'ri build.target ni hisoblab yozasiz.

Oldin bilishingiz kerak: JS versiyalari va brauzer mosligi, PostCSS, Autoprefixer va browserslist, Transpilyatsiya, Bundler nima.

1. Nega bu kerak?

JS versiyalari darsida uch g'oyani o'rgandik: Baseline belgisi, polyfill (yetishmagan metodni qo'shish) va transpile (sintaksisni qayta yozish). PostCSS darsida browserslist CSS prefikslarini boshqardi. U darslarda bir va'da bor edi: "bu qoidani loyiha sozlamasiga yozamiz". Bugun yozamiz — va bitta tuzoqni topamiz.

vazifalar ning royxat.ts faylida teglar bo'yicha guruhlash bor:

ts
const guruhlar = Object.groupBy(vazifalar, (v) => v.teg);

Vite sukut bo'yicha qaysi brauzerlar uchun yig'adi? Uning node_modules/vite/dist/node/chunks/node.js faylida:

js
const ESBUILD_BASELINE_WIDELY_AVAILABLE_TARGET = [
	"chrome111",
	"edge111",
	"firefox114",
	"safari16.4",
	"ios16.4"
];

Object.groupBy esa Chrome 117, Firefox 119 va Safari 17.4 dan beri bor. Ya'ni Vite "Firefox 114 da ishlaydi" deb yig'adi, sahifa esa Firefox 114–118 da teglar hisobida TypeError: Object.groupBy is not a function bilan yiqiladi. Build xatosiz o'tadi. Bu darsdagi asosiy saboq shu: Vite sintaksisni moslaydi, API qo'shmaydi.

Hayotiy o'xshatish: «Bahor» menyusini rus tiliga tarjima qildingiz (transpile) — mijoz o'qiy oladi. Lekin "qozon kabob" taomi oshxonada umuman yo'q bo'lsa, tarjima uni pishirib bermaydi. Uni boshqa joydan olib kelish kerak (polyfill).

Maslahat: Chiqishlar 2026-10-10 da Node 24.21.0 bilan: browserslist 4.29.3 (caniuse-lite 1.0.30001815), web-features 3.40.1, Vite 8.3.3, @vitejs/plugin-legacy 8.2.3.

2. browserslist

2.1 So'rovlar va qamrov

browserslist — "qaysi brauzerlar?" savoliga so'rov tili. U caniuse ma'lumotlaridan (caniuse-lite paketi) foydalanadi. Uchta keng tarqalgan so'rovni o'lchadik:

bash
npx browserslist --coverage "defaults"
text
These browsers account for 84.65% of all users globally
So'rov Brauzer versiyalari Dunyo qamrovi
defaults 35 84.65 %
last 2 versions 30 53.21 %
baseline widely available 134 87.4 %

defaults — "0,5 % dan ko'p ulushli, har birining oxirgi 2 versiyasi, Firefox ESR, o'lmaganlar" (JS versiyalari darsida ochganmiz). So'rov last 2 versions esa juda tor: atigi 53 %, chunki yangilanmagan telefonlar tushib qoladi. So'rov baseline widely available — Baseline'da "keng tarqalgan" imkoniyatlar ishlaydigan hamma versiyalar, 134 qator, eng katta qamrov.

2.2 Qayerga yoziladi

Ikki joydan biriga — ikkalasiga emas:

text
# .browserslistrc — loyiha ildizida
baseline widely available

yoki package.json da "browserslist": ["baseline widely available"]. Ikkalasi bo'lsa, browserslist to'xtaydi: …\ikki contains both .browserslistrc and package.json with browsers — "papkada ham .browserslistrc, ham brauzerli package.json bor". O'quvchi uchun eng qulayi — .browserslistrc: izoh yozsa bo'ladi.

Kim o'qiydi: Babel (preset-env), Autoprefixer, PostCSS, @vitejs/plugin-legacy, Lightning CSS (sozlansa), SWC (env.targets). Kim o'qimaydi: Vite'ning o'z JS build'i — u build.target ga qaraydi. Shuning uchun vazifalar da .browserslistrc yo'q — u hech narsani o'zgartirmasdi va "yozilgan, demak ishlayapti" degan yolg'on ishonch berardi.

2.3 Ma'lumot eskiradi: update-browserslist-db

Brauzer versiyalari ro'yxati caniuse-lite paketida — lock-faylda qotib qoladi. Eski lock bilan:

bash
npx browserslist
text
Browserslist: browsers data (caniuse-lite) is 7 months old. Please run:
  npx update-browserslist-db@latest
  Why you should do it regularly: https://github.com/browserslist/update-db#readme

"Brauzerlar ma'lumoti 7 oylik. Iltimos, yangilang — nega muntazam qilish kerakligi havolada". Yangilaymiz:

bash
npx update-browserslist-db@1.3.3
text
Registry latest:         1.0.30001815
Installed version:       1.0.30001782
Removing old caniuse-lite from lock file
Installing new caniuse-lite version
$ npm install caniuse-lite baseline-browser-mapping
Cleaning package.json dependencies from caniuse-lite
$ npm uninstall caniuse-lite baseline-browser-mapping
caniuse-lite has been successfully updated

No target browser changes

Buyruq lock-fayldagi caniuse-lite ni yangiladi va oxirida aytdi: "maqsad brauzerlar o'zgarmadi". O'zgarsa — qaysi versiyalar qo'shilgani yoki tushganini ro'yxat bilan chiqaradi. Nega muntazam: defaults "oxirgi 2 versiya" deydi — ma'lumot eski bo'lsa, siz 7 oy oldingi "oxirgi" versiyalar uchun yig'asiz.

Tekshirib ko'ring: Sardor .browserslistrc ga last 2 versions yozdi va "eng yangi brauzerlar — eng xavfsiz tanlov" dedi. Nima noto'g'ri?

Javob

Qamrov — atigi 53 %. "Oxirgi 2 versiya" har brauzerga bir xil qaraydi: kam ishlatiladigan brauzerlarning oxirgi versiyalari kiradi, ko'p ishlatiladigan, lekin bir oz eski telefon brauzerlari esa tushib qoladi. defaults (84.65 %) yoki baseline widely available (87.4 %) — haqiqiy foydalanuvchilarga yaqinroq. Har doim --coverage bilan tekshiring.

3. Baseline va Vite

3.1 Ikki xil "widely available"

JS versiyalari darsidan: Baseline "widely available" — imkoniyat hamma asosiy brauzerda paydo bo'lganiga 30 oy o'tgan. Bu ro'yxat har kuni siljiydi. Bugun browserslist'ning baseline widely available so'rovida eng kichik versiyalar:

text
chrome 123
edge 123
firefox 124
safari 17.4
ios_saf 17.4

Vite 8.3.3 ning "baseline-widely-available" sukuti esa chrome111, firefox114, safari16.4. Vite'ning tur tavsifida (index.d.ts) sababi yozilgan: "browsers that are included in the Baseline Widely Available on 2026-01-01" — "2026-01-01 kunidagi Baseline Widely Available brauzerlari". Ya'ni Vite ro'yxati qotirilgan sana bo'yicha, browserslist'niki — bugungi. Ikkalasi ham "Baseline", lekin farq Safari'da bir yarim yil.

3.2 Imkoniyat qachondan "keng"?

web-features paketi (Baseline ma'lumotlarining manbai) bilan vazifalar ishlatadigan eng yangi imkoniyatlarni tekshirdik:

Imkoniyat Baseline Chrome / Firefox / Safari
Object.groupBy (array-group) widely, 2026-09-05 dan 117 / 119 / 17.4
toSorted (array-by-copy) widely, 2026-01-04 dan 110 / 115 / 16
<link rel="modulepreload"> widely, 2026-03-18 dan 66 / 115 / 17
blocking="render" yo'q (Firefox'da yo'q) 105 / — / 18.2

Object.groupBy atigi bir oy oldin "widely available" bo'ldi — Vite'ning 2026-01-01 ro'yxatida u hali yo'q edi. blocking="render" — Firefox'da umuman yo'q, lekin bu HTML atributi: tanimagan brauzer uni shunchaki e'tiborsiz qoldiradi, sahifa buzilmaydi.

4. build.target: sintaksis ha, API yo'q

4.1 Tajriba

Kichik loyiha — main.js:

js
// main.js — taomlarni turiga qarab guruhlash
class Menu {
  #dishes = []; // private maydon — ES2022 sintaksisi

  add(name, type, price) {
    this.#dishes.push({ name, type, price });
  }

  byType() {
    // Object.groupBy — API (metod), sintaksis emas
    return Object.groupBy(this.#dishes, (dish) => dish.type);
  }
}

const menu = new Menu();
menu.add("Osh", "taom", 35000);
menu.add("Manti", "taom", 30000);
menu.add("Ko'k choy", "ichimlik", 5000);
console.log(Object.keys(menu.byType())); // [ 'taom', 'ichimlik' ]

Ikkita "yangi" narsa: #dishes — sintaksis (ES2022), Object.groupBy — API (ES2024 metodi). Uch xil target bilan yig'dik:

bash
npx vite build --target es2020
--target Hajm WeakMap Object.groupBy
sukut (baseline-widely-available) 0.96 kB 0 o'zgarmagan
es2020 1.34 kB 1 o'zgarmagan
esnext 0.96 kB 0 o'zgarmagan

ES2020 brauzerlari #private ni bilmaydi, shuning uchun Vite (ichida Oxc) uni qayta yozdi. Minifikatsiyasiz build'dan (--minify false) parcha:

text
var _dishes = /* @__PURE__ */ new WeakMap();
var Menu = class {
	constructor() {
		_classPrivateFieldInitSpec(this, _dishes, []);
	}
	byType() {
		return Object.groupBy(_classPrivateFieldGet2(_dishes, this), (dish) => dish.type);
	}
};

#dishes — yashirin WeakMap va yordamchi funksiyalar bo'ldi (_classPrivateFieldGet2 — ular fayl tepasida qo'shilgan, +0.38 kB). Object.groupBy esa harfma-harf o'sha. ES2020 brauzerida bu qator yiqiladi.

4.2 Nega Vite polyfill qo'shmaydi

Vite'ning index.d.ts dagi build.target tavsifi: "…syntax transformation and does not cover polyfills" — "faqat sintaksisni o'giradi, polyfill'larni qamramaydi". Sabab bor: polyfill — qo'shimcha kod, ko'pincha katta. Uni "har ehtimolga" qo'shish zamonaviy brauzer foydalanuvchilarini (ko'pchilik) bekorga jazolaydi.

flowchart TB
  K["Kodingiz"] --> S{"yangi narsa<br/>nima?"}
  S -->|"sintaksis:<br/>#x, ?., ??"| T["build.target<br/>Oxc qayta yozadi"]
  S -->|"API:<br/>Object.groupBy"| P{"target bu API'ni<br/>qamraydimi?"}
  P -->|ha| OK["hech narsa kerak emas"]
  P -->|yo'q| X["target'ni ko'taring<br/>yoki polyfill"]

Ikki yo'l bor: target'ni kodga moslash (eski brauzerlarni ongli ravishda qo'llamaslik) yoki polyfill qo'shish.

4.3 CSS ham target'ga bog'liq

build.target faqat JavaScript'ga emas, CSS'ga ham ta'sir qiladi (alohida sozlama — build.cssTarget, sukut bo'yicha build.target bilan bir xil). Vite 8 CSS'ni Lightning CSS bilan qayta ishlaydi — PostCSS va Lightning CSS darsidagi vosita. Sinov uchun menyu.css:

css
/* menyu.css — zamonaviy CSS: nesting va light-dark() */
:root { color-scheme: light dark; }
.menyu {
  color: light-dark(#14201a, #e8f0ea);
  & li { padding: 0.5rem; }
}

Sukut target bilan (Safari 16.4 da light-dark() yo'q) chiqqan CSS:

text
:root{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark}@media (prefers-color-scheme:dark){:root{--lightningcss-light: ;--lightningcss-dark:initial}}.menyu{color:var(--lightningcss-light,#14201a)var(--lightningcss-dark,#e8f0ea)}.menyu li{padding:.5rem}

light-dark() — o'zgaruvchilar va @media bilan qayta yozilgan, nesting (& li) — oddiy .menyu li selektoriga ochilgan. 0.27 kB. target: ["chrome123", "edge123", "firefox120", "safari17.5"] bilan (light-dark() bor brauzerlar):

text
:root{color-scheme:light dark}.menyu{color:light-dark(#14201a,#e8f0ea);& li{padding:.5rem}}

0.09 kB — uch baravar kichik, chunki hech narsa qayta yozilmadi. CSS'da ham qoida o'sha: zamonaviy sintaksis eski brauzer uchun qayta yoziladi, lekin narxi — hajm. vazifalar da --target es2020 sinovida CSS 3.59 dan 3.80 kB ga o'sgani shundan.

5. Polyfill: core-js va plugin-legacy

5.1 core-js

JS versiyalari darsida core-js'ni ko'rgan edik: import "core-js/actual/object/group-by.js" bitta metodni qo'shadi. Qo'lda bitta-bitta ulash — xatoga moyil. Avtomatlashtirish uchun Vite'da rasmiy plagin bor.

5.2 @vitejs/plugin-legacy

Plagin ikkinchi, "eski" build yasaydi: Babel bilan o'giradi va kerakli core-js polyfill'larini qo'shadi. Uning peerDependencies ida terser (eski minifikator) ham bor.

js
// vite.config.js — eski brauzerlar uchun alohida "legacy" build
import legacy from "@vitejs/plugin-legacy";
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [legacy({ targets: ["defaults", "safari >= 13"] })],
});

targets — browserslist so'rovi (plagin .browserslistrc ni ham o'qiydi). Natija:

text
dist/assets/index-legacy-CJ9-TSJ_.js       1.43 kB │ gzip:  0.77 kB
dist/assets/polyfills-legacy-DvG1yjGt.js  32.60 kB │ gzip: 11.86 kB
…
dist/index.html                1.47 kB │ gzip: 0.68 kB
dist/assets/index-NM8txHdE.js  1.57 kB │ gzip: 0.85 kB
✓ built in 29.28s

(O'rtadagi bosqich qatorlari qisqartirildi.) Uch narxni sanaymiz:

Narx Plaginsiz Plagin bilan
Build vaqti 0.1–0.3 s 29.3 s
Fayllar 1 JS 3 JS
Eski brauzer yuklaydi — 32.60 kB polyfill (gzip 11.86)

29 soniyaning 26 tasi — Vite'ning o'z hisobotiga ko'ra vite:legacy-post-process (Babel). index.html da esa endi <script nomodule> va inline (fayl manzilisiz, ichida kod yozilgan) <script type="module"> teglari bor:

text
<script type="module">
<script type="module">
<script type="module" crossorigin src="/assets/index-NM8txHdE.js">
<script nomodule>
<script nomodule crossorigin id="vite-legacy-polyfill" src="/assets/polyfills-legacy-DvG1yjGt.js">
<script nomodule crossorigin id="vite-legacy-entry" data-src="/assets/index-legacy-CJ9-TSJ_.js">

nomodule — "modulni bilmaydigan (eski) brauzer bajarsin" (Brauzerda ESM darsida). Inline skriptlar esa vazifalar uchun to'xtatuvchi: bizning CSP script-src 'self' (XSS va DOM xavfsizligi) inline skriptni bloklaydi. Plagin CSP uchun hash'larni hujjatlarida beradi, lekin har yangilashda ularni kuzatish kerak.

Diqqat: plugin-legacy — 2016–2020 yillardagi brauzerlarni qo'llash kerak bo'lgan loyihalar uchun (davlat idoralari kompyuterlari, eski Android telefonlar). Avval statistikangizni ko'ring: foydalanuvchilaringizning necha foizi eski brauzerda? vazifalar da bunday foydalanuvchi yo'q — plagin kanonga kirmaydi.

Tekshirib ko'ring: Nega plugin-legacy zamonaviy brauzer foydalanuvchisini sekinlashtirmaydi, garchi dist/ 32 kB ga kattalashgan bo'lsa ham?

Javob

Zamonaviy brauzer type="module" ni biladi va nomodule skriptlarni yuklamaydi. Polyfill va legacy chunk faqat eski brauzerga ketadi. Zamonaviy brauzer faqat ikki kichik inline skriptni qo'shimcha bajaradi. Narxni asosan dasturchi (build vaqti) va CSP to'laydi.

6. vazifalar: to'g'ri build.target

Bizning tanlov: polyfill emas — target'ni kodga moslash. Hisob oddiy: kod ishlatadigan har imkoniyatning brauzer versiyalaridan eng kattasi. Object.groupBy — eng "yosh": Chrome/Edge 117, Firefox 119, Safari 17.4. toSorted (110/115/16) va modulepreload (66/115/17) undan eski — ular avtomatik qamraladi.

Ikkinchi topilma: Vite sukut bo'yicha modulepreload uchun kichik polyfill qo'shadi (Bundler nima darsida vite/modulepreload-polyfill.js ni grafda ko'rgan edik). Bizning target'dagi hamma brauzerda modulepreload bor — polyfill keraksiz.

Uch build'ni o'lchadik (index chunk):

Variant Hajm gzip
sukut (baseline-widely-available, polyfill bilan) 25.86 kB 9.67 kB
kanon (chrome117…, polyfill'siz) 25.33 kB 9.47 kB
--target es2020 (namoyish) 27.07 kB 10.04 kB

Kanon --target esnext bilan bayt-bayt bir xil chiqdi (fayl nomidagi hash ham bir xil — Dvsf2Sj6). Ya'ni bizning brauzerlar kodimizdagi hamma sintaksisni biladi — hech narsa qayta yozilmaydi. es2020 da esa #vazifalar kabi private maydonlar 6 ta WeakMap ga aylandi va kod 1.7 kB kattalashdi — eski brauzerni qo'llashning narxi.

7. Ko'p uchraydigan xatolar

Xato Oqibati To'g'risi
.browserslistrc yozildi, Vite o'qiydi deb o'ylash target o'zgarmaydi build.target
"target eski brauzerni qo'llaydi" deb ishonish API'lar yo'q, is not a function target ≥ eng yangi API yoki polyfill
caniuse-lite yangilanmaydi "oxirgi versiya" — eski npx update-browserslist-db@latest
plugin-legacy "har ehtimolga" build ×100 sekin, inline skript, CSP faqat statistika talab qilsa
package.json va .browserslistrc ikkalasida browserslist xatosi bittasida

8. Mashqlar

Mashqlar kurs/mashqlar/16/22-target/ da.

1-mashq (oson): Sintaksis yoki API?

Har biri uchun ayting: build.target uni eski brauzerga moslay oladimi?

  • a?.b —
  • Object.groupBy(...) —
  • class { #x = 1 } —
  • array.toSorted() —
  • structuredClone(obj) —
Yechim

?. va #x — sintaksis: transpiler ularni eski yozuvga qayta yozadi. Object.groupBy, toSorted, structuredClone — API (funksiya va metodlar): ularni qayta yozib bo'lmaydi, faqat polyfill qo'shiladi yoki brauzer o'zida bo'lishi kerak. Qoida: kodni o'qiy olmaslik — sintaksis; o'qiydi, lekin "is not a function" — API.

2-mashq (o'rta): Qamrovni o'lchang

npx browserslist@4.29.3 --coverage bilan uch so'rovni solishtiring: defaults, defaults and fully supports es6-module, baseline widely available. Qaysi biri vazifalar ning build.target iga eng yaqin?

Yechim

defaults — 84.65 %, baseline widely available — 87.4 %. O'rtadagisi — 84.64 %: defaults dan ES modullarni bilmaydigan brauzerlarni chiqaradi, farq atigi 0.01 %. Ya'ni defaults dagi deyarli hamma brauzer type="module" ni biladi. vazifalar ning target'i (Chrome 117+, Firefox 119+, Safari 17.4+) — baseline widely available (Chrome 123+, Safari 17.4+) dan biroz kengroq: Chrome 117–122 ham qamraladi. Lekin bu so'rovlar boshqa narsalarni (Opera, Samsung Internet) ham o'z ichiga oladi — to'liq mos ro'yxat yo'q, shuning uchun vazifalar target'ni kod asosida hisobladi.

3-mashq (qiyin): Target kalkulyatori

target.mjs yozing: minTarget(features, ids) web-features ma'lumotlari va imkoniyat ID'lari ro'yxatidan Vite build.target massivini qaytarsin — har brauzer (chrome, edge, firefox, safari) uchun eng katta versiya. Biror brauzerda imkoniyat umuman yo'q bo'lsa, uni missing ro'yxatiga yozsin.

Ishoralar: npm i -D -E web-features@3.40.1, import { features } from "web-features", features["array-group"].status.support — { chrome: "117", firefox: "119", safari: "17.4", … }. Versiyalarni satr sifatida solishtirmang: "9" > "17" — true (satrlarni solishtirish). Nuqtadan bo'lib, son qiling.

Yechim
js
// target.mjs — kod ishlatadigan imkoniyatlardan Vite build.target
// (web-features ma'lumotlari bo'yicha eng kichik brauzer versiyalari)
const BROWSERS = ["chrome", "edge", "firefox", "safari"];

// "17.4" va "16" ni son kabi solishtiramiz: 17.4 > 16
function newer(a, b) {
  const [a1, a2 = 0] = a.split(".").map(Number);
  const [b1, b2 = 0] = b.split(".").map(Number);
  return a1 !== b1 ? a1 > b1 : a2 > b2;
}

export function minTarget(features, ids) {
  const target = {};
  const missing = [];
  for (const id of ids) {
    const support = features[id].status.support;
    for (const browser of BROWSERS) {
      const version = support[browser];
      if (!version) {
        missing.push(`${id}: ${browser}`);
        continue;
      }
      const old = target[browser];
      if (!old || newer(version, old)) target[browser] = version;
    }
  }
  const viteTarget = BROWSERS.filter((b) => target[b]).map(
    (b) => `${b}${target[b]}`,
  );
  return { viteTarget, missing };
}

if (import.meta.main) {
  const { features } = await import("web-features");
  const ids = process.argv.slice(2);
  const { viteTarget, missing } = minTarget(features, ids);
  console.log("target:", JSON.stringify(viteTarget));
  if (missing.length) console.log("yo'q:", missing.join("; "));
}

Ikki test bilan (ℹ tests 2, ℹ pass 2). vazifalar ning JS imkoniyatlari:

bash
node target.mjs array-group array-by-copy modulepreload
text
target: ["chrome117","edge117","firefox119","safari17.4"]

Aynan kanondagi qiymat. search (HTML <search> elementi, Chrome 118) qo'shilsa — chrome118. Lekin u HTML: tanimagan brauzer uni oddiy <div> kabi ko'rsatadi, build.target esa faqat JS va CSS uchun. blocking-render bilan — yo'q: blocking-render: firefox: buni bilish foydali, lekin u ham HTML atributi.

4-mashq: Vazifalar qadami — build.target

  • Branch: build/target
  • Commit: build: build.target — Object.groupBy bor brauzerlar, polyfill'siz

vite.config.ts dagi build ga ikki kalit qo'shing: target (3-mashq natijasi) va modulePreload: { polyfill: false }. Build'ni sukut bilan va keyin bilan solishtiring.

Yechim
ts
  build: {
    // Qaysi brauzerlar uchun (16/#22). Vite sintaksisni shu
    // versiyalarga moslaydi, lekin API'ni (Object.groupBy...)
    // QO'SHMAYDI — polyfill yo'q. Vite'ning
    // "baseline-widely-available" i — 2026-01-01 ro'yxati
    // (chrome111, firefox114, safari16.4), bizning kodda esa
    // Object.groupBy (royxat.ts) — Chrome 117, Firefox 119,
    // Safari 17.4 dan (web-features 3.40: widely available 2026-09)
    target: ["chrome117", "edge117", "firefox119", "safari17.4"],
    // <link rel="modulepreload"> shu brauzerlarning hammasida bor —
    // Vite qo'shadigan polyfill kerak emas
    modulePreload: { polyfill: false },
Kalit Nima qiladi Sukut
build.target sintaksis qaysi brauzerlarga moslanadi "baseline-widely-available"
build.modulePreload.polyfill modulepreload polyfill'ini qo'shish true

Natija: index chunk 25.86 → 25.33 kB (gzip 9.67 → 9.47 kB), --target esnext bilan bayt-bayt bir xil. index.html va CSP o'zgarmagan.

Testlar: 145/145. Brauzer: 159/159. Diff: 1 fayl, +10.

bash
git switch -c build/target
npm run build && npm test
git add vite.config.ts
git commit -m \
"build: build.target — Object.groupBy bor brauzerlar, polyfill'siz"
git push -u origin build/target
gh pr create --fill
gh pr merge --merge

Commit sarlavhasi — 67 belgi.

9. Real ishda

  • Korporativ va davlat loyihalari ko'pincha "qaysi brauzerlar" ro'yxatini shartnomada yozadi. Ishdagi birinchi savolingiz shu bo'lsin — undan build.target va .browserslistrc kelib chiqadi.
  • Analitika (Google Analytics yoki saytingizning o'z statistikasi) — haqiqiy foydalanuvchilar brauzerlari. Target'ni taxminga emas, raqamga qarab tanlang.
  • Intervyu savollari: "Polyfill va transpile farqi?", "browserslist nima?", "Baseline nima?", "Vite polyfill qo'shadimi?".

Xulosa

  • browserslist — "qaysi brauzerlar" so'rovi (.browserslistrc yoki package.json); Babel, Autoprefixer, plugin-legacy o'qiydi, Vite'ning JS build'i — o'qimaydi.
  • caniuse-lite lock'da eskiradi — npx update-browserslist-db@latest muntazam.
  • Vite build.target sintaksisni (#private, ?.) qayta yozadi, API'ni (Object.groupBy) qo'shmaydi; sukut — 2026-01-01 dagi Baseline ro'yxati.
  • Polyfill — core-js; plugin-legacy uni avtomatlashtiradi, lekin narxi: build ~30 s, +32 kB eski brauzerga, inline skriptlar (CSP).
  • vazifalar: target kod ishlatadigan eng yangi API bo'yicha — chrome117, edge117, firefox119, safari17.4, modulePreload polyfill'siz.

Keyingi dars: Tree shaking, minifikatsiya va o'lik kodni olib tashlash — formatDollar qanday g'oyib bo'lgani, /*#__PURE__*/ va sideEffects nima qilishi va nega lodash'ni boshqacha import qilish kerak.

Manbalar

  • browserslist — github.com/browserslist/browserslist (so'rovlar, --coverage, konfiguratsiya fayllari); update-db — github.com/browserslist/update-db
  • web.dev: "Baseline" — web.dev/baseline; web-features — github.com/web-platform-dx/web-features
  • Vite: "Build Options → build.target", "build.modulePreload" — vite.dev/config/build-options
  • Vite: @vitejs/plugin-legacy README ("Content Security Policy" bo'limi) — github.com/vitejs/vite/tree/main/packages/plugin-legacy
  • core-js — github.com/zloirock/core-js
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Polyfill, browserslist va Baseline: build.target, core-js va plugin-legacy — IlmHamroh