008. Módulos (import / export)

Los módulos en Javascript significa que podemos llamar a los archivos Javascript no sólo desde el archivo HTML sino también desde un archivo Javascript interno, y esto está ya perfectamente soportado en nuestros navegadores.

Lo ideal es que el código Javascript esté incluido en archivos Javascript independientes.

Mandar llamar un archivo Javascript

Para mandar llamar un archivo Javascript, como recomendación, salvo que el programador de una librería nos diga que invoquemos el script en la cabecera, los archivos Javascript tienen que estar invocados antes del cierre de la etiqueta </body> porque el código Javascript es bloqueante, y si nuestros archivos pesan mucho o son muchos archivos los que estamos llamando en la cabecera, puede ocurrir que el navegador del usuario tarde en cargar el HTML y los estilos.

Ejm

...
<script src="js/modulos.js"></script>
</body>
...

Para que el archivo Javascript tenga la capacidad de llamar internamente a otros archivos Javascript, es muy importante que a la etiqueta de apertura <script> le pongamos un nuevo valor al atributo type, de la siguiente forma.

Ejm

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

Si no tenemos este type en la invocación de nuestra etiqueta <script>, simplemente las importaciones van a mandar error.

Navegadores antiguos

Para navegadores antiguos, podemos incluir otro enlace por si algún navegador no soportase importación de módulos Javascript, con la siguiente sintaxis.

<script src="js/modulos.j" type="module"></script>
<script src="js/no-modulos.js" nomodule></script>

Incluimos un segundo script con el atributo booleano nomodule, para que, si el navegador no soporte módulos, cargue este segundo archivo en vez del primero.

Ordenamiento de código

Conviene  recordar que en los primeros capítulos del curso, mostrábamos el ordenamiento que tiene que tener nuestro código, el cual es:

  • Importación de módulos
  • Declaración de variables
  • Declaración de funciones
  • Ejecución de código

Como podemos ver, lo primero que debemos hacer son las importaciones de módulos.

Mandar llamar a archivos Javascript dentro de otros

Vamos a hacer un ejm. Para ello vamos a crear dos archivos, el archivo módulos, que va a contener otros archivos .js, y un archivo denominado constantes.js, que vamos a exportar al archivo modulos.js, y que va a tener la siguiente sintaxis.

Ejm archivo constantes.js

export const PI = Math.PI;

Y desde el archivo modulos.js vamos a mandar llamar a la constante PI en el archivo constantes.js de la siguiente forma,

Ejm archivo modulos.js

import {PI} from "./constantes.js";

Muy importante: siempre poner para la importación el punto y la barra invertida (./), si no dará error. Si tuviésemos que subir niveles, hacia una carpeta que esté más arriba, por cada nivel habría un punto (../) por un nivel más arriba. Como en nuestro caso está en la misma carpeta, solo pondremos «./».

Muy importante: nuestros archivos siempre tienen que llevar el atributo type=»module» en la etiqueta <script>, si no no funcionarán.

Exportar lo que necesitemos

En un archivo .js podemos exportar lo que necesitemos, no todo. Si no le incluimos la palabra export a nuestra sintaxis, no se exportará.

Ejm

// Esta variable sí se exportará
export const PI = Math.PI;

// Estas dos variables no se exportarán
let usuario = "Francisco";
let passwd = "Francisco";

Nota: No tenemos que exportar necesariamente todo, tan sólo lo que necesitemos.

Exportar funciones

También podemos exportar a manera de objeto, de la siguiente manera. Vamos a exportar operaciones de un archivo denominada aritmetica.js.

Ejm en archivo aritmetica.js

export function sumar(a, b) {
  return a + b;
}

export function restar(a, b) {
  return a - b;
}

Y ahora importamos en nuestro archivo modulos.js como siempre

Ejm en archivo modulos.js

import { PI } from "./constantes.js";
import { sumar, restar } from "./aritmetica.js";

console.log("Archivo modulos.js");
console.log(PI); // Imprimirá en la consola el número PI
console.log(sumar(2,3)); // Imprimirá en la consola 5
console.log(restar(2,3)); // Impirmirá en la consola -3

Devolver todo en un objeto

Las funciones de arriba las vamos a unificar y devolverlas a manera de objeto.

Ejm en archivo aritmetica.js

function sumar(a, b) {
  return a + b;
}

function restar(a, b) {
  return a - b;
}

export const aritmetica = {
  sumar,
  restar,
};

Y el archivo modulos.js quedaría de la siguiente manera.

Ejm en archivo modulos.js

// Importamos los archivos
import { PI } from "./constantes.js";
import { aritmetica } from "./aritmetica.js";

// Realizamos las operaciones que necesitemos
console.log("Archivo modulos.js");
console.log(PI);
console.log(aritmetica.sumar(2, 3));
console.log(aritmetica.restar(2, 3));

Importar por defecto

Significa que cuando vayamos a llamar ese archivo, es la función, variable, clase… que por defecto se va a exportar.

Para ello escribimos la siguiente sintaxis.

Ejm en archivo constantes.js

export default function saludar() {
  console.log("Hola Módulos +ES6");
}

La palabra default indica que cuando se exporte este archivo, esa función se exporta automáticamente,

Nuestro archivo modulos.js quedaría con la siguiente sintaxis

Ejm en archivo modulos.js

import saludar, { PI } from "./constantes.js";
import { aritmetica } from "./aritmetica.js";

console.log("Archivo modulos.js");
console.log(PI);
console.log(aritmetica.sumar(2, 3));
console.log(aritmetica.restar(2, 3));
saludar();

Nota: no se pueden tener dos funciones, objetos, variables… exportadas por defecto, tan sólo puede haber una por archivo. Sólamente puede haber una exportación.

Con export default ocurre que no podemos utilizar export default a la vez que declaramos una variable con const o let, daría error, habría que hacerlo de la siguiente manera.

Ejm

let saludo = "Mi nombre es Francisco";
export default saludo;

Esto ocurre sólo en export default pero no en export sólo, y ocurre porque en el momento en el que se importe el archivo donde se vaya a hacer la invocación, carga ese objeto, esa función por defecto.  Por lo tanto, primero hay que declarar la variable y luego la exportación de la misma. Solamente las funciones y las clases permiten la exportación por defecto en el momento en que se están declarando.

Por lo tanto:

  • Si es constante o variable: primero se hace la declaración, y después la exportación.
  • Si es función o clase: se puede exportar por defecto directamente cuando la estamos creando.

Generar alias

Podemos utilizar un alias para agilizar, de la siguiente forma.

Ejm

import { aritmetica as calculos } from "./aritmetica.js"; // calculos es alias de aritmetica
Scroll al inicio