2.14-bob: Modullar — ES Modules (import/export), CommonJS
2-QISM — JavaScript (0 dan chuqurgacha) · 14-mavzu
1. Kirish va motivatsiya
Hozirgacha kodni bitta faylda yozdik. Lekin real loyiha yuzlab fayldan iborat: har komponent, har funksiya, har sahifa — alohida faylda. Ularni bir-biriga bog'lash kerak: bu fayldagi funksiyani u faylda ishlatish. Bu — modullar tizimi.
Modul — alohida fayl bo'lib, o'z kodini export qiladi (boshqalar ishlatishi uchun ochadi) va boshqa modullardan import qiladi (kerakli narsani oladi). Bu — kodni tartibli, qayta ishlatiladigan va boshqarib bo'ladigan qiladi (0.6: decomposition).
O'xshatish: modul — kutubxonadagi kitob. Har kitob o'z mavzusi (bitta vazifa); kerak bo'lsa "olib" (import) ishlatasiz. Hammasini bitta ulkan kitobga yozsangiz — topib bo'lmaydi. Modullar — bilimni bo'laklarga ajratish.
0.7-bobdagi package.json, node_modules (npm paketlari ham modullar!), va React/Node loyihalarining butun tuzilishi — modullarga tayanadi. import/exportsiz zamonaviy loyiha yo'q.
2. Nazariya — chuqur tushuntirish
2.1. Nega modullar?
Bitta katta fayl muammolari: nom konfliktlari (global scope — 2.4), topish qiyin, qayta ishlatib bo'lmaydi, jamoada ishlash dahshat. Modullar:
- Inkapsulyatsiya — har modul o'z scope'i 2.4-bob; faqat export qilingani ko'rinadi.
- Qayta ishlatish — bir modulni ko'p joyda
import. - Tartib — har fayl bitta mas'uliyat 9.1-bob.
- Bog'liqliklar aniq —
importkim kimga bog'liqligini ko'rsatadi.
2.2. Ikki tizim: ESM va CommonJS
JS'da ikki modul tizimi bor:
| ES Modules (ESM) | CommonJS (CJS) | |
|---|---|---|
| Sintaksis | import/export |
require/module.exports |
| Yuklash | asinxron, static | sinxron |
| Qayerda | brauzer + zamonaviy Node | eski Node (default edi) |
| Holat | zamonaviy standart | eski (hali keng) |
Qaysini? Yangi kodda — ESM (
import/export). U brauzerda ham, Node'da ham ishlaydi (standart). CommonJS — eski Node loyihalarida uchraydi, bilish kerak.package.jsonda"type": "module"0.7-bob — ESM'ni yoqadi.
2.3. ESM — export (chiqarish)
Ikki usul: named (nomli) va default:
// matematika.js — NAMED export (bir nechta)
export const PI = 3.14159;
export function qosh(a, b) { return a + b; }
export class Kalkulyator {}
// yoki oxirida birga:
const ayir = (a, b) => a - b;
export { ayir };
// DEFAULT export — faylda BITTA (asosiy narsa)
export default function asosiy() {}2.4. ESM — import (olish)
// Named import — {} ichida, AYNAN o'sha nom bilan
import { PI, qosh } from "./matematika.js";
// Qayta nomlash (alias)
import { qosh as qoshish } from "./matematika.js";
// Default import — {} SIZ, istalgan nom bilan
import asosiy from "./matematika.js";
// Hammasini birga
import asosiy, { PI, qosh } from "./matematika.js";
// Barchasini obyekt sifatida (namespace)
import * as math from "./matematika.js";
math.PI; math.qosh(2, 3);Named vs default farqi: named —
{ aniqNom }(export'dagi nom bilan); default —{}siz, istalgan nom. Bir faylda ko'p named, lekin faqat bitta default.
2.5. CommonJS — require/module.exports
Eski Node tizimi (bilish kerak):
// matematika.js — eksport
const qosh = (a, b) => a + b;
module.exports = { qosh, PI: 3.14 }; // obyekt sifatida
// yoki: exports.qosh = qosh;
// app.js — import
const { qosh } = require("./matematika"); // require — sinxron
const math = require("./matematika"); // hammasi
math.qosh(2, 3);ESM CJS: ikkalasini aralashtirish muammoli. Bitta loyihada bittasini tanlang. Zamonaviy: ESM. Node paketida
package.json"type"belgilaydi 0.7-bob.
2.6. Modul xususiyatlari
- Har modul o'z scope'i 2.4-bob — modul ichidagi o'zgaruvchi global emas (avtomatik himoya).
- Bir marta bajariladi — modul birinchi
importda bir marta ishga tushadi, natija cache'lanadi (keyingi import'lar shu nusxani oladi). - Strict mode — ESM doim strict (2.5:
thisundefined). - Static —
importlar fayl boshida (hoisting'ga o'xshash); shartli import uchun dynamic import 2.7-bob. - Top-level await — ESM faylda
awaitniasyncfunksiyasiz, modul yuqori darajasida ishlatsa bo'ladi 2.11-bob; CommonJS'da yo'q. Modul shuawaittugaguncha kutadi:
// data.js — ESM, top-level await (async funksiya KERAK emas)
const javob = await fetch("/sozlama.json");
export const sozlama = await javob.json();2.7. Dynamic import — shartli/kechiktirilgan yuklash
import() funksiyasi — modulni kerak bo'lganda (asinxron) yuklaydi 2.11-bob:
// Faqat kerak bo'lganda yuklash (Promise qaytaradi — 2.11)
async function ogirModulIshlat() {
const { ogirFunksiya } = await import("./ogir-modul.js");
ogirFunksiya();
}
// Foydasi: boshlang'ich yuklanishni yengil qiladi (code splitting — 11.8)Bu — React'da React.lazy 11.8-bob va Next.js'da (13) bundle optimizatsiyasining asosi.
2.8. Brauzerda ESM
HTMLda type="module" bilan (1.1, 0.5):
<script type="module" src="app.js"></script>
<!-- module: ESM, defer 0.5-bob, o'z scope'i, CORS qoidalari -->
type="module"— avtomatikdefer(0.5: DOM tayyor bo'lganda), o'z scope (global emas). Lekin lokaldafile://bilan CORS muammosi — dev server (Vite — 11.3) kerak.
3. Sintaksis — tez ma'lumotnoma
// ESM (zamonaviy)
export const x = 1; // named
export default fn; // default
export { a, b };
import { x, a as b } from "./m.js"; // named (alias)
import fn from "./m.js"; // default
import * as m from "./m.js"; // namespace
const m = await import("./m.js"); // dynamic (2.7)
// CommonJS (eski Node)
module.exports = { x };
const { x } = require("./m");4. Batafsil kod namunalari
Misol 1 — Named export/import (2.3, 2.4)
// utils/matematika.js
export const PI = 3.14159;
export function aylanaYuza(r) { return PI * r ** 2; }
export function qosh(a, b) { return a + b; }
// app.js
import { PI, aylanaYuza, qosh as qoshish } from "./utils/matematika.js";
console.log(aylanaYuza(5)); // 78.54
console.log(qoshish(2, 3)); // 5Misol 2 — Default export (2.3, 2.4)
// User.js — asosiy narsa = class
export default class User {
constructor(ism) { this.ism = ism; }
}
// qo'shimcha named ham bo'lishi mumkin
export const MAX_USERS = 100;
// app.js
import User, { MAX_USERS } from "./User.js"; // default {} siz, named {} bilan
const u = new User("Ali");Misol 3 — Modulni qayta ishlatish (barrel — 2.4)
// components/index.js — "barrel" (bir joydan hammasi)
export { default as Tugma } from "./Tugma.js";
export { default as Karta } from "./Karta.js";
export { default as Modal } from "./Modal.js";
// app.js — bitta joydan import (qulay)
import { Tugma, Karta, Modal } from "./components/index.js";
// (React loyihalarida juda keng tarqalgan — 11)Misol 4 — Dynamic import (2.7, 2.11)
// Faqat tugma bosilganda og'ir modulni yukla (code splitting g'oyasi)
document.querySelector("#export").addEventListener("click", async () => {
// PDF kutubxonasi faqat KERAK bo'lganda yuklanadi (boshlang'ich yengil)
const { pdfYarat } = await import("./pdf-generator.js");
pdfYarat();
});5. To'g'ri va noto'g'ri holatlar
1) Named/default'ni aralashtirish
// default'ni {} bilan import
import { User } from "./User.js"; // User default eksport bo'lsa — undefined!
// default {} siz
import User from "./User.js";2) Fayl kengaytmasini unutish (ESM, brauzer/Node)
// ESM'da kengaytma shart (brauzer/Node ESM)
import { x } from "./utils";
// .js bilan
import { x } from "./utils.js";3) ESM va CommonJS aralashmasi
// ESM faylda require, yoki teskari
import { x } from "./m.js";
const y = require("./n"); // chalkashlik
// bittasini tanla (zamonaviy: ESM)4) Har fayl uchun ko'p default
// bir faylda 2 ta default — xato
export default a;
export default b;
// bitta default + named (Misol 2)6. Keng tarqalgan xatolar va yechimlari
Xato 1 — Cannot use import statement outside a module
Sababi: Node ESM'ni yoqmagan. Yechimi: package.jsonda "type": "module" 0.7-bob, yoki fayl .mjs; brauzerda <script type="module"> 2.8-bob.
Xato 2 — Cannot find module './x'
Sababi: noto'g'ri yo'l yoki kengaytma yo'q (0.2: path). Yechimi: to'g'ri relative path (./, ../ — 0.2); ESM'da .js kengaytma; harf registri (0.2: Linux!).
Xato 3 — X is not a function / undefined (import)
Sababi: named/default chalkashligi 2.4-bob. Yechimi: eksport turini tekshiring — default {} siz, named {} bilan.
Xato 4 — require is not defined (ESM'da)
Sababi: ESM faylda CommonJS require 2.5-bob. Yechimi: import ishlating; yoki fayl CommonJS bo'lsa .cjs.
Xato 5 — Circular dependency (aylanma bog'liqlik)
Sababi: A B A import (bir-birini chaqiradi). Yechimi: umumiy kodni uchinchi modulga ajrating; arxitekturani qayta ko'ring 9.3-bob.
7. Integratsiya — bu mavzu stack'ning qayerida uchraydi
- npm/package.json (0.7, 5.2):
node_modulespaketlari — modullar;"type": "module". - Node/Express (5): har route/service alohida modul.
- React (11): har komponent — modul; barrel export (Misol 3).
- Code splitting (11.8, 13): dynamic import —
React.lazy, Next bundle. - TypeScript (7): modul + tip;
import type. - Build (Vite — 11.3): ESM asosida; tree-shaking (ishlatilmagan eksportni olib tashlash).
- Funksional kod 2.15-bob: toza funksiyalarni modulga ajratish.
8. Eng yaxshi amaliyotlar (best practices)
- Yangi kodda ESM (
import/export) — zamonaviy standart 2.2-bob. - Bitta fayl — bitta mas'uliyat 9.1-bob; kodni mantiqli modullarga bo'ling.
- Named export odatda afzal (aniq nom, tree-shaking); default — faylning asosiy narsasi uchun 2.4-bob.
- Barrel (
index.js) bilan importni soddalashtiring, lekin ortiqcha qilmang (Misol 3). - Relative path to'g'ri (
./,../), kengaytma bilan (0.2, 6-bo'lim). - ESM/CJS aralashtirmang — bitta tizim 2.5-bob.
- Dynamic import bilan og'ir modulni kechiktiring (code splitting — 2.7).
- Circular dependency'dan qoching — umumiyni ajrating (6-bo'lim).
9. Amaliy loyiha: "Modulli Utility Kutubxonasi"
Oldingi boblardagi (2.3, 2.6, 2.7) funksiyalarni modullarga tashkil qilasiz.
Maqsad
import/export (named + default), barrel va dynamic import'ni amalda qo'llab, kodni professional, modulli tuzilishda tashkil qilish.
Talablar (requirements)
- Modul tuzilmasi:
src/ichidastring-utils.js,number-utils.js,array-utils.js,validatorlar.js(RegEx — 2.13) — har biri tegishli funksiyalarni named export. - Avvalgi funksiyalarni ko'chiring: 2.6 (string), 2.7 (array), 2.13 (validatsiya) loyihalaridagi funksiyalarni tegishli modulga joylang.
- Default export: bitta asosiy class (masalan
KalkulyatoryokiMatnTahlilchi) default eksport (Misol 2). - Barrel:
src/index.js— barcha modullarni bir joydan eksport (Misol 3). - Asosiy fayl (
app.js): barrel orqali import qilib, funksiyalarni ishlating. - Dynamic import: bitta "og'ir" funksiyani (masalan hisobot generatori) faqat kerak bo'lganda
await import()bilan yuklang (Misol 4). - Ishga tushiring: Node ESM bilan (
"type": "module"— 0.7) yoki brauzer<script type="module">2.8-bob. - Har modul o'z scope'ida (global o'zgaruvchi yo'q — 2.6).
Maslahatlar (hint)
package.jsonga"type": "module"qo'shing 0.7-bob — ESM uchun.- ESM'da import yo'lida
.jskengaytma shart (6-bo'lim). - Named:
export const/export function; import{ nom }. - Barrel:
export { default as X } from "./X.js"yokiexport * from "./m.js". - Dynamic:
const { fn } = await import("./modul.js")(async ichida — 2.11). - Harf registriga e'tibor (0.2: Linux serverda muhim).
"Tayyor" mezonlari (acceptance criteria)
- Kamida 4 modul, har biri named export bilan.
- Bitta default export ishlatilgan.
- Barrel (
index.js) orqali import ishlaydi. -
app.jsmodullarni to'g'ri import qilib ishlatadi. - Dynamic import (
await import) bitta modulda ishlaydi. - ESM to'g'ri sozlangan (
"type": "module"yoki brauzer module). - Hech qaysi modul global o'zgaruvchi yaratmaydi.
Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.
10. Xulosa va keyingi bobga ko'prik
Bu bobda kodni fayllarga bo'lib bog'lashni — modullarni o'rgandik:
- Modul — alohida fayl; o'z scope'i 2.4-bob, export (ochadi) / import (oladi); bir marta bajariladi, cache'lanadi.
- ESM (zamonaviy):
export/import(named{}bilan, default{}siz), asinxron/static; brauzer + Node. - CommonJS (eski Node):
module.exports/require, sinxron. - Dynamic import (
import()) — kerak bo'lganda yuklash (code splitting — 11.8). - Best: ESM, bitta mas'uliyat, named afzal, to'g'ri path, ESM/CJS aralashtirma.
Keyingi bob — 2.15-bob: Functional programming asoslari — immutability, pure functions, HOF. 2.3 (HOF), 2.7 (map/filter/reduce), 2.8 (immutability) da funksional g'oyalarni sezdik; endi ularni bir tizim sifatida — funksional dasturlash paradigmasi — o'rganamiz. Bu — toza, bashoratli, test qilishga oson kod yozishning kuchli usuli.
Foydalanilgan rasmiy/ishonchli manbalar
- MDN Web Docs — JavaScript modules,
import/export, dynamic import - Node.js docs — ECMAScript modules, CommonJS
- MDN — ESM vs CommonJS farqlari,
type="module"
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!