Modullar: import və export
Hər fayl ayrıca moduldur: içindəki hər şey defolt olaraq gizlidir, yalnız export edilən hissə bayırdan görünür. Test layihəsində struktur məhz bunun üzərində qurulur — page object-lər, helper-lər, test datası ayrı-ayrı fayllarda yaşayır.
Named export (adlandırılmış) — bir fayldan istənilən qədər:
- elan yerində:
export const BASE_URL = '...',export class LoginPage {} - import:
import { LoginPage, BASE_URL } from './pages/login.page' - ad dəyişmək:
import { LoginPage as Login } from '...' - hamısını bir ad altında:
import * as pages from './pages'
Default export — faylda cəmi bir dənə:
export default class LoginPage {}- import:
import LoginPage from './pages/login.page'— burada ad İSTƏNİLƏN ola bilər
Məhz bu sərbəstlik default export-un zəif yeridir: eyni class layihənin müxtəlif yerlərində fərqli adlarla import olunur, axtarış və refactoring çətinləşir. Komandaların əksəriyyəti test layihələrində named export-a üstünlük verir.
| Xüsusiyyət | ESM (müasir standart) | CommonJS (Node-un köhnə sistemi) |
|---|---|---|
| Sintaksis | import / export | require() / module.exports |
| Necə aktivləşir | package.json-da "type": "module" və ya .mjs uzantısı | Node-un defoltu; .cjs uzantısı |
| Yüklənmə | statik — alətlər asılılıqları əvvəlcədən görür | dinamik — require() istənilən yerdə çağırıla bilər |
| Top-level await | dəstəklənir | dəstəklənmir |
| Fayl uzantısı importda | təmiz ESM-də tələb olunur ('./api.js') | tələb olunmur |
| Qarışdırmaq | CJS-i import etmək olur | ESM-i require() etmək olmur (yalnız dinamik import()) |
Barrel fayl — qovluğun "giriş qapısı" rolunu oynayan index.ts:
export { LoginPage } from './login.page'; — və testdə import { LoginPage, CartPage } from '../pages' yazmaq olur.
Üstünlüyü: import sətirləri qısalır, daxili fayl strukturunu dəyişmək testlərə toxunmadan mümkün olur. Çatışmazlığı: barrel bir faylı import edəndə bütün qovluğu yükləyir və dairəvi import riskini kəskin artırır.
Dairəvi import (circular import) — A faylı B-ni, B isə A-nı import edir. Nəticə: modullardan biri hələ tam yüklənməmiş halda istifadə olunur və dəyər undefined olur. POM-da klassik təzahürü: BasePage naviqasiya üçün LoginPage-i import edir, LoginPage extends BasePage — və test Class extends value undefined is not a constructor xətası ilə düşür.
Həll yolları: (1) ümumi hissəni üçüncü fayla çıxarmaq (types.ts, constants.ts); (2) valideyn class-ın uşaqlarını tanımasına imkan verməmək — obyekti parametr kimi ötürmək; (3) son çarə: funksiyanın içində dinamik await import('./login.page').
Test framework-ləri importları özləri həll edir və bu, adi Node davranışından fərqlənir. Bilməli olduqların:
- Playwright TypeScript faylları transpile edir və
tsconfig.json-dakıpathsalias-larını (@pages/login) dəstəkləyir — amma həmin alias-larts-node-suz təmiz Node script-ində işləməyəcək - ESM rejimində JSON faylını
import data from './users.json' with { type: 'json' }şəklində və ya sadəcəfs.readFileSyncilə oxumaq lazımdır - Jest öz
moduleNameMappermexanizmi ilə işləyir — Playwright config-indəki alias-lar orada avtomatik tanınmır
İnterview üçün faydalı cümlə: "Import xətaları demək olar həmişə üç səbəbdən yaranır: ESM/CJS qarışığı, alias-ın yalnız bir alətdə konfiqurasiya olunması, və ya dairəvi asılılıq."
📚 Mənbələr və sənədlər
- JavaScript modullarırəsmideveloper.mozilla.org
- Node.js ECMAScript modullarırəsminodejs.org
CommonJS ilə ESM arasındakı fərqlərin rəsmi siyahısı.