Capire i diversi formati di moduli javascript

Quando si tratta di costruire la tua applicazione, se sei come me ti chiedi sempre: quale formato devo usare? CJS? AMD ? UMD ? ESM ? Quali sono le differenze? Perché così tanti formati?

Con questo articolo, cercherò di rispondere a queste domande 😊.

#I diversi formati

#CommonJS (CJS)

Questo è uno dei primi formati creati. Sono sicuro che l’hai già usato. È il sistema di moduli che ha inizialmente ispirato NodeJS.

Questo sistema si basa sull’importazione e l’esportazione di moduli grazie ad alcune note parole chiave: require e exports. L’oggetto module.exports è davvero specifico di 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

Il team di CommonJS ha creato questa API come sincrona, il che non è molto buono per i browser… Inoltre, Commonjs non è nativamente compreso dai browser; richiede o una libreria di caricamento o un po’ di transpilazione.

#Asynchronous Module Definition (AMD)

AMD è una specie di divisione di CommonJS. È stata creata da membri del team CJS che non erano d’accordo con la direzione presa dal resto del team.

Hanno deciso di creare AMD per supportare il caricamento asincrono dei moduli. Questo è il sistema di moduli usato da RequireJS e che funziona lato client (nei browser).

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

Questo esempio funziona solo se avete requirejs sul vostro sito web. Puoi trovare altri esempi AMD.

#Universal Module Definition (UMD)

Come avrai capito questi 2 formati sono purtroppo incomprensibili tra loro. Questo è il motivo per cui è stato creato l’UMD. È basato su AMD ma con alcuni casi speciali inclusi per gestire la compatibilità con CommonJS.

Purtroppo, questa compatibilità aggiunge una certa complessità che lo rende complicato da leggere/scrivere. Se vuoi, puoi trovare più modelli di codice UMD su questo repository github.

#ES2015 Modules (ESM)

Come questi 3 formati non sono così facili da leggere, difficili da analizzare per l’analizzatore di codice statico e non supportati ovunque, il team ECMA (il team dietro la standardizzazione di Javascript) ha deciso di creare lo standard ECMAScript 2015 (noto anche come ES6).Questo formato è davvero semplice da leggere e scrivere e supporta entrambe le modalità di funzionamento sincrono e asincrono.

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

Inoltre, i moduli es possono essere analizzati staticamente che permettono agli strumenti di build (come Webpack o Rollup) di eseguire il tree-shaking sul codice. Il tree-shaking è un processo che rimuove il codice inutilizzato dai bundle.

Purtroppo, questo formato ha ancora 2 contro (ma stanno migliorando):

  • ESM non supporta i moduli importati dinamicamente ma c’è una proposta da mesi ormai che ha iniziato ad essere implementata su alcuni browser.
  • Non è supportato su tutti i browser ma fortunatamente, questo può essere “aggiustato” grazie al… transpiling !

#Transpiling

Transpiling è il processo di traduzione di una lingua o versione di una lingua in un’altra. Così qui, l’idea è di trasporre ES6 in ES5 per ottenere un miglior supporto del browser.Sfortunatamente, questa trasposizione ha un costo in quanto aggiunge del codice extra per mettere le toppe alle caratteristiche mancanti di ES6 che non esistono in ES5.

Il transpiler più famoso che viene solitamente usato in questo caso è Babel.

#Letture ulteriori

Se volete andare oltre (attraverso esempi, spiegazioni, ecc.) per capire come funzionano questi diversi formati, ecco alcune letture che ho trovato e che mi hanno ispirato:

  • JavaScript Module Systems Showdown: CommonJS vs AMD vs ES2015
  • Si dovrebbe usare esm
  • Scrivere JavaScript modulare con AMD, CommonJS & ES Harmony
  • Cos’è AMD, CommonJS, e UMD?
  • Tecniche di modularizzazione (ci sono più pagine qui)
  • Lo stato dei moduli JavaScript