Como usar los módulos JS

Import y export

Como ya sabrás los módulos de JavaScript son archivos que contienen código: funciones, objetos y variables que nos permite organizar y racionalizar programas de cierta entidad.

Las aplicaciones o scripts de JavaScript pueden importar funcine, objetos y variables desde estos archivos. Etos script que imprtan funciones solo tienen que cumplir una sola condición : deben a su vez ser de tipo módulo type="module".

Tu vas a seguir escribiendo tus scripts como siempre, pero si van a usar módulos externos simplemente los declaras como type="module".

Las funciones básicas para usar módulos son dos:

import
Esta directiva se encarga de leer desde el modulo las funciones, objetos y variables que vayas a utilizar en tu aplicación. Solo necesitas decirle que vas a importar y desde donde.
export
Esta función se coloca dentro del módulo para declarar los elementos que se van a exportar. Es decir,  un script solo puede importar aquellos elementos que se declaran exportables.
 

El módulo debe declarar o marcar lo que es exportable, no todo el contenido es legible desde fuera. Y la aplicación importará solo lo que vaya a usar, no necesita importar todo el código del módulo.

Notas

Para poder importar elementos desde un módulo las aplicaciones de JavaScript deben ser del tipo module

Basta con añadir el atributo type="module" al elemento script en la página donde vayas a usarlo.

<script type="module">código JavaScript inline</script>

<script type="module" src="archivo.js"> </script>

Escribir el módulo: export

Para usar módulos lo primero es comprender su estructura y las características que deben cumplir los archivos para ser utilizables como module.

El código contenido en los módulos es como cualquier programa JavaScript: variables, constantes, funciones y objetos.

Solo se añade una directiva export a los elementos que se van a exportar, o sea, elementos que son accesibles (importables) desde fuera. Es decir en el arfchivo hay que definir los elementos que se pueden exportar.

Por ejemplo en este módulo se va a definir una función para detectar si un número es múltiplo de otro: esMultiplo( mult, div )

export { checkEven }

function checkEven( mult, div){

    return (mult % div == 0)

}

Como ves la palabra clave export se antepone al nombre de la función, con lo cual esta función será accesible (importable) desde cualquier aplicación tipo module, ojo. En esta forma usas el nombre de un función ya definida.

Otro ejemplo algo más complejo, se trata de un módulo con una función que devuelve los números pares de una lista de números. Por simplicidad uso código muy básico.

export function extractEven( lista ){

let pares = [];

for (let item = 0; item < lista.length; item++ ){

   if (esPar(lista[ item ])){

     pares.push(lista[ item ]);

     }

  }

return pares;

}

function esPar( num ){

   return (num % 2 == 0);

}

En este ejemplo puedes ver que la función exportada se define en el mismo lugar donde se declara como exportable.

Vemos que la función esPar(num) no es exportable, el archivo externo que use este módulo no ve esa función y no puede importarla. Solo puede importar extractEven()

Existe la opción de usar un elemento exportado por defecto, basta con poner delante export default

En este ejemplo usamos export default, export en definiciones y export con nombres

export default {PI};

export {esPar};

export function extractEven( lista ){

let pares = [];

for (let item = 0; item < lista.length; item++ ){

   if (esPar(lista[ item ])){

     pares.push(lista[ item ]);

   }

}

return pares;

}

function esPar( num ){

   return (num % 2 == 0);

}

let Pi = Math.PI;

Aquí pones un export para cada elemento exportable, pero pueden agruparse, un mismo export seguido de los nombres exportados entre llaves 

export {Pi, esPas, extractEven}

También puedes exportar cambiando nombre, al importar usas el nombre alternativo o alias, como

export extractEven as leerPares

Como ves si sabes programar en JavaScript sabes crear módulos.

Código estricto

Al escribir el código dentro del módulo ten en cuenta que estas en modo estricto, o sea, que estas obligado a declarar las variables antes de usarla, una costumbre, por otro lado, muy sana y aconsejable cuando se escriben programas.

El modo estricto presenta ventajas como:

  1. Evita errores comunes: Prohíbe acciones como el uso de variables sin declararlas, lo que reduce errores.
  2. Mejoras de seguridad: Evita ciertas prácticas que pueden llevar a problemas de seguridad, como el uso de with o la redefinición de propiedades no configurables.
  3. Optimización de rendimiento: En algunos motores JavaScript, el modo estricto permite optimizaciones que pueden hacer que el código se ejecute más rápido.

Uso del módulo: Import

Una vez has creado el módulo toca utilizarlo. Para eso JavaScript provee la directiva import con la que podemos importar los elementos que necesitemos del modulo

La importación es también muy sencilla de realizar solo tienes que saber el nombre del elemento o elementos que vas a importar.

import { Pi } from "./mimodulo.js";

let radio = 20;

let longitud = 2 * Pi * radio;

console.log("Longitud "+longitud);

Importas el elemento, en este caso la constantePi, y lo usas como si estuviera declarado en el script.

Importante: El nombre del módulo debe ser su url (relativa o absoluta) y debe estar alojado en el mismo servidor donde se encuentre el script que lo usa

Puedes importar varios elementos a la vez

import { esPar, extractEven } from "./mimodulo.js";

console.log(esPar(9);

let pares = extracEven([ 4,7,3,5,2,8 ]);

Y para evitar colisiones de nombres con otros que estés usando en tu script puedes cambiar el nombre de un elemento importado

import { Pi as numPi} from "./mimodulo.js";

let area, radio=4;

area = numPi * radio*radio;

console.log("Area "+area);

¿Y si quiero importar todo el módulo? Pues usas el archiconocido comodín asterisco * con un nombre de alias. Este será el nombre del objeto con el que accedes a los elementos del modulo

import * as miObj from "./mimodulo.js";

let radio = 20;

let longitud = 2*miObj.Pi*radio;

console.log("Longitud "+longitud);

console.log( miObj.esPar( 48 ) ) ;

El modulo se convierte en un objeto con los métodos y propiedades definidos en el módulo

 

Usos

Los módulos son ideales para generar componentes web reutilizables. Ejemplo: este from para login

export function createLoginForm() {

const form = document.createElement("form");

// Crear el campo de usuario

const usernameLabel = document.createElement("label");

usernameLabel.textContent = "Usuario:";

const usernameInput = document.createElement("input");

usernameInput.type = "text";

usernameInput.name = "username";

// Crear el campo de contraseña

const passwordLabel = document.createElement("label");

passwordLabel.textContent = "Contraseña:";

const passwordInput = document.createElement("input");

passwordInput.type = "password";

passwordInput.name = "password";

// Botón de envío

const submitButton = document.createElement("button");

submitButton.type = "submit";

submitButton.textContent = "Iniciar sesión";

// Agregar los elementos al formulario

form.appendChild(usernameLabel);

form.appendChild(usernameInput);

form.appendChild(passwordLabel);

form.appendChild(passwordInput);

form.appendChild(submitButton);

return form;

}

En la página web tendrás un script que importe y agregue este form al documento

<script type="module">

import { createLoginForm } from './loginForm.js';

const loginBox = document.getElementById('container');

const loginForm = createLoginForm();

loginBox.appendChild(loginForm);

</script>