A különböző javascript modulformátumok megértése

Amikor az alkalmazásod építéséről van szó, ha olyan vagy, mint én, mindig felteszed magadnak a kérdést: melyik formátumot használjam ? CJS ? AMD ? UMD ? ESM ? Mik a különbségek ? Miért van ennyi formátum?

Ebben a cikkben megpróbálok választ adni ezekre a kérdésekre 😊.

#A különböző formátumok

#CommonJS (CJS)

Ez az egyik első létrehozott formátum. Biztos vagyok benne, hogy már használtad. Ez az a modulrendszer, amely eredetileg a NodeJS-t inspirálta.

Ez a rendszer a modulok importálására és exportálására támaszkodik néhány jól ismert kulcsszónak köszönhetően: require és exports. A module.exports objektum valóban a NodeJS-re jellemző.

 // utils.js // we create a function function add(r){ return r + r; } // export (expose) add to other modules exports.add = add; // index.js var utils = require('./utils.js'); utils.add(4); // = 8

A commonJS csapat ezt az API-t szinkronnak alkotta meg, ami nem túl jó a böngészők számára… Ráadásul a Commonjs-t a böngészők nem értik natívan; vagy egy betöltő könyvtárat, vagy némi transzpilálást igényel.

#Asynchronous Module Definition (AMD)

Az AMD a CommonJS valamiféle felosztása. A CJS csapat azon tagjai hozták létre, akik nem értettek egyet a csapat többi tagja által követett iránnyal.

Az AMD létrehozása mellett döntöttek, hogy támogassák az aszinkron modul betöltést. Ez a RequireJS által használt modulrendszer, amely kliensoldalon (böngészőkben) működik.

 // add.js define(function() { return add = function(r) { return r + r; } }); // index.js define(function(require) { require('./add'); add(4); // = 8 }

Ez a példa csak akkor működik, ha a weboldaladon van requirejs. Találhatsz más AMD példákat is.

#Universal Module Definition (UMD)

Amint talán megértetted, ez a 2 formátum sajnos kölcsönösen értelmezhetetlen egymás számára. Ezért hozták létre az UMD-t. Ez az AMD-n alapul, de néhány speciális esetet tartalmaz a CommonJS kompatibilitás kezelésére.

Ez a kompatibilitás sajnos némi komplexitást ad hozzá, ami bonyolulttá teszi az olvasást/írást. Ha akarod, megtalálhatod az UMD kód több sablonját ezen a github tárolón.

#ES2015 Modules (ESM)

Mivel ez a 3 formátum nem olyan könnyen olvasható, statikus kódelemzővel nehezen elemezhető és nem mindenhol támogatott, az ECMA csapat (a Javascript szabványosítása mögött álló csapat) úgy döntött, hogy létrehozza az ECMAScript 2015 (más néven ES6) szabványt.Ez a formátum igazán egyszerűen olvasható és írható, és támogatja mind a szinkron, mind az aszinkron működési módokat.

 // add.js export function add(r) { return r + r; } // index.js import add from "./add"; add(4); // = 8

Mellett az es modulok statikusan elemezhetőek, ami lehetővé teszi a build eszközök (mint a Webpack vagy a Rollup) számára, hogy a kódon tree-shakinget végezzenek. A tree-shaking egy olyan folyamat, amely eltávolítja a nem használt kódot a csomagokból.

Sajnos ennek a formátumnak még mindig van 2 hátránya (de javulnak):

  • Az ESM nem támogatja a dinamikusan importált modulokat, de már hónapok óta van egy javaslat, amelyet néhány böngészőben elkezdtek megvalósítani.
  • Nem minden böngésző támogatja, de szerencsére ez “javítható” a… transzpilálásnak köszönhetően !

#Transpilálás

A transzpilálás az egyik nyelv vagy nyelvváltozat lefordítása egy másik nyelvre. Itt tehát arról van szó, hogy az ES6-ot átfordítjuk ES5-be, hogy jobb böngészőtámogatást kapjunk. sajnos ennek az átfordításnak ára van, mivel némi extra kódot adunk hozzá, hogy az ES6 hiányzó funkcióit, amelyek az ES5-ben nem léteznek, befoltozzuk.

A leghíresebb transzpiler, amit ilyenkor általában használnak, a Babel.

#További olvasmányok

Ha tovább akarsz menni (példákon, magyarázatokon stb. keresztül), hogy megértsd, hogyan működnek ezek a különböző formátumok, itt van néhány olvasmány, amit találtam és ami inspirált:

  • JavaScript Module Systems Showdown: CommonJS vs AMD vs ES2015
  • You Should be Using esm
  • Writing Modular JavaScript With AMD, CommonJS & ES Harmony
  • What is AMD, CommonJS, and UMD?
  • Modularization techniques (itt több oldal van)
  • The state of JavaScript modules