Mundarija (27)
- Bu darsda
- 1. Nega bu kerak?
- 2. AST: kod daraxt bo'lib
- 2.1 Bitta qator — bitta daraxt
- 2.2 Uch bosqich
- 3. Bitta fayl — to'rt transpiler
- 3.1 Kirish fayli
- 3.2 Babel
- 3.3 SWC
- 3.4 esbuild
- 3.5 Oxc
- 3.6 /*#__PURE__*/ nima?
- 4. JSX: classic va automatic runtime
- 4.1 Ikki usul
- 4.2 React is not defined
- 5. Tezlik
- 6. Qaysi biri qayerda
- 7. Type stripping: faqat o'chirish yoki to'liq o'girish
- 8. Transpile ≠ typecheck — oxirgi marta
- 9. Ko'p uchraydigan xatolar
- 10. Mashqlar
- 1-mashq (oson): AST tugunlari
- 2-mashq (o'rta): Ikki runtime va targets
- 3-mashq (qiyin): O'z Babel plaginingiz
- 11. Real ishda
- Xulosa
- Manbalar
Transpilyatsiya: Babel, SWC, esbuild va Oxc — AST, JSX va TypeScript qanday o'giriladi
Qisqacha: Transpiler kodni o'qiydi, uni AST (abstrakt sintaksis daraxti) ga aylantiradi, daraxtni o'zgartiradi va qaytadan kod yozadi. Shu yo'l bilan TypeScript turlari o'chadi, JSX
jsx()chaqiruvlariga aylanadi, yangi sintaksis eski brauzer uchun qayta yoziladi. To'rt asosiy vosita: Babel (JavaScript'da, eng moslashuvchan, eng sekin), SWC (Rust), esbuild (Go) va Oxc (Rust, Vite 8 ichida). Hammasi turlarni tekshirmaydi — buni faqattscqiladi.
Bu darsda
- AST nima ekanini haqiqiy parser chiqishida ko'rasiz.
- Bitta
.tsxfaylni Babel, SWC, esbuild va Oxc bilan o'girib, natijalarni solishtirasiz. babel.config.json(preset va plagin) va.swcrcni o'qiy olasiz.- JSX'ning classic va automatic runtime farqini va
React is not definedxatosini tushunasiz. - Kichik Babel plagini yozasiz va "transpile ≠ typecheck" ni yana bir bor isbotlaysiz.
Oldin bilishingiz kerak: JS versiyalari va brauzer mosligi, JS dvigateli ichida, TypeScript build: tsc, bundler'lar va tsgo, Bundler nima.
1. Nega bu kerak?
Bundler nima darsida Vite vazifalar ning 24 modulini yig'di. Lekin modullar .ts edi, brauzerga esa oddiy JavaScript bordi. : number lar, interface lar qayerga ketdi? Buni bundler emas, uning ichidagi transpiler qildi.
Transpiler bilan avval ham uchrashgansiz. JS versiyalari darsida Babel ?. ni eski Safari uchun === null || … === void 0 ga aylantirdi. tsc va bundler'lar darsida esbuild turlarni o'chirdi va xatoni jim o'tkazib yubordi. Bugun ichkariga qaraymiz: transpiler qanday ishlaydi, nega ular to'rtta va qaysi biri qayerda.
Sardorga bu nega kerak? 17-qismda React keladi va har fayl .tsx bo'ladi — TypeScript va JSX birga. Bir kun React is not defined yoki "Babel config topilmadi" xatosini ko'radi. Uni tushunish uchun "fayl qanday o'giriladi" degan xarita kerak.
Hayotiy o'xshatish: tarjimon. U matnni so'zma-so'z emas, avval jumlani tahlil qiladi (ega, kesim, to'ldiruvchi), keyin boshqa tilda qayta quradi. Transpiler ham avval kodni "gap bo'laklariga" ajratadi — bu AST.
Maslahat: Chiqishlar 2026-10-10 da Node 24.21.0 bilan: Babel 8.0.6, SWC 1.16.13 (
@swc/cli0.8.1), esbuild 0.28.2, Oxc (oxc-transform,oxc-parser) 0.153.0.
2. AST: kod daraxt bo'lib
2.1 Bitta qator — bitta daraxt
AST (Abstract Syntax Tree — abstrakt sintaksis daraxti) — kodning tuzilishini ko'rsatadigan daraxt: har tugun — bitta til qismi (e'lon, o'zgaruvchi, qiymat). JS dvigateli ichida darsida V8 kodni avval AST'ga aylantirishini ko'rgan edik. Transpilerlar ham xuddi shunday boshlaydi.
const price: number = 35000; ni Oxc parser'i (oxc-parser) bilan tahlil qildik (joy ma'lumotlari — start, end — olib tashlandi):
{
"type": "VariableDeclaration",
"kind": "const",
"declarations": [
{
"type": "VariableDeclarator",
"id": {
"type": "Identifier",
"decorators": [],
"name": "price",
"optional": false,
"typeAnnotation": {
"type": "TSTypeAnnotation",
"typeAnnotation": {
"type": "TSNumberKeyword"
}
}
},
"init": {
"type": "Literal",
"value": 35000,
"raw": "35000"
},
"definite": false
}
],
"declare": false
}O'qib chiqamiz: "o'zgaruvchi e'loni (const), ichida bitta e'lonchi: nomi price, tur izohi — number kalit so'zi, boshlang'ich qiymati — 35000 literali". Bo'sh joylar, nuqta-vergul, qatorlar — yo'q: AST faqat ma'noni saqlaydi. Shuning uchun "abstrakt".
2.2 Uch bosqich
flowchart LR
A["manba kod<br/>Taom.tsx"] -->|"parse<br/>(tahlil)"| B["AST"]
B -->|"transform<br/>(o'zgartirish)"| C["yangi AST"]
C -->|"generate<br/>(yozish)"| D["JavaScript"]Turlarni o'chirish — AST'dan typeAnnotation tugunini olib tashlash. JSX'ni o'girish — JSXElement tugunini CallExpression (funksiya chaqiruvi) tuguniga almashtirish. Kod yozuvchi (generator) esa yangi daraxtdan matn yasaydi — o'z uslubida: shuning uchun har transpiler chiqishi biroz boshqacha formatlangan.
Tekshirib ko'ring: Nega transpiler turlarni o'chira oladi-yu,
pricega satr berilganini sezmaydi?
Javob
Turni o'chirish — faqat bitta fayl AST'idagi typeAnnotation tugunini olib tashlash. Turlarni tekshirish esa boshqa ish: "35000" ning turi string ekanini hisoblash, uni number bilan solishtirish, import qilingan turlarni boshqa fayllardan topish. Bu butun dastur haqida bilim talab qiladi — tsc ning ishi. Transpilerlar ataylab buni qilmaydi: aynan shuning uchun ular 10–100 baravar tez.
3. Bitta fayl — to'rt transpiler
3.1 Kirish fayli
React komponenti (React'ni 17-qismda o'rganamiz — hozir faqat sintaksisi muhim):
// Taom.tsx — React komponenti (React — 17-qismda)
type Dish = { name: string; price: number };
export function DishCard({ dish }: { dish: Dish }) {
const label = dish.price?.toLocaleString("uz-UZ") ?? "—";
return <li className="taom">{dish.name}: {label} so'm</li>;
}Ichida uch narsa o'girilishi kerak: tur (type Dish, : { dish: Dish }), JSX (<li …>) va — eski brauzer bo'lsa — ?. va ??.
3.2 Babel
Babel — 2014-yildan beri eng mashhur transpiler, JavaScript'da yozilgan. U o'zi hech narsa o'girmaydi: hamma ishni plaginlar qiladi. Plagin — bitta o'zgartirish (masalan, faqat ?. ni). Preset — plaginlar to'plami: @babel/preset-typescript (turlarni o'chiradi), @babel/preset-react (JSX), @babel/preset-env (yangi sintaksis, targets ga qarab).
Sozlama — babel.config.json:
{
"presets": [
["@babel/preset-env", { "targets": "chrome 117" }],
["@babel/preset-react", { "runtime": "automatic" }],
"@babel/preset-typescript"
]
}| Kalit | Nima qiladi | Sukut |
|---|---|---|
presets |
plaginlar to'plamlari (oxiridan boshiga qo'llanadi) | [] |
plugins |
alohida plaginlar (presetlardan oldin) | [] |
targets |
qaysi brauzerlar uchun (browserslist so'rovi) | browserslist yoki eng eski |
runtime (react) |
"automatic" yoki "classic" |
Babel 8 da "automatic" |
Tartibga e'tibor bering: presetlar teskari tartibda ishlaydi — avval TypeScript o'chiriladi, keyin JSX, keyin env. Bu Babel'ning eski, lekin muhim qoidasi.
NODE_ENV=production npx babel src/Taom.tsximport { jsxs as _jsxs } from "react/jsx-runtime";
// Taom.tsx — React komponenti (React — 17-qismda)
export function DishCard({
dish
}) {
const label = dish.price?.toLocaleString("uz-UZ") ?? "—";
return /*#__PURE__*/_jsxs("li", {
className: "taom",
children: [dish.name, ": ", label, " so'm"]
});
}type Dish va : { dish: Dish } yo'q. ?. va ?? qoldi — Chrome 117 ularni biladi. targets ni "safari 13" qilsak, JS versiyalari darsidagidek _dish$price === null || … ga aylanadi. <li> esa _jsxs("li", {…}) bo'ldi — buni pastda ochamiz.
NODE_ENV=production nega? Usiz Babel 8 react/jsx-dev-runtime dan _jsxDEV ni oladi — u xato xabarlariga fayl va qator ma'lumotini qo'shadigan "dasturchi" varianti.
3.3 SWC
SWC (Speedy Web Compiler) — Rust'da yozilgan, Babel'ning tez o'rinbosari. Next.js uni ishlatadi. Sozlama — .swcrc:
{
"jsc": {
"parser": { "syntax": "typescript", "tsx": true },
"target": "es2022",
"transform": {
"react": { "runtime": "automatic" }
}
}
}npx swc src/Taom.tsxSuccessfully compiled 1 file with swc.
// Taom.tsx — React komponenti (React — 17-qismda)
import { jsxs as _jsxs } from "react/jsx-runtime";
export function DishCard({ dish }) {
const label = dish.price?.toLocaleString("uz-UZ") ?? "—";
return /*#__PURE__*/ _jsxs("li", {
className: "taom",
children: [
dish.name,
": ",
label,
" so'm"
]
});
}Natija Babel'niki bilan deyarli bir xil — faqat formatlash boshqa (4 bo'sh joy). .swcrc kalitlari:
| Kalit | Nima qiladi | Sukut |
|---|---|---|
jsc.parser.syntax |
manba tili: "ecmascript" yoki "typescript" |
"ecmascript" |
jsc.parser.tsx |
.tsx dagi JSX'ni o'qish |
false |
jsc.target |
chiqish qaysi ES versiyasida | "es5" |
jsc.transform.react.runtime |
JSX qaysi funksiyaga aylanadi | "classic" |
target: "es2022" — browserslist o'rniga ES versiyasi. Babel'dan farqi: SWC'da JSX runtime sukut bo'yicha hali "classic", shuning uchun "automatic" ni yozib qo'ydik.
3.4 esbuild
esbuild — Go'da yozilgan transpiler va bundler. Sozlama fayli yo'q — hammasi bayroqlarda:
npx esbuild src/Taom.tsx --jsx=automatic --target=es2022import { jsxs } from "react/jsx-runtime";
export function DishCard({ dish }) {
const label = dish.price?.toLocaleString("uz-UZ") ?? "\u2014";
return /* @__PURE__ */ jsxs("li", { className: "taom", children: [
dish.name,
": ",
label,
" so'm"
] });
}Ikki farq: izoh o'chdi va "—" "\u2014" ga aylandi. esbuild sukut bo'yicha ASCII'dan tashqari belgilarni escape qiladi (--charset=utf8 bilan o'chadi). Ma'nosi bir xil — brauzer ikkalasini bir xil o'qiydi.
3.5 Oxc
Oxc (JavaScript Oxidation Compiler) — Rust'da yozilgan vositalar to'plami: parser, transformer, minifikator, linter. Vite 8 ichida TS va JSX'ni aynan Oxc o'giradi. Node API bilan:
import { readFileSync } from "node:fs";
import { transformSync } from "oxc-transform";
const code = readFileSync("src/Taom.tsx", "utf8");
const result = transformSync("Taom.tsx", code, {
target: "es2022",
jsx: { runtime: "automatic" },
});
console.log(result.code);import { jsxs as _jsxs } from "react/jsx-runtime";
export function DishCard({ dish }) {
const label = dish.price?.toLocaleString("uz-UZ") ?? "—";
return /* @__PURE__ */ _jsxs("li", {
className: "taom",
children: [
dish.name,
": ",
label,
" so'm"
]
});
}Tab bilan formatlangan, izoh yo'q. Fayl nomi ("Taom.tsx") birinchi argument — Oxc kengaytmaga qarab TS va JSX ekanini biladi.
3.6 /*#__PURE__*/ nima?
To'rttalasi ham _jsxs(…) oldiga shu izohni qo'ydi. U minifikatorga aytadi: "bu chaqiruvning yon ta'siri yo'q — natijasi ishlatilmasa, uni o'chirib yuborsang bo'ladi". Bu Tree shaking darsining kaliti — o'sha yerda batafsil.
Tekshirib ko'ring: To'rt vosita to'rt xil formatda yozdi (2 bo'sh joy, 4 bo'sh joy, tab). Bu muammo emasmi?
Javob
Yo'q. Transpiler chiqishi o'qish uchun emas, keyingi halqa uchun: bundler uni yig'adi, minifikator esa bo'sh joylarni baribir o'chiradi. Ma'no — AST — bir xil. Formatlash faqat siz yozadigan manba kodda muhim, u yerda Prettier ishlaydi.
4. JSX: classic va automatic runtime
4.1 Ikki usul
JSX — HTML'ga o'xshash yozuv, lekin brauzer uni bilmaydi. Transpiler uni funksiya chaqiruviga aylantiradi. Qaysi funksiyaga — runtime sozlamasi hal qiladi. runtime: "classic" bilan Babel chiqishi:
export function DishCard({
dish
}) {
const label = dish.price?.toLocaleString("uz-UZ") ?? "—";
return /*#__PURE__*/React.createElement("li", {
className: "taom"
}, dish.name, ": ", label, " so'm");
}| Classic | Automatic | |
|---|---|---|
| Chaqiruv | React.createElement("li", …) |
_jsxs("li", …) |
| Import | yo'q — React faylda bo'lishi shart |
o'zi qo'shadi: react/jsx-runtime |
| Bolalar | qo'shimcha argumentlar | children xususiyati |
| Qachondan | 2013 | React 17 (2020) |
4.2 React is not defined
Classic chiqishda React qayerdan keladi? Hech qayerdan — transpiler uni import qilmaydi. Komponentni chaqirib ko'rdik:
ReferenceError: React is not definedClassic runtime'da har JSX faylning boshida import React from "react" bo'lishi shart edi. Eski React kodida bu qatorni har faylda ko'rasiz — sababi shu. Automatic runtime import'ni o'zi qo'shadi va bu xato yo'qoldi. Bugungi hamma vosita (Babel 8, SWC, esbuild, Oxc, Vite shablonlari) automatic ishlatadi. Eski loyihada React is not defined ko'rsangiz — config'da runtime: "classic" qolgan.
5. Tezlik
To'rttalasini bir xil ish bilan o'lchadik: vazifalar ning 19 ta .ts moduli (79 839 belgi), faqat turlarni o'chirish. Har vosita Node ichida, xotirada, 20 marta ketma-ket; 5 marta takrorlab, mediana olindi. Mashina: Intel Core i5-12500H, 16 GB, Windows 11.
- Babel 8.0.6JavaScript54,1 ms
- esbuild 0.28.2Go, alohida jarayon39,6 ms
- SWC 1.16.13Rust8,2 ms
- Oxc 0.153.0Rust2,6 ms
Manba: O'lchandi: vazifalar v6 src/ (19 .ts), transformSync, 5×20 marta, mediana; i5-12500H, Node 24.21.0, 2026-10-10
Ikki izoh:
- Raqamlar shovqinli. Uchinchi o'lchovda (kompyuterda boshqa ishlar bor edi) hammasi taxminan ikki baravar sekin chiqdi: Babel 102.6, esbuild 64.8, SWC 13.5, Oxc 5.0 ms. Lekin tartib va nisbat o'zgarmadi: Oxc ~20 baravar, SWC ~7 baravar Babel'dan tez.
- esbuild bu o'lchovda adolatsiz holatda. U alohida Go jarayonida ishlaydi va har
transformSyncchaqiruvi jarayonlararo xabar almashadi — kichik fayllarda vaqtning asosiy qismi shu. Butun loyihani bitta buyruq bilan yig'ganda esbuild juda tez: tsc va bundler'lar darsida CLI bilan 181 ms (Node ishga tushishi bilan) o'lchagan edik.
Xulosa: Rust va Go'dagi vositalar JavaScript'dagi Babel'dan bir tartib tez. Shuning uchun 2020-yillarda ekotizim ularga ko'chdi: Next.js — SWC, Vite 8 — Oxc va Rolldown.
6. Qaysi biri qayerda
| Vosita | Til | Qayerda uchraydi | Kuchli tomoni |
|---|---|---|---|
| Babel | JS | eski loyihalar, Jest, React Compiler | plaginlar, istalgan o'zgartirish |
| SWC | Rust | Next.js, @vitejs/plugin-react-swc |
tez, Babel'ga yaqin |
| esbuild | Go | Vite 7 gacha, tsx, ko'p CLI | tez bundler ham |
| Oxc | Rust | Vite 8, Rolldown, Oxlint | eng tez, bitta to'plam |
Amalda siz transpilerni kamdan-kam o'zingiz tanlaysiz: framework tanlaydi. Lekin config faylini ko'rib, qaysi vosita ishlayotganini tanishingiz kerak: babel.config.json yoki .babelrc — Babel, .swcrc — SWC. Vite 8 loyihasida esa alohida config yo'q — Oxc vite.config ichidan sozlanadi. Babel bugun ham kerak bo'ladigan joy — maxsus o'zgartirish: masalan, React Compiler Babel plagini sifatida ishlaydi (18-qismda).
7. Type stripping: faqat o'chirish yoki to'liq o'girish
Turlarni o'chirishning ikki darajasi bor. Type stripping ("turlarni sidirib tashlash") — faqat tur yozuvlarini o'chirish: : number, type, interface, as. Qolgan kod harfma-harf o'sha joyida qoladi. Node 24 .ts faylni aynan shunday bajaradi (TypeScript'ni o'rnatish darsida ko'rgansiz). To'liq transform esa JavaScript'da umuman yo'q narsani yangi kod bilan almashtiradi.
Farq enum da ko'rinadi. holat.ts:
enum OrderStatus {
New = "yangi",
Ready = "tayyor",
}
console.log(OrderStatus.Ready);node holat.tsSyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript enum is not supported in strip-only mode"TypeScript enum i faqat-o'chirish rejimida qo'llanmaydi". enum — tur emas, u ishlash paytida obyekt yaratadi. Uni o'chirib bo'lmaydi — o'rniga kod yozish kerak. Oxc buni qiladi:
var OrderStatus = /* @__PURE__ */ function(OrderStatus) {
OrderStatus["New"] = "yangi";
OrderStatus["Ready"] = "tayyor";
return OrderStatus;
}(OrderStatus || {});
console.log(OrderStatus.Ready);esbuild esa yana bir qadam qo'yadi — qiymat shu faylda ma'lum bo'lgani uchun uni to'g'ridan-to'g'ri qo'yadi: console.log("tayyor" /* Ready */);.
| Sintaksis | Node 24 (strip) | Transpiler (Oxc, esbuild…) |
|---|---|---|
: number, type, interface |
o'chiradi | o'chiradi |
enum, namespace (qiymatli) |
ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX |
kod yozadi |
konstruktordagi private x (parameter properties) |
||
| JSX |
15-qismda vazifalar ga erasableSyntaxOnly bayrog'ini yoqgan edik: tsc faqat o'chiriladigan sintaksisga ruxsat beradi. Shuning uchun bizning kod uch joyda bir xil ishlaydi: node --test (strip), tsc va Vite (Oxc). Bu qaror bundlerga o'tishni og'riqsiz qildi — biror fayl transpiler'ning "qo'shimcha" imkoniyatiga tayanmaydi.
Yana bir shart — fayllar alohida o'girilishi. Transpiler bitta faylni ko'radi, shuning uchun import type aniq yozilishi kerak (tsc va bundler'lar darsidagi verbatimModuleSyntax). Bu ham vazifalar da 15-qismdan beri yoqiq.
8. Transpile ≠ typecheck — oxirgi marta
bad.ts:
const price: number = "35000";
console.log(price + 5000);Kompilyator:
TS2322: Type 'string' is not assignable to type 'number'.esbuild esa:
npx esbuild bad.tsconst price = "35000";
console.log(price + 5e3);Oxc ham xatosiz o'girdi (errors: []), Babel va SWC ham. Bajarilsa — 350005000. tsc va bundler'lar darsidagi qoida o'zgarmaydi: transpiler tezligi tekshiruvsizlikdan keladi. vazifalar da "build": "tsc && vite build" aynan shuning uchun — avval tsc tekshiradi, keyin Vite (ichida Oxc) o'giradi.
9. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
React is not defined |
JSX classic runtime, import React yo'q |
runtime: "automatic" |
?. eski brauzerda SyntaxError |
targets juda yangi |
to'g'ri targets (Polyfill va Baseline) |
| Babel config ishlamadi | .babelrc faqat o'z papkasida, babel.config.json — ildizda |
ildizdagi babel.config.json |
| build o'tdi, tur xatosi bor | transpiler tekshirmaydi | tsc --noEmit alohida |
10. Mashqlar
Mashqlar kurs/mashqlar/16/21-transpilyatsiya/ da.
1-mashq (oson): AST tugunlari
const price: number = 35000; AST'idan javob bering:
- Butun qator qaysi turdagi tugun:
35000qaysi tugun:- Turni o'chirish uchun qaysi tugun olib tashlanadi:
Yechim
VariableDeclaration — butun e'lon; Literal — 35000 qiymati (raw — manbadagi yozuvi). TSTypeAnnotation — : number qismi; uni o'chirsak, qolgan daraxtdan const price = 35000; yoziladi. Bu — type stripping'ning butun mohiyati.
2-mashq (o'rta): Ikki runtime va targets
Taom.tsx va darsdagi babel.config.json bilan (npm i -D -E @babel/core@8.0.6 @babel/cli@8.0.6 @babel/preset-env@8.0.6 @babel/preset-react@8.0.1 @babel/preset-typescript@8.0.1):
runtimeni"classic"qiling. Chiqishda qaysi funksiya chaqiriladi?targetsni"safari 13"qiling.?.va??ga nima bo'ladi?- Shu ikki o'zgarishni SWC'da qanday yozasiz?
Yechim
React.createElement("li", { className: "taom" }, dish.name, ": ", label, " so'm")— va import yo'q.?.va??—(_dish$price = dish.price) === null || _dish$price === void 0 ? void 0 : …kabi uzun shartlarga aylanadi: Safari 13 bu sintaksisni bilmaydi..swcrcda:"jsc.transform.react.runtime": "classic"va"jsc.target": "es2019"(?.va??— ES2020). SWC browserslist'ni ham o'qiy oladi —"env": { "targets": "safari 13" }— lekin u holdajsc.targetyozilmaydi. Ikkalasini birga yozsak, SWC to'xtaydi:`env` and `jsc.target` cannot be used together— "envvajsc.targetni birga ishlatib bo'lmaydi".
3-mashq (qiyin): O'z Babel plaginingiz
Babel plagini yozing: kodda console.debug(...) chaqiruvlari production'ga tushmasin.
- Alohida qatordagi
console.debug(...)— butun qator o'chsin. - Ifoda ichida (
const x = console.debug(1)) —void 0ga almashsin. logger.debug(...)ga tegmasin.- Uch holatni
node:testvatransformSyncbilan sinang.
Ishoralar: Babel plagini — { name, visitor } qaytaradigan funksiya. visitor.CallExpression(path) — har funksiya chaqiruvi tugunida ishlaydi. path.get("callee").matchesPattern("console.debug") — chaqirilgan narsa aynan console.debug mi. path.parentPath.isExpressionStatement() — chaqiruv alohida qatormi. path.parentPath.remove() va path.replaceWithSourceString("void 0") — o'chirish va almashtirish. Sinovda configFile: false, babelrc: false — loyihadagi config aralashmasin.
Yechim
// debug-olib-tashla.mjs — Babel plagini: console.debug(...) ni
// production kodidan olib tashlaydi (AST tugunini o'chiradi)
export default function removeDebug() {
return {
name: "debug-olib-tashla",
visitor: {
CallExpression(path) {
const callee = path.get("callee");
if (callee.matchesPattern("console.debug")) {
// Ifoda — alohida qator bo'lsa, butun qatorni o'chiramiz
if (path.parentPath.isExpressionStatement()) {
path.parentPath.remove();
} else {
// a = console.debug(...) — qiymat o'rniga undefined
path.replaceWithSourceString("void 0");
}
}
},
},
};
}Test:
// node --test debug-olib-tashla.test.mjs
import { test } from "node:test";
import assert from "node:assert/strict";
import { transformSync } from "@babel/core";
import removeDebug from "./debug-olib-tashla.mjs";
const run = (code) =>
transformSync(code, {
configFile: false,
babelrc: false,
plugins: [removeDebug],
}).code;
test("console.debug qatori o'chadi, console.log qoladi", () => {
const out = run(
'console.debug("narx:", price);\nconsole.log("Osh");',
);
assert.equal(out, 'console.log("Osh");');
});Yana ikki test — void 0 holati va logger.debug ga tegilmasligi. ℹ tests 3, ℹ pass 3, ℹ fail 0.
Plagin AST bilan ishlaydi, matn bilan emas: "console.debug" satri ichidagi so'zga yoki izohdagi console.debug ga tegmaydi. Regex bilan almashtirish bunday farqni ko'rmasdi. Shu g'oya Bog'liqliklarni yangilash darsidagi codemod'larning ham asosi.
11. Real ishda
- Config fayllarni o'qish: begona repoda
babel.config.json,.babelrc,.swcrcni ko'rsangiz — loyiha qaysi transpilerda ekanini bilasiz (Begona repoda orientatsiya darsida mashq qilamiz). - Jest (eski, lekin hali keng tarqalgan test vositasi)
.tsva JSX'ni Babel yoki SWC orqali o'giradi — u yerdagi xatolarning yarmi transpiler config'idan. - Intervyu savollari: "Transpiler va compiler farqi?", "AST nima?", "Babel preset va plagin farqi?", "Nega Vite
tscdan tez?", "JSX automatic runtime nima?".
Xulosa
- Transpiler: parse → AST → transform → generate. AST — kodning ma'nosi, formatsiz.
- Babel — plaginlar va presetlar (
babel.config.json, presetlar teskari tartibda); SWC (.swcrc), esbuild (bayroqlar) va Oxc (Vite 8 ichida) — tez muqobillar. - JSX classic →
React.createElement(React import shart, aks holdaReact is not defined); automatic →react/jsx-runtimedanjsx/jsxs, import o'zi qo'shiladi. - O'lchovimizda Oxc ~20, SWC ~7 baravar Babel'dan tez; esbuild'ning kuchi — bitta buyruqli butun build.
- Hech bir transpiler turlarni tekshirmaydi:
tsc && vite build.
Keyingi dars: Polyfill, browserslist va Baseline — transpiler sintaksisni qaysi brauzerlar uchun o'girishini kim hal qiladi? vazifalar ga build.target yozamiz va Vite nimani qila olmasligini o'lchaymiz.
Manbalar
- Babel: "Configure Babel", "Presets", "Plugin Development" (Babel Handbook) — babeljs.io/docs
- Babel 8 release notes — babeljs.io/blog
- SWC: "Configuring SWC" (
.swcrc,jsc.target,jsc.transform.react) — swc.rs/docs - esbuild: "API → Transform",
--jsx,--charset— esbuild.github.io/api - Oxc: "Transformer",
oxc-transformvaoxc-parser— oxc.rs/docs - React blog: "Introducing the New JSX Transform" (2020-09-22) — legacy.reactjs.org/blog
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!