Entender los diferentes formatos de módulos javascript
Cuando se trata de construir tu aplicación, si eres como yo siempre te preguntas: ¿qué formato debo usar? ¿CJS ? AMD ? UMD ? ¿ ESM ? ¿Cuáles son las diferencias? ¿Por qué tantos formatos?
A través de este artículo, intentaré responder a esas preguntas 😊.
#Los diferentes formatos
#CommonJS (CJS)
Este es uno de los primeros formatos creados. Seguro que ya lo has utilizado. Es el sistema de módulos que inspiró inicialmente a NodeJS.
Este sistema se basa en la importación y exportación de módulos gracias a unas conocidas palabras clave: require
y exports
. El objeto module.exports
es realmente específico de 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
El equipo de CommonJS creó esta API como una síncrona que no es tan buena para los navegadores… Además, Commonjs no es entendido de forma nativa por los navegadores; requiere una librería de carga o algún transpiling.
#Definición de Módulo Asíncrono (AMD)
AMD es una especie de escisión de CommonJS. Ha sido creada por miembros del equipo de CJS que no estaban de acuerdo con la dirección tomada por el resto del equipo.
Han decidido crear AMD para soportar la carga de módulos asíncronos. Este es el sistema de módulos utilizado por RequireJS y que funciona del lado del cliente (en los navegadores).
// add.js define(function() { return add = function(r) { return r + r; } }); // index.js define(function(require) { require('./add'); add(4); // = 8 }
Este ejemplo sólo funciona si tienes requirejs en tu sitio web. Puedes encontrar otros ejemplos de AMD.
#Definición Universal de Módulos (UMD)
Como habrás entendido esos 2 formatos son desafortunadamente ininteligibles entre sí. Por eso se ha creado el UMD. Está basado en AMD pero con algunos casos especiales incluidos para manejar la compatibilidad con CommonJS.
Desgraciadamente, esta compatibilidad añade cierta complejidad que hace que sea complicado leer/escribir. Si quieres, puedes encontrar múltiples plantillas de código UMD en este repositorio de github.
#ES2015 Modules (ESM)
Como estos 3 formatos no son tan fáciles de leer, son difíciles de analizar por un analizador de código estático y no son compatibles en todas partes, el equipo de ECMA (el equipo detrás de la estandarización de Javascript) decidió crear el estándar ECMAScript 2015 (también conocido como ES6).Este formato es realmente sencillo de leer y escribir y soporta tanto modos de funcionamiento síncronos como asíncronos.
// add.js export function add(r) { return r + r; } // index.js import add from "./add"; add(4); // = 8
Además, los módulos es pueden ser analizados estáticamente lo que permite a las herramientas de construcción (como Webpack o Rollup) realizar tree-shaking en el código. Tree-shaking es un proceso que elimina el código no utilizado de los paquetes.
Desgraciadamente, este formato todavía tiene 2 contras (pero están mejorando):
- ESM no soporta módulos importados dinámicamente pero hay una propuesta desde hace meses que ha empezado a implementarse en algunos navegadores.
- No está soportado en todos los navegadores pero, afortunadamente, esto se puede «arreglar» gracias a… ¡transpiling!
#Transpiling
Transpiling es el proceso de traducir un lenguaje o versión de un lenguaje a otro. Así que aquí, la idea es transpilar ES6 a ES5 para conseguir un mejor soporte de los navegadores.Desgraciadamente, esta transpilación tiene un coste ya que se añade algo de código extra para parchear las características que faltan en ES6 y que no existen en ES5.
El transpilador más famoso que se suele utilizar en este caso es Babel.
#Lecturas adicionales
Si quieres ir más allá (a través de ejemplos, explicaciones, etc.) para entender cómo funcionan esos diferentes formatos, aquí tienes algunas lecturas que he encontrado y que me han inspirado:
- JavaScript Module Systems Showdown: CommonJS vs AMD vs ES2015
- Deberías usar esm
- Escribir JavaScript modular con AMD, CommonJS & Armonía ES
- ¿Qué es AMD, CommonJS y UMD?
- Técnicas de modularización (hay múltiples páginas aquí)
- El estado de los módulos JavaScript