Mundarija (35)
- Bu darsda
- 1. Nega bu kerak?
- 2. CommonJS asoslari
- 2.1 require va module.exports
- 2.2 Har fayl — funksiya ichida
- 2.3 exports tuzog'i
- 2.4 Nusxa, jonli emas
- 2.5 Dinamik va sinxron
- 2.6 Kesh va qayta yuklash
- 3. Node faylni qaysi tizimda ishlatadi
- 3.1 Kengaytma va "type"
- 3.2 Avtomatik aniqlash — va uning ogohlantirishi
- 3.3 ESM loyihada require yo'q
- 4. ESM'dan CommonJS'ni import qilish
- 4.1 Default — doim ishlaydi
- 4.2 Nom topilmasa
- 5. CommonJS'dan ESM'ni require qilish
- 5.1 require(esm) — Node 24 da ishlaydi
- 5.2 Cheklov: top-level await
- 5.3 ESM'da CommonJS nomlari
- 6. Ikki tizim yonma-yon
- 7. Ko'p uchraydigan xatolar
- 7.1 require is not defined in ES module scope
- 7.2 exports = {...}
- 7.3 Named export '...' not found
- 7.4 .js faylda export, lekin xato
- 7.5 ERR_REQUIRE_ASYNC_MODULE
- 8. Mashqlar
- 1-mashq (oson): Qaysi tizim?
- 2-mashq (o'rta): CommonJS'dan ESM'ga
- 3-mashq (qiyin): Aralash loyiha
- 4-mashq: Vazifalar qadami — package.json, Node tekshiruvi va main ga
- 9. Real ishda
- Xulosa
- Manbalar
Node.js'da CommonJS va ESM: require, module.exports va o'zaro ishlash
Qisqacha: CommonJS — Node'ning eski modul tizimi:
require("./fayl")bilan oladi,module.exports = {...}bilan beradi. U kod ishlayotganda, sinxron yuklanadi va qiymat nusxasini beradi; ESM esa statik va jonli bog'lanishli. Node faylni.mjs(ESM),.cjs(CommonJS) yoki.js+package.jsondagi"type"bo'yicha taniydi. ESM CommonJS'niimportqila oladi, Node 24 da esa CommonJS ham ESM'nirequireqila oladi — faqat unda top-levelawaitbo'lmasa.
Bu darsda
- CommonJS modulini
requirevamodule.exportsbilan yoza va o'qiy olasiz. exports = ...tuzog'ini,requirekeshini va qiymat nusxalanishini tushuntira olasiz.- Node
.jsfaylni qaysi tizimda ishga tushirishinipackage.jsonva kengaytmaga qarab aniqlay olasiz. - ESM'dan CommonJS'ni va CommonJS'dan ESM'ni (
require(esm)) ulay olasiz, cheklovlarini bilasiz. vazifalargapackage.jsonqo'shib, ro'yxat mantiqini Node'da tekshirasiz varefactor/modullarnimainga qo'shib, Pages'ga chiqarasiz.
Oldin bilishingiz kerak: Modul semantikasi, Strict mode, this: to'rt qoida, JSON asoslari.
1. Nega bu kerak?
Kursda kodni ESM'da yozamiz. Lekin dasturchi faqat o'z kodini yozmaydi — u boshqalarning kodini o'qiydi. Va u yerda siz tez-tez shunday qatorlarni uchratasiz:
const express = require("express");
const { readFileSync } = require("fs");
module.exports = { narxniTop };Bu — CommonJS (qisqacha CJS) — Node'ning o'z modul tizimi. Node 2009-yilda paydo bo'lganda JavaScript'da modullar yo'q edi, shuning uchun Node o'zinikini yaratdi. ESM tilga faqat 2015-yilda qo'shildi. O'n yil davomida npm'ga yuz minglab paket CommonJS'da yozildi. Eski darsliklar, StackOverflow javoblari, ko'p sozlama fayllari — hammasi shunda.
Strict mode darsida .cjs va .mjs farqini ko'rib, "formatlarni keyin batafsil ko'ramiz" degan edik. this: to'rt qoida darsida esa .cjs faylning yuqori darajasidagi this — {} ekanini va bu "module.exports obyekti" ekanini aytgan edik. Bugun ikkalasining sababini ochamiz.
Hayotdan o'xshatish: ikki xil hujjat aylanishi. Eski idorada hujjat qog'oz nusxa bo'lib keladi: olgan zahoti u sizniki, asl hujjat o'zgarsa ham, qo'lingizdagi nusxa eskicha qoladi. Yangi idorada hamma bitta elektron hujjatga havola oladi: kimdir uni yangilasa, hamma yangisini ko'radi. CommonJS — qog'oz nusxa, ESM — umumiy elektron hujjat. Ikkala idora ham ishlayapti va ular bir-biriga hujjat yuborishni o'rganishi kerak.
2. CommonJS asoslari
2.1 require va module.exports
«Bahor» menyusi CommonJS'da:
// menyu.cjs
console.log("menyu.cjs yuklandi");
const narxlar = { osh: 35000, manti: 30000 };
function narxniTop(taom) {
return narxlar[taom] ?? 0;
}
module.exports = { narxlar, narxniTop };// asosiy.cjs
const { narxniTop } = require("./menyu.cjs");
const menyu = require("./menyu.cjs");
console.log(narxniTop("osh"));
console.log(menyu === require("./menyu.cjs"));
console.log(Object.keys(require.cache).length);node asosiy.cjs:
menyu.cjs yuklandi
35000
true
2Qatorma-qator:
module.exports = {...}— fayl tashqariga beradigan bitta qiymat. Odatda obyekt, lekin funksiya yoki klass ham bo'lishi mumkin.require("./menyu.cjs")— faylni yuklaydi, bajaradi va o'shamodule.exportsni qaytaradi. Oddiy funksiya chaqiruvi: natijani o'zgaruvchiga yozasiz.const { narxniTop } = require(...)— bu oddiy destructuring.import { ... }ga o'xshaydi, lekin ESM'ning statik importi emas: qaytgan obyektdan xususiyat olinyapti.- "menyu.cjs yuklandi" bir marta. Uch
require— bitta bajarilish.menyu === require(...)—true: hamma bitta obyektni oldi. require.cache— yuklangan fayllar keshi. Ikkita yozuv:asosiy.cjsning o'zi vamenyu.cjs.
2.2 Har fayl — funksiya ichida
require, module, __dirname qayerdan keladi? Ularni hech kim e'lon qilmadi. Sir shunda: Node har CommonJS faylni ishga tushirishdan oldin uni funksiyaga o'raydi — taxminan shunday:
(function (exports, require, module, __filename, __dirname) {
// sizning faylingiz shu yerda
});Beshta nom — shu funksiyaning parametrlari. Bu bir nechta sirni ochadi:
- Fayl o'z muhitiga ega — funksiya muhiti, xuddi IIFE kabi. Shuning uchun
.cjsdagivarglobal'ga tushmaydi. this—module.exports. Node funksiyanithissifatidamodule.exportsbilan chaqiradi. Boshida u bo'sh obyekt —this: to'rt qoida darsidagi{}aynan shu.__dirnameva__filename— fayl turgan papka va faylning to'liq yo'li.
// bosh.cjs
console.log(this === module.exports, this);
console.log(typeof __dirname, typeof __filename, typeof require);true {}
string string functionBu ikki qatorni bosh.cjs faylga yozib, node bosh.cjs bilan ishga tushiring — natija yuqoridagidek. Saytdagi tugma bilan emas: brauzerda module yo'q.
2.3 exports tuzog'i
Beshta parametrdan biri — exports. U boshida module.exports bilan bitta obyektga qaraydi. Shuning uchun xususiyat qo'shish ikkalasi bilan ham ishlaydi:
exports.sotuvQosh = (narx) => narx; // ishlaydiLekin exports ga yangi obyekt bersangiz:
// kassa.cjs
exports.sotuvQosh = (narx) => narx;
exports = { hisobot: () => "hisobot" };// sinov.cjs
const kassa = require("./kassa.cjs");
console.log(kassa);
console.log(typeof kassa.hisobot);{ sotuvQosh: [Function (anonymous)] }
undefinedhisobot yo'qoldi — xatosiz! Sabab Havola semantikasi darsida: exports = {...} faqat mahalliy o'zgaruvchini boshqa obyektga qaratdi. require esa doim module.exports ni qaytaradi — u hamon eski obyekt. Sxema:
flowchart LR
ME["module.exports"] --> O1["{ sotuvQosh }"]
E1["exports — oldin"] -.-> O1
E2["exports — keyin"] --> O2["{ hisobot }"]
R["require natijasi"] --> O1Qoida: butun qiymatni almashtirish — faqat module.exports = .... exports.nom = ... — faqat xususiyat qo'shish uchun. Chalkashmaslik uchun ko'p jamoalar exports ni umuman ishlatmaydi.
2.4 Nusxa, jonli emas
Modul semantikasi darsidagi hisoblagich CommonJS'da:
// hisob.cjs
let soni = 0;
function oshir() {
soni++;
}
module.exports = { soni, oshir };// hisob-sinov.cjs
const hisob = require("./hisob.cjs");
hisob.oshir();
hisob.oshir();
console.log(hisob.soni);0ESM'da 2 bo'lardi. Bu yerda { soni, oshir } obyekt yaratilgan paytda soni ning qiymati — 0 — obyektga nusxalandi. Keyin oshir() modul ichidagi o'zgaruvchini o'zgartiradi, obyektdagi nusxani emas. «Nega bu kerak?» dagi qog'oz nusxa. CommonJS'da jonli qiymat kerak bo'lsa, funksiya (olish()) yoki getter eksport qilinadi.
2.5 Dinamik va sinxron
require — oddiy funksiya. Shuning uchun u ESM'ning statik qoidalaridan ozod:
- Istalgan joyda —
ifichida, funksiya ichida:if (sinov) { const x = require("./x.cjs"); }. - Hisoblangan manzil bilan —
require("./tillar/" + til + ".cjs"). - Sinxron — fayl diskdan o'qilib, bajarilib bo'lguncha keyingi qator kutadi. Disk uchun bu tez; tarmoq uchun esa imkonsiz. Brauzer CommonJS'ni to'g'ridan-to'g'ri ishlata olmasligining sababi shu.
Bu erkinlikning narxi — Modul semantikasi darsida ko'rdik: bundler kod ishlamasdan "nima kerak" deya olmaydi va tree-shaking ishlamaydi.
Kengaytma. require("./menyu") — Node o'zi .js, .json va .node (C++ da yozilgan qo'shimcha — kam uchraydi) kengaytmalarini qo'shib qidiradi, shuning uchun eski kodda kengaytmasiz yozuv ko'p. Lekin .cjs ni o'zi qo'shmaydi: papkada faqat menyu.cjs bo'lsa, require("./menyu") — Error: Cannot find module './menyu'. ESM'da esa kengaytma doim majburiy (ESM import).
2.6 Kesh va qayta yuklash
require.cache — oddiy obyekt, uni o'zgartirish mumkin. Kalitni o'chirsangiz, keyingi require faylni qayta bajaradi:
const m = require("./menyu.cjs");
m.narxlar.osh = 1;
console.log(require("./menyu.cjs").narxlar.osh);
delete require.cache[require.resolve("./menyu.cjs")];
console.log(require("./menyu.cjs").narxlar.osh);menyu.cjs yuklandi
1
menyu.cjs yuklandi
35000Ikkinchi require keshdan oldi — o'zgargan 1. Kesh tozalangach, fayl qayta bajarildi va narx yana 35000. require.resolve faylning to'liq yo'lini qaytaradi — kesh kaliti shu. ESM'da bunday qayta yuklash yo'q.
Tekshirib ko'ring:
module.exports.narx = 35000; exports.narx = 40000;—requireqilgan faylnarxni qanday ko'radi?
Javob
40000. Ikkala qator ham bitta obyektning xususiyatini yozdi: exports hali module.exports bilan bir obyektga qaraydi. Muammo faqat exports = {...} — butun obyektni almashtirganda chiqadi.
3. Node faylni qaysi tizimda ishlatadi
3.1 Kengaytma va "type"
Bir xil .js fayl bir loyihada ESM, boshqasida CommonJS bo'lishi mumkin. Node buni shu tartibda hal qiladi:
flowchart TD
F["Fayl"] --> X{"Kengaytma?"}
X -- ".mjs" --> E["ESM"]
X -- ".cjs" --> C["CommonJS"]
X -- ".js" --> P{"Eng yaqin package.json<br/>da type?"}
P -- "module" --> E
P -- "commonjs" --> C
P -- "yo'q" --> D{"import/export<br/>sintaksisi bormi?"}
D -- "ha" --> E
D -- "yo'q" --> Cpackage.json — loyiha sozlamalari fayli: nomi, bog'liqliklari, buyruqlari. Uni npm bilan frontend asboblari qismida to'liq o'rganamiz. Hozir undan bitta maydon kerak:
{
"type": "module"
}Node .js faylning papkasidan boshlab yuqoriga qarab eng yaqin package.json ni qidiradi. Unda "type": "module" bo'lsa — papkadagi hamma .js ESM. "commonjs" bo'lsa yoki maydon umuman bo'lmasa — CommonJS. .mjs va .cjs esa "type" dan qat'i nazar o'z tizimida ishlaydi.
3.2 Avtomatik aniqlash — va uning ogohlantirishi
Diagrammaning pastki qismi — Node'ning yangi xulqi. "type" aytilmagan .js faylda import yoki export bo'lsa, Node uni avval CommonJS deb o'qishga urinadi, bo'lmasa — ESM deb qayta o'qiydi. Bu sintaksis bo'yicha aniqlash Node 22.7 dan sukut bo'yicha yoqilgan. Nega modullar darsida node --check assets/js/vazifa.js aynan shu tufayli ishladi.
Atrofda hech qanday package.json bo'lmasa, Node buni jimgina qiladi. Lekin package.json bor-u, "type" yo'q bo'lsa — ogohlantiradi:
(node:10276) [MODULE_TYPELESS_PACKAGE_JSON] Warning: Module type of file:///C:/Users/Aziz/bahor/menyu.js is not specified and it doesn't parse as CommonJS.
Reparsing as ES module because module syntax was detected. This incurs a performance overhead.
To eliminate this warning, add "type": "module" to C:\Users\Aziz\bahor\package.json.Tarjimasi: "menyu.js ning modul turi ko'rsatilmagan va u CommonJS sifatida o'qilmadi. Modul sintaksisi topilgani uchun ES modul sifatida qayta o'qilmoqda — bu qo'shimcha vaqt oladi. Ogohlantirishni yo'qotish uchun package.json ga "type": "module" qo'shing". Node o'zi yechimni aytyapti. Qoida: ESM loyihada "type": "module" ni aniq yozing — taxminga tayanmang.
3.3 ESM loyihada require yo'q
"type": "module" li loyihadagi .js faylda eski odat bilan require yozilsa:
ReferenceError: require is not defined in ES module scope, you can use import instead
This file is being treated as an ES module because it has a '.js' file extension and 'C:\Users\Aziz\bahor\package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension."ES modul muhitida require aniqlanmagan, uning o'rniga import ishlating. Bu fayl ES modul deb hisoblanmoqda, chunki u .js va package.json da "type": "module" bor. CommonJS skript sifatida ishlatish uchun uni .cjs ga qayta nomlang". Ikki yo'l: kodni import ga o'tkazish yoki faylni .cjs qilish.
Teskari holat — .cjs faylda export:
SyntaxError: Unexpected token 'export'.cjs doim CommonJS — u export ni tanimaydi.
Tekshirib ko'ring: Loyihada
"type": "module".eslint.config.jsESM'da, eskipostcss.config.jsesamodule.exports = {...}. Nima qilish kerak?
Javob
Eng oson yo'l — postcss.config.js ni postcss.config.cjs ga qayta nomlash. Ikkinchi yo'l — uni export default {...} ga o'tkazish. Sababi: "type": "module" papkadagi hamma .js ni ESM qiladi, module.exports esa ESM'da yo'q. Kengaytma .cjs bitta faylni bu qoidadan chiqaradi. PostCSS darsida biz to'g'ridan-to'g'ri postcss.config.mjs + export default yozgan edik — bu tuzoqqa tushmaslik uchun.
4. ESM'dan CommonJS'ni import qilish
4.1 Default — doim ishlaydi
ESM fayl CommonJS faylni oddiy import bilan oladi. module.exports — default eksport bo'lib keladi:
// asosiy.mjs
import menyu from "./menyu.cjs";
import { narxniTop } from "./menyu.cjs";
console.log(menyu.narxlar.manti, narxniTop("osh"));menyu.cjs yuklandi
30000 35000Nomli import ({ narxniTop }) ham ishladi. Qanday qilib? Node CommonJS faylning matnini ishga tushirishdan oldin o'qib chiqadi va module.exports = { narxlar, narxniTop } yoki exports.nom = ... kabi oddiy qatorlardan nomlarni topadi. Tekshirib ko'ramiz: import * as m from "./menyu.cjs" qilib, console.log(Object.keys(m)) ni chiqarsak:
[ 'default', 'module.exports', 'narxlar', 'narxniTop' ]default va 'module.exports' — ikkalasi ham butun module.exports obyekti; qolganlari — topilgan nomlar.
4.2 Nom topilmasa
Agar module.exports murakkabroq yo'l bilan yasalsa, Node nomlarni oldindan ko'ra olmaydi:
// dinamik.cjs
function yasash() {
return { osh: 35000 };
}
module.exports = yasash();import { osh } from "./dinamik.cjs";SyntaxError: Named export 'osh' not found. The requested module './dinamik.cjs' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from './dinamik.cjs';
const { osh } = pkg;"osh nomli eksporti topilmadi. So'ralgan modul — CommonJS, u module.exports ning hamma qismini nomli eksport sifatida bermasligi mumkin. CommonJS modulni doim default orqali olish mumkin" — va Node tayyor kodni ham yozib berdi. Qoida: CommonJS paketdan nomli import xato bersa — default bilan olib, destructuring qiling.
5. CommonJS'dan ESM'ni require qilish
5.1 require(esm) — Node 24 da ishlaydi
Uzoq vaqt bu taqiqlangan edi: CommonJS fayl ESM'ni require qila olmasdi, faqat dinamik import() bilan (u Promise qaytaradi — 11-qismda). Endi — mumkin. require(esm) Node 22.12 dan sukut bo'yicha yoqilgan. Biz Node 24.21 va 22.17 da sinadik — ikkalasida ham ogohlantirishsiz ishladi:
// vazifa.mjs
export class Vazifa {
constructor(matn) {
this.matn = matn;
}
}
export default function salom() {
return "salom";
}// sinov.cjs
const modul = require("./vazifa.mjs");
console.log(modul);
console.log(new modul.Vazifa("Non olish"));
console.log(modul.default());[Module: null prototype] {
Vazifa: [class Vazifa],
__esModule: true,
default: [Function: salom]
}
Vazifa { matn: 'Non olish' }
salomrequire ESM'ning modul obyektini qaytaradi (ESM import dagi import * as). Default — .default ichida. __esModule: true — eski asboblar bilan kelishuv belgisi: "bu obyekt ESM'dan keldi, default'ni .default dan ol". Bunday asboblarga Babel (yangi JS'ni eski brauzerlar uchun eski JS'ga o'giradigan dastur) va TypeScript kiradi — ikkalasini keyingi qismlarda ko'ramiz, hozir bilish shart emas.
5.2 Cheklov: top-level await
ESM'da await ni funksiyadan tashqarida, eng yuqori darajada yozish mumkin (top-level await — 11-qismda). Bunday modul asinxron — u bajarilishi uchun kutishi kerak. require esa sinxron, kuta olmaydi:
Error [ERR_REQUIRE_ASYNC_MODULE]: require() cannot be used on an ESM graph with top-level await. Use import() instead. To see where the top-level await comes from, use --experimental-print-required-tla."require() ni top-level await bor ESM grafigida ishlatib bo'lmaydi. Uning o'rniga import() ishlating". Grafikning istalgan joyidagi bitta top-level await butun grafikni require uchun yopiq qiladi.
Diqqat: Eski Node versiyalarida (22.12 dan oldin, 20.19 dan oldin)
require(esm)ERR_REQUIRE_ESMxatosini berardi. Internetdagi eski javoblar "ESM paketni CommonJS'dan ishlatib bo'lmaydi" deydi — bu endi to'g'ri emas, lekin loyihangiz qaysi Node versiyasida ishlashini bilib qo'ying:node -v.
5.3 ESM'da CommonJS nomlari
ESM fayl ichida __dirname, require yo'q (Modul semantikasi):
ReferenceError: __dirname is not defined in ES module scopeO'rnini bosuvchilar:
| CommonJS | ESM |
|---|---|
__dirname |
import.meta.dirname (Node 20.11+) |
__filename |
import.meta.filename |
require("./x.cjs") |
import x from "./x.cjs" |
require (zarur bo'lsa) |
createRequire(import.meta.url) |
Oxirgi qator — kam uchraydigan holat uchun: ESM ichida baribir require kerak bo'lsa (masalan, eski kod require.cache ga tayansa):
import { createRequire } from "node:module";
const require = createRequire(import.meta.url);
const eski = require("./menyu.cjs");
console.log(eski.narxniTop("manti"));menyu.cjs yuklandi
30000createRequire — shu modulga nisbatan ishlaydigan haqiqiy require yasaydi.
Tekshirib ko'ring:
hisobot.cjsichidarequire("./kassa.mjs")bor.kassa.mjsning o'zida top-levelawaityo'q, lekin u import qiladigankurs.mjsdaawaiteng yuqori darajada yozilgan.node hisobot.cjsnima beradi?
Javob
ERR_REQUIRE_ASYNC_MODULE xatosi. require bitta faylni emas, butun grafikni sinxron yuklashi kerak. Grafikning istalgan joyidagi top-level await uni asinxron qiladi — require kuta olmaydi. Yechim: hisobot ni ESM'ga o'tkazish yoki import() (11-qismda).
6. Ikki tizim yonma-yon
| CommonJS | ESM | |
|---|---|---|
| Yozuv | require / module.exports |
import / export |
| Qachon yuklanadi | kod ishlayotganda, sinxron | oldindan, statik |
| Qiymat | nusxa (obyekt havolasi) | jonli bog'lanish |
Yuqori this |
module.exports |
undefined |
| Rejim (Strict mode) | oddiy | qat'iy |
| Kengaytma | ixtiyoriy | majburiy |
| Qayerda | faqat Node | Node va brauzer |
Yangi kod — ESM. CommonJS'ni o'qiy olish shart, yozish esa faqat eski loyihada yoki faqat CommonJS'ni tushunadigan asbob sozlamasida. Ikkala tizim uchun ham kod chiqaradigan paketlar ("dual package") bor — ularni frontend asboblari qismida ko'ramiz.
7. Ko'p uchraydigan xatolar
7.1 require is not defined in ES module scope
ESM faylda require. Tuzatish: import ga o'ting yoki faylni .cjs qiling.
7.2 exports = {...}
Xato yo'q, eksport — bo'sh. Tuzatish: module.exports = {...}.
7.3 Named export '...' not found
CommonJS paketdan nomli import. Tuzatish: import pkg from "..."; const { nom } = pkg; — Node xabarning o'zida yozib bergan kod.
7.4 .js faylda export, lekin xato
Unexpected token 'export' va ogohlantirish Failed to load the ES module ... Make sure to set "type": "module" in the nearest package.json file or use the .mjs extension. — fayl .cjs yoki "type": "commonjs" muhitida. Tuzatish: kengaytma yoki "type".
7.5 ERR_REQUIRE_ASYNC_MODULE
require qilingan ESM grafigida top-level await. Tuzatish: chaqiruvchini ESM'ga o'tkazing yoki import() ishlating (11-qism).
8. Mashqlar
1-mashq (oson): Qaysi tizim?
Har fayl uchun ayting: ESM yoki CommonJS?
kassa.mjs,package.jsonda"type": "commonjs".kassa.js,package.jsonda"type": "module".kassa.cjs,package.jsonda"type": "module".kassa.js,package.jsonbor,"type"yo'q, fayldarequirevamodule.exports.kassa.js, hech qayerdapackage.jsonyo'q, fayldaexport.
Yechim
- ESM —
.mjshar doim ESM,"type"ga qaramaydi. - ESM —
.js+"type": "module". - CommonJS —
.cjshar doim CommonJS. - CommonJS —
"type"yo'q, kod CommonJS sifatida o'qiladi. - ESM — sintaksis bo'yicha aniqlash;
package.jsonyo'q, demak ogohlantirishsiz.
2-mashq (o'rta): CommonJS'dan ESM'ga
Eski «Bahor» faylini ESM'ga o'tkazing (yetkazish.mjs) va uni ishlatadigan asosiy.mjs yozing. Xulq o'zgarmasin.
// yetkazish.cjs
const YAQIN_MASOFA = 5;
function yetkazishNarxi(km) {
if (km <= YAQIN_MASOFA) {
return 10000;
}
return km * 2000;
}
module.exports = { yetkazishNarxi, YAQIN_MASOFA };// asosiy.cjs
const { yetkazishNarxi } = require("./yetkazish.cjs");
console.log(yetkazishNarxi(3), yetkazishNarxi(8));Yechim
// yetkazish.mjs
export const YAQIN_MASOFA = 5;
export function yetkazishNarxi(km) {
if (km <= YAQIN_MASOFA) {
return 10000;
}
return km * 2000;
}// asosiy.mjs
import { yetkazishNarxi } from "./yetkazish.mjs";
console.log(yetkazishNarxi(3), yetkazishNarxi(8));10000 16000Uch o'zgarish: module.exports = {...} o'rniga e'lonlar oldida export; require o'rniga import; kengaytma .mjs. Endi xato nomni Node ishga tushirishdan oldin topadi. YAQIN_MASOFA ham eksport qilindi — CommonJS versiyada ham u tashqariga chiqqan edi.
3-mashq (qiyin): Aralash loyiha
Papkada "type": "module" li package.json bor. Ikki fayl kerak:
eski-hisobot.cjs— CommonJS:module.exports = function hisobot(tushum) { ... }—"Tushum: N so'm"qaytaradi.asosiy.js— ESM:eski-hisobot.cjsni import qilib,hisobot(40000)ni chiqarsin; o'z papkasining nomini ham chiqarsin (CommonJS'dagi__dirnameo'rniga).
So'ng teskari yo'lni ham sinang: sinov.cjs da asosiy.js ni require qilib ko'ring. Nima bo'ladi va nega?
Yechim
// eski-hisobot.cjs
module.exports = function hisobot(tushum) {
return `Tushum: ${tushum} so'm`;
};// asosiy.js
import hisobot from "./eski-hisobot.cjs";
import path from "node:path";
console.log(hisobot(40000));
console.log(path.basename(import.meta.dirname));node asosiy.js (papka nomi bahor bo'lsa):
Tushum: 40000 so'm
bahormodule.exportsfunksiya — u to'g'ridan-to'g'ri default bo'ldi.import.meta.dirname—__dirnamening ESM'dagi o'rni..cjskengaytmasi tufaylimodule.exports"type": "module"papkasida ham ishladi.
sinov.cjs da require("./asosiy.js") — Node 24 da ishlaydi: asosiy.js bajariladi (ikki qator chiqadi) va require uning modul obyektini qaytaradi. asosiy.js da top-level await yo'q, shuning uchun require(esm) cheklovi tegmaydi. Agar u yerda await bo'lsa — ERR_REQUIRE_ASYNC_MODULE.
4-mashq: Vazifalar qadami — package.json, Node tekshiruvi va main ga
refactor/modullar ning oxirgi qadami.
- Repo ildiziga
package.jsonqo'shing: nomivazifalar,"private": trueva"type": "module". tekshiruv/royxat.jsfaylidaVazifalarRoyxatini brauzersiz — Node'da tekshiring: qolgan vazifalar soni (qoldi), yangi id, takror matn, belgilash, filtr, o'chirishdan keyingi id.render.jsni Node'da import qilib ko'ring. Nima bo'ladi?- Branch'ni
mainga qo'shing, GitHub'ga yuboring va Pages'da tekshiring.
Ishora: tekshiruv uchun kichik tekshir(nomi, haqiqiy, kutilgan) funksiyasini yozing — u === bilan solishtirib, yoki chiqarsin. Haqiqiy test kutubxonalari (Birinchi avtomatik test) 12-qismda — hozir qo'lda.
Yechim
1. package.json:
{
"name": "vazifalar",
"private": true,
"type": "module"
}"private": true — "bu paket npm'ga chiqarilmaydi" (tasodifiy nashrdan himoya). "type": "module" — papkadagi hamma .js ES modul: Node ham, kodni o'qigan odam ham buni taxmin qilmaydi. Brauzerga ta'siri yo'q — u type="module" atributiga qaraydi.
2. tekshiruv/royxat.js:
// tekshiruv/royxat.js — VazifalarRoyxati ni brauzersiz tekshirish
// Ishga tushirish: node tekshiruv/royxat.js
import { VazifalarRoyxati } from "../assets/js/royxat.js";
function tekshir(nomi, haqiqiy, kutilgan) {
const belgi = haqiqiy === kutilgan ? "✅" : "❌";
console.log(`${belgi} ${nomi}: ${haqiqiy}`);
}
const royxat = VazifalarRoyxati.dan([
{ id: 1, matn: "Non olish", bajarildi: false },
{ id: 2, matn: "DOM darsini takrorlash", bajarildi: true },
]);
tekshir("boshida qoldi", royxat.qoldi, 1);
tekshir("yangi id", royxat.qosh("Choy damlash").id, 3);
tekshir("qo'shgandan keyin qoldi", royxat.qoldi, 2);
tekshir("takror matn", royxat.matnBormi("non olish", null), true);
royxat.almashtir(1);
tekshir("belgilagandan keyin qoldi", royxat.qoldi, 1);
const bajarilganlar = royxat.korinadiganlar("bajarilgan");
tekshir("bajarilganlar", bajarilganlar.length, 2);
royxat.ochir(3);
tekshir("o'chirgandan keyin id", royxat.qosh("Kitob o'qish").id, 4);node tekshiruv/royxat.js✅ boshida qoldi: 1
✅ yangi id: 3
✅ qo'shgandan keyin qoldi: 2
✅ takror matn: true
✅ belgilagandan keyin qoldi: 1
✅ bajarilganlar: 2
✅ o'chirgandan keyin id: 4Manzil ../assets/js/royxat.js — tekshiruv faylidan bir pog'ona yuqoriga. royxat.js o'zi vazifa.js ni import qiladi — Node grafikni o'zi yig'di. Oxirgi qator muhim: o'chirilgan 3 qayta berilmadi, closure'dagi hisoblagich ishlayapti (Closure amaliyotda). qoldi — getter, u statistika() ga tayanadi: hisob bitta joyda.
3. render.js Node'da:
export const forma = document.getElementById("yangi-forma");
^
ReferenceError: document is not definedKutilgan natija: render.js — brauzer qatlami, u DOM'siz yashay olmaydi. vazifa.js, royxat.js, paket.js va holat.js esa DOM'ga tegmaydi — ular Node'da ham ishlaydi. Modullarga bo'lishning yashirin sovg'asi shu: mantiq ekrandan ajraldi va uni alohida tekshirish mumkin. 12-qismdagi avtomatik testlar aynan shu ajratishga tayanadi.
git add package.json tekshiruv/royxat.js
git commit -m "Vazifalar: package.json va ro'yxat tekshiruvini qo'sh"4. main ga va Pages'ga:
git switch main
git merge refactor/modullar
git branch -d refactor/modullar
git pushPages bir-ikki daqiqada yangilanadi (Yakuniy loyiha). https://login.github.io/vazifalar/ ni oching va DevTools bilan tekshiring:
- Console — toza, qizil xato yo'q.
- Network (JS filtri, "Disable cache") — oltita
.jsfayl, hammasi200,modulepreloadtufayli deyarli bir vaqtda. - Ilova — uch vazifa, "2 ta vazifa qoldi, 1 ta bajarildi"; belgilash, filtr, qo'shish, tahrirlash, o'chirish, teglar, eksport va import — avvalgidek.
- Telefonda ham oching.
Biror modul 404 bersa — Brauzerda ESM darsidagi ikki tuzoqni tekshiring: / bilan boshlangan manzil va katta-kichik harf. Lokal Windows'da ishlagan, lekin Pages'da buzilgan modul ko'pincha shulardan biri.
Besh darsdagi ish:
| Dars | refactor/modullar da |
|---|---|
| Nega modullar | reja, vazifa.js |
ESM import |
qolgan beshta modul, type="module", "use strict" olib tashlandi |
| Modul semantikasi | README — modullar xaritasi |
| Brauzerda ESM | modulepreload |
| shu dars | package.json, Node tekshiruvi, merge |
Foydalanuvchi hech qanday farq ko'rmaydi. Ichkarida esa: global'da nol nom, oltita mustaqil fayl va brauzersiz tekshiriladigan mantiq. Bu tuzilma Yakuniy loyiha: vazifalar v2 ning asosi bo'ladi.
9. Real ishda
- Eski kod bazalari. Ko'p kompaniyalarning Node serverlari hamon CommonJS'da. Ularni ESM'ga bosqichma-bosqich ko'chirishda
"type",.cjs,createRequirevarequire(esm)ishlatiladi. - Sozlama fayllari.
eslint.config.js,vite.config.js,postcss.config.mjs,jest.config.cjs— fayl nomidagi kengaytma qaysi tizimni kutayotganini aytadi. Asbob sozlamasi "ishlamayapti" desa, birinchi tekshiruv —"type"va kengaytma mosligi. - npm paketlari. Hujjatda "ESM-only" ("faqat ESM") yozilgan kutubxona eski Node'da
requirebilan ishlamasdi; Node 22.12+ da esa ishlaydi (top-levelawaitbo'lmasa). - Intervyu. "CommonJS va ESM farqi?", "
module.exportsvaexportsfarqi?", "ESM'da__dirnameqanday olinadi?" — Node intervyularining doimiy savollari. Bugungi «Ikki tizim yonma-yon» jadvali — tayyor javob.
Xulosa
- CommonJS:
require()faylni sinxron yuklab,module.exportsni qaytaradi; har fayl funksiyaga o'ralgan — shuning uchun__dirname,requirevathis === module.exports. exports.nom = ...— mumkin;exports = {...}— jim xato. Butun qiymat — faqatmodule.exports.requirekeshlaydi (bir marta bajariladi), qiymatlarni nusxalaydi (jonli emas), istalgan joyda chaqiriladi — shuning uchun tree-shaking qiyin.- Node:
.mjs— ESM,.cjs— CommonJS,.js— eng yaqinpackage.jsondagi"type"; yo'q bo'lsa — sintaksis bo'yicha (ogohlantirish bilan). ESM loyihada"type": "module"ni aniq yozing. - ESM CommonJS'ni import qiladi (
module.exports— default); Node 24 da CommonJS ESM'nirequireqiladi — top-levelawaitsiz grafiklar uchun. - Yangi kod — ESM; CommonJS — o'qish va eski loyihalar uchun.
Keyingi dars: Yakuniy loyiha: vazifalar v2 — 10-qismning hamma bilimini — HOF, closure, klasslar, xatolar va modullarni — bitta toza arxitekturaga yig'amiz.
Manbalar
- Node.js 24 hujjatlari: "Modules: CommonJS modules" (
require(esm), "The module wrapper", "exports shortcut"), "Modules: Packages — Determining module system", "Modules: ECMAScript modules — Interoperability with CommonJS" — nodejs.org/api - MDN: "JavaScript modules" — developer.mozilla.org
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!