Zrozumieć różne formaty modułów javascript
Kiedy przychodzi do budowania aplikacji, jeśli jesteś taki jak ja, zawsze zadajesz sobie pytanie: jakiego formatu powinienem użyć ? CJS ? AMD ? UMD ? ESM ? Jakie są różnice ? Dlaczego tyle formatów ?
Poprzez ten artykuł postaram się odpowiedzieć na te pytania 😊.
#Różne formaty
#CommonJS (CJS)
Jest to jeden z pierwszych stworzonych formatów. Jestem prawie pewien, że już go używałeś. Jest to system modułów, który początkowo zainspirował NodeJS.
System ten opiera się na importowaniu i eksportowaniu modułów dzięki kilku dobrze znanym słowom kluczowym: require
i exports
. Obiekt module.exports
jest naprawdę specyficzny dla 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
Zespół CommonJS stworzył to API jako synchroniczne, które nie jest tak dobre dla przeglądarek… Co więcej, Commonjs nie jest natywnie rozumiane przez przeglądarki; wymaga albo biblioteki loadera, albo jakiejś transpilacji.
#Asynchronous Module Definition (AMD)
AMD jest pewnego rodzaju odłamem CommonJS. Został on stworzony przez członków zespołu CJS, którzy nie zgadzali się z kierunkiem obranym przez resztę zespołu.
Postanowili oni stworzyć AMD, aby wspierać asynchroniczne ładowanie modułów. Jest to system modułów używany przez RequireJS i działający po stronie klienta (w przeglądarkach).
// add.js define(function() { return add = function(r) { return r + r; } }); // index.js define(function(require) { require('./add'); add(4); // = 8 }
Ten przykład działa tylko wtedy, gdy masz requirejs na swojej stronie. Możesz znaleźć kilka innych przykładów AMD.
#Universal Module Definition (UMD)
Jak być może zrozumiałeś te 2 formaty są niestety wzajemnie niezrozumiałe dla siebie. Dlatego właśnie stworzono UMD. Jest on oparty na AMD, ale z pewnymi specjalnymi przypadkami uwzględnionymi w celu obsługi kompatybilności CommonJS.
Niestety, ta kompatybilność dodaje pewną złożoność, która komplikuje odczyt / zapis. Jeśli chcesz, możesz znaleźć wiele szablonów kodu UMD na tym repozytorium github.
#ES2015 Modules (ESM)
Jako że te 3 formaty nie są tak łatwe do odczytania, trudne do przeanalizowania dla statycznego analizatora kodu i nie wszędzie obsługiwane, zespół ECMA (zespół stojący za standaryzacją Javascript) zdecydował się stworzyć standard ECMAScript 2015 (znany również jako ES6).Format ten jest naprawdę prosty do odczytu i zapisu oraz obsługuje zarówno synchroniczne, jak i asynchroniczne tryby pracy.
// add.js export function add(r) { return r + r; } // index.js import add from "./add"; add(4); // = 8
Co więcej, moduły es mogą być statycznie analizowane, co pozwala narzędziom budującym (takim jak Webpack lub Rollup) wykonywać tree-shaking na kodzie. Tree-shaking to proces, który usuwa nieużywany kod z wiązek.
Niestety, ten format wciąż ma 2 minusy (ale się poprawiają):
- ESM nie obsługuje dynamicznie importowanych modułów, ale od miesięcy jest propozycja, która zaczęła być wdrażana w niektórych przeglądarkach.
- Nie jest to wspierane na wszystkich przeglądarkach, ale na szczęście można to „naprawić” dzięki… transpilingowi !
#Transpiling
Transpiling jest procesem tłumaczenia jednego języka lub wersji języka na inny. Tak więc tutaj chodzi o transpilację ES6 do ES5, aby uzyskać lepsze wsparcie przeglądarki.Niestety, ta transpilacja ma koszt, ponieważ dodaje trochę dodatkowego kodu, aby załatać brakujące funkcje ES6, które nie istnieją w ES5.
Najbardziej znanym transpilatorem, który jest zwykle używany w tym przypadku, jest Babel.
#Dalsze lektury
Jeśli chcesz pójść dalej (poprzez przykłady, wyjaśnienia itp.), aby zrozumieć, jak działają te różne formaty, oto kilka lektur, które znalazłem i które mnie zainspirowały:
- 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 (there are multiple pages here)
- The state of JavaScript modules
.