Bosh sahifa Wiki Module

Module

Module — dastur kodini alohida mantiqiy yoki texnik birlikka ajratadigan tuzilma. Module function, class, constant va boshqa symbolarni o‘z ichiga oladi hamda qaysi qismlar tashqariga eksport qilinishini belgilaydi.

Module codebase’ni kichik qismlarga bo‘lib, nomlar to‘qnashuvi, dependency va compilationni boshqarishga yordam beradi.

Module chegarasi

Module ichki va tashqi qismlarni ajratadi.

  • Export — boshqa module ishlata oladigan symbol.
  • Internal — faqat module ichida ishlatiladigan implementation.

Yaxshi module public API’ni kichik va aniq saqlaydi.

File module

Ko‘p tillarda har source fayl module bo‘lishi mumkin.

Fayldagi private yoki local nomlar boshqa faylga avtomatik ko‘rinmaydi.

Import orqali kerakli symbol olinadi.

Boshqa tillarda bitta module bir nechta fayldan iborat bo‘lishi mumkin.

Import

Module boshqa module’ga dependency yaratadi.

import math
import storage.client

Import jarayoni:

  • module topish;
  • yuklash;
  • compile yoki parse;
  • initialization;
  • namespacega bog‘lash

bosqichlarini o‘z ichiga olishi mumkin.

Export

Module explicit eksport ro‘yxatini berishi mumkin.

Bu:

  • internal helperni yashiradi;
  • auto-completionni tozalaydi;
  • public contractni hujjatlashtiradi;
  • tree shakingni yengillashtiradi;
  • refactoring chegarasini saqlaydi.

Barcha nomni avtomatik eksport qilish public APIni tasodifiy kengaytiradi.

Module initialization

Module birinchi importda top-level kodni bajarishi mumkin.

Masalan:

  • constant hisoblash;
  • registryga yozilish;
  • config o‘qish;
  • connection yaratish.

Og‘ir yoki side effectli initialization:

  • startupni sekinlashtiradi;
  • import orderga bog‘liqlik;
  • test qiyinligi;
  • circular dependency

keltirib chiqaradi.

Import cache

Runtime module’ni bir marta yuklab, cache’da saqlashi mumkin.

Keyingi import bir xil module objectini qaytaradi.

Bu singleton state yaratadi.

Testlar orasida module global state tozalanmasa natija bir-biriga ta’sir qiladi.

Circular dependency

Module A Bni, B esa Ani import qiladi.

Muammo:

  • A hali to‘liq initialize bo‘lmagan;
  • B Adagi symbolni topolmaydi;
  • partial object;
  • load order xatosi.

Yechimlar:

  • umumiy contractni uchinchi modulega chiqarish;
  • dependency inversion;
  • importni function ichiga kechiktirish;
  • responsibilityni qayta ajratish.

Dependency graph

Modulelar directed graph hosil qiladi.

Node — module, edge — import.

Acyclic graph build va tushunishni osonlashtiradi.

Layer architecture’da yuqori qatlam pastki qatlamga tayanadi, teskari dependency interface orqali boshqariladi.

Namespace bilan munosabat

Module o‘z namespace’ini yaratishi mumkin.

Ammo namespace va module bir xil tushuncha emas.

Bitta namespace bir nechta module’da kengayishi yoki module bir nechta namespace bilan ishlashi mumkin.

Package bilan munosabat

Package bir nechta module’ni guruhlaydi yoki tarqatadi.

Masalan:

package
├── parser module
├── lexer module
└── formatter module

Package manager package’ni o‘rnatadi, runtime esa module’larni import qiladi.

Compilation unit

Compiled tillarda module alohida compilation unit bo‘lishi mumkin.

Afzalliklari:

  • incremental build;
  • parallel compilation;
  • internal symbol hiding;
  • dependency tracking;
  • reusable binary interface.

Header-based tizimlarda module qayta parse xarajatini kamaytirishi mumkin.

Module format

JavaScriptda bir nechta module formatlar mavjud bo‘lgan:

  • ES Modules;
  • CommonJS;
  • AMD;
  • UMD.

Ularning loading, export va runtime semantikasi farq qiladi.

Bundler formatlar orasida transformatsiya qilishi mumkin.

Static import

Static import source’da oldindan ko‘rinadi.

Vositalar:

  • dependency graph;
  • tree shaking;
  • cycle tahlili;
  • preloading

bajarishi mumkin.

Static import odatda module load boshida ishlaydi.

Dynamic import

Module runtime shartiga ko‘ra yuklanadi.

Qo‘llanishlar:

  • code splitting;
  • plugin;
  • optional feature;
  • platform-specific code;
  • lazy loading.

Dynamic path static analysisni qiyinlashtirishi mumkin.

Code splitting

Katta application bir nechta bundle yoki chunkga bo‘linadi.

Foydalanuvchi kerakli module’ni keyin yuklaydi.

Afzalligi — initial load kichik.

Kamchiligi — runtime network request va version mosligi.

Tree shaking

Statik export/import asosida ishlatilmagan code olib tashlanadi.

Side effectli module tree shakingni cheklaydi.

Package metadata module side effect-free ekanini belgilashi mumkin.

Noto‘g‘ri belgi kerakli initializationni olib tashlaydi.

Plugin module

Application belgilangan interface’ga mos module’ni dynamic yuklashi mumkin.

Plugin:

contractiga ega.

Ishonchsiz plugin application huquqida code bajarishi mumkin.

Module state

Top-level variable module singleton state’iga aylanishi mumkin.

Bu:

uchun qulay.

Ammo:

  • parallel test;
  • multi-tenant;
  • hot reload;
  • thread safety

muammosi tug‘dirishi mumkin.

Hot reload

Development muhitida o‘zgargan module qayta yuklanadi.

State saqlanishi yoki reset bo‘lishi frameworkga bog‘liq.

Oldingi instance va yangi code birga qolsa moslik muammosi yuz beradi.

Public module dizayni

Yaxshi module:

  • bitta aniq mas’uliyat;
  • kichik public API;
  • dependency kam;
  • side effect nazoratli;
  • nomlar tushunarli;
  • testlanadigan;
  • cycle’siz.

Module juda mayda bo‘lsa import va navigation shovqini oshadi.

Diagnostika

Module muammosida:

tekshiriladi.

“Symbol mavjud emas” module yuklanmaganini, eksport qilinmaganini yoki partial initializationni bildirishi mumkin.

Module identity

Runtime module’ni faqat fayl nomi bilan emas, canonical path, package nomi yoki loader identity orqali ajratishi mumkin. Bir fayl ikki xil path bilan yuklansa, ikkita module instance va ikkita global state paydo bo‘lishi ehtimoli bor.

Bog‘liq tushunchalar

Import, Export, Namespace, Package, Dependency graph, Circular dependency, Code splitting, Tree shaking, Plugin, Compilation unit