Förstå de olika formatet för javascriptmoduler
När det gäller att bygga en applikation frågar du som jag dig alltid: Vilket format ska jag använda? CJS ? AMD? UMD ? ESM ? Vilka är skillnaderna? Varför så många format?
I den här artikeln ska jag försöka besvara dessa frågor 😊.
#De olika formaten
#CommonJS (CJS)
Detta är ett av de första format som skapades. Jag är ganska säker på att du redan har använt det. Det är det modulsystem som ursprungligen inspirerade NodeJS.
Detta system bygger på import och export av moduler tack vare några välkända nyckelord: require
och exports
. module.exports
-objektet är verkligen specifikt för NodeJS.
// 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
CommonJS-teamet skapade det här API:et som ett synkront API, vilket inte är så bra för webbläsare… Dessutom är Commonjs inte naturligt förstått av webbläsare; det kräver antingen ett laddningsbibliotek eller någon transpilering.
#Asynchronous Module Definition (AMD)
AMD är någon slags uppdelning av CommonJS. Den har skapats av medlemmar i CJS-teamet som inte höll med om den riktning som resten av teamet tog.
De har bestämt sig för att skapa AMD för att stödja asynkron modulinläsning. Detta är det modulsystem som används av RequireJS och som fungerar på klientsidan (i webbläsare).
// add.js define(function() { return add = function(r) { return r + r; } }); // index.js define(function(require) { require('./add'); add(4); // = 8 }
Detta exempel fungerar endast om du har requirejs på din webbplats. Du kan hitta några andra AMD-exempel.
#Universal Module Definition (UMD)
Som du kanske har förstått är dessa två format tyvärr ömsesidigt obegripliga för varandra. Det är därför UMD har skapats. Det är baserat på AMD men med några specialfall inkluderade för att hantera CommonJS-kompatibilitet.
Tyvärr tillför denna kompatibilitet en viss komplexitet som gör det komplicerat att läsa/skriva. Om du vill kan du hitta flera mallar av UMD-kod på detta github-repository.
#ES2015 Modules (ESM)
Då dessa tre format inte är så lätta att läsa, svåra att analysera med statisk kodanalysator och inte stöds överallt, beslutade ECMA-teamet (teamet bakom standardiseringen av Javascript) att skapa standarden ECMAScript 2015 (även känd som ES6).Detta format är riktigt enkelt att läsa och skriva och stöder både synkrona och asynkrona driftsätt.
// add.js export function add(r) { return r + r; } // index.js import add from "./add"; add(4); // = 8
För övrigt kan es-moduler analyseras statiskt vilket gör det möjligt för byggverktyg (som Webpack eller Rollup) att utföra tree-shaking på koden. Tree-shaking är en process som tar bort oanvänd kod från buntar.
Det här formatet har tyvärr fortfarande 2 nackdelar (men de förbättras):
- ESM har inte stöd för dynamiskt importerade moduler men det finns ett förslag sedan flera månader tillbaka som har börjat implementeras i vissa webbläsare.
- Det stöds inte av alla webbläsare men som tur är kan detta ”åtgärdas” tack vare… transpiling !
#Transpiling
Transpiling är processen att översätta ett språk eller en version av ett språk till ett annat. Så här är tanken att transpila ES6 till ES5 för att få ett bättre webbläsarstöd. tyvärr har denna transpilering en kostnad eftersom den lägger till lite extra kod för att lappa de saknade funktionerna i ES6 som inte finns i ES5.
Den mest kända transpilern som brukar användas i det här fallet är Babel.
#Fortsatt läsning
Om du vill gå vidare (genom exempel, förklaringar etc.) för att förstå hur dessa olika format fungerar, så finns här några läsningar som jag har hittat och som inspirerat mig:
- JavaScript Module Systems Showdown: CommonJS vs AMD vs ES2015
- Du borde använda esm
- Skrivning av modulärt JavaScript med AMD, CommonJS & ES Harmony
- Vad är AMD, CommonJS och UMD?
- Modulariseringstekniker (det finns flera sidor här)
- Situationen för JavaScript-moduler