Diferencias entre CommonJS y ES Module
- 896Palabras
- 4Minutos
- 09 Sep, 2024
En el desarrollo de JavaScript, los sistemas de módulos juegan un papel crucial al ayudarnos a gestionar y organizar el código. CommonJS y ES Module son dos estándares principales de modularización que presentan diferencias significativas en la carga de módulos, el mecanismo de exportación y la compatibilidad. Este artículo comparará en detalle las principales características y diferencias entre estos dos sistemas de módulos.
1. Forma de carga de módulos
CommonJS:
-
Carga sincrónica: CommonJS utiliza un método de carga sincrónica para los módulos. Esto significa que al usar la función
require()
, el módulo se carga y ejecuta inmediatamente. Este método es muy adecuado para el lado del servidor (como Node.js), pero puede causar problemas de rendimiento en entornos de navegador, ya que el navegador necesita completar la carga del módulo antes de continuar con el código siguiente.1// Importar módulo2const math = require("./math");3console.log(math.add(2, 3));
ES Module:
-
Carga estática y asíncrona: ES Module admite carga estática y asíncrona. La importación de módulos se analiza de forma estática en la fase de compilación, lo que permite al motor de JavaScript optimizar. ES Module admite la carga asíncrona a través de la sintaxis
import
(utilizandoimport()
dinámico), lo que es particularmente importante en entornos de navegador.1// Importación estática2import { add } from "./math.js";3console.log(add(2, 3));45// Importación dinámica6import("./math.js").then((module) => {7console.log(module.add(2, 3));8});
2. Exportación e importación de módulos
CommonJS:
-
Exportación de módulos: Se usa
module.exports
o el objetoexports
para exportar la funcionalidad del módulo. Se pueden exportar objetos, funciones u otros valores.1// Exportar módulo2module.exports = {3add: function (a, b) {4return a + b;5},6}; -
Importación de módulos: Se usa la función
require()
para importar módulos.1// Importar módulo2const math = require("./math");3console.log(math.add(2, 3));
ES Module:
-
Exportación de módulos: Se usa la palabra clave
export
para exportar la funcionalidad del módulo, soportando exportaciones nombradas y exportaciones por defecto.1// Exportación nombrada2export function add(a, b) {3return a + b;4}56// Exportación por defecto7export default function add(a, b) {8return a + b;9} -
Importación de módulos: Se usa la palabra clave
import
para importar módulos, soportando la importación de parte del módulo o del módulo completo.1// Importación de exportaciones nombradas2import { add } from "./math.js";3console.log(add(2, 3));45// Importación de exportación por defecto6import add from "./math.js";7console.log(add(2, 3));
3. Resolución de módulos
CommonJS:
-
Resolución dinámica: Las rutas de los módulos se resuelven dinámicamente, lo que permite calcular las rutas de los módulos en tiempo de ejecución. Esto hace posible la importación condicional o la carga dinámica de módulos.
1const math = require("./math-" + someCondition + ".js");
ES Module:
-
Resolución estática: Las rutas de los módulos se resuelven estáticamente en la fase de compilación, lo que permite al compilador determinar las dependencias antes de que el código se ejecute. Esto permite el análisis estático y la optimización, pero no soporta la resolución dinámica de rutas.
1import { add } from "./math.js";
4. Compatibilidad
CommonJS:
- Principalmente para Node.js: CommonJS es el sistema de módulos por defecto en Node.js. Los entornos de navegador no soportan directamente los módulos CommonJS, pero se pueden usar herramientas como Browserify o Webpack para trabajar con módulos CommonJS.
ES Module:
- Estandarización: ES Module es parte del estándar ECMAScript, y es ampliamente soportado tanto en navegadores modernos como en Node.js. Es el sistema de módulos recomendado tanto para el frontend como para el backend.
5. Comportamiento en tiempo de ejecución
CommonJS:
- Carga dinámica y caché: Los módulos CommonJS se cargan y ejecutan en la primera llamada a
require
, y luego se almacenan en caché. Las llamadas subsecuentes arequire
para el mismo módulo devolverán la instancia del módulo en caché.
ES Module:
- Carga estática y dependencias circulares: ES Module soporta el análisis estático, permitiendo que las dependencias de los módulos se determinen en la fase de compilación. Para las dependencias circulares, ES Module permite la carga parcial, lo que significa que un módulo aún puede referenciar partes de otros módulos mientras se carga.
6. Valores exportados vs. Referencias exportadas
CommonJS:
-
Valores exportados son copias: En CommonJS, los valores exportados del módulo son una copia del objeto exportado. Modificar el objeto exportado no afectará los valores vistos en otros módulos.
math.js 1let count = 0;23module.exports = {4add: function (a, b) {5return a + b;6},7getCount: function () {8return count;9},10};1112// app.js13const math = require("./math");14console.log(math.getCount()); // Salida: 015math.count = 10; // No cambiará el valor devuelto por math.getCount()16console.log(math.getCount()); // Aún muestra: 0
ES Module:
-
Valores exportados son referencias: En ES Module, los valores exportados del módulo son una referencia al objeto original. Las modificaciones al objeto exportado se reflejarán en otros módulos.
math.js 1export let count = 0;23export function add(a, b) {4return a + b;5}67// app.js8import { count, add } from "./math.js";9console.log(count); // Salida: 010count = 10; // Cambia el count en math.js11import { count as newCount } from "./math.js";12console.log(newCount); // Aún muestra: 10
Conclusión
- CommonJS es adecuado para el lado del servidor (Node.js), sus módulos se cargan de manera sincrónica, son simples de usar, pero en un entorno de navegador requieren herramientas adicionales para su soporte.
- ES Module es el sistema de módulos estándar de ECMAScript, admite análisis estático y optimización, es adecuado para navegadores modernos y Node.js, ofreciendo mejor rendimiento y flexibilidad.
Elegir el sistema de módulos adecuado puede ayudar a mejorar la mantenibilidad y el rendimiento del código, por lo que es crucial elegir según las necesidades y el entorno del proyecto.