Cuando crece el tamaño de un proyecto y tenemos más ficheros de código (cómo al trabajar con clases) es necesario organizarlos de forma que sea fácil encontrarlos y que no haya problemas de dependencias.
Sin embargo tener muchos ficheros hace que tengamos que importarlos todos, y en el orden adecuado, en nuestro index.html (mediante etiquetas <script src="...">) lo que empieza a ser engorroso y reduce el rendimiento al tener el navegador que hacer muchas peticiones HTTP.
Además muchas veces incluimos en el código características del lenguaje que aún no están soportadas por todos los navegadores.
Para evitar este problema se utilizan las herramientas de construcción de proyectos o module bundlers que unen todo el código de los distintos ficheros javascript en un único fichero que es el que se importa en el index.html y hacen los mismo con los ficheros CSS.
Además proporcionan otras ventajas:
Nosotros usaremos el bundler Vite que es el más usado en entorno frontend y mejora el rendimiento de su predecesor webpack. Proporciona:
import / export) desde el primer momentoPara poder usar Vite debemos instalarlo. Como lo usaremos en muchos proyectos lo podemos instalarlo global con
npm install -g vite
Vite se utiliza con npm que es el gestor de paquetes de Node.js por lo que debemos tenerlo instalado. Para crear un nuevo proyecto haremos:
npm create vite@latest
Al crear el proyecto nos pregunta qué framework vamos a utilizar (le diremos que Vanilla, es decir, Javascript sin framework) y si como lenguaje usaremos Javascript o Typescript.
Esto crea un directorio con el nombre de nuestro proyecto que contiene el scaffolding del mismo, con la siguiente estructura: Esto crea una carpeta con la siguiente estructura:
nombre-proyecto/
├── index.html
├── package.json
├── public/
└── src/
├── main.js
├── style.css
└── assets/
└── vite.svg
Lo que tenemos en cada uno de los ficheros y carpetas es:
index.html: html con un div con id app que es donde se cargará la app y una etiqueta script que carga un módulo llamado main.js. No es necesario modificarlopackage.json: fichero de configuración del proyecto. A continuación veremos lo que contiene.public/: carpeta donde dejar elementos estáticos que no pasarán por vite (como imágenes, ficheros CSS, …). Podemos poner imágenes, CSS, etc y lo referenciaremos de forma ABSOLUTA como si estuviera en / la raíz de nuestro proyectosrc/: carpeta donde poner todo nuestro código: los ficheros .js, .css, … En función del tamaño de la aplicación podríamos crear dentro subcarpetas (os propongo un nombre para ellas aunque podéis llamarlas como queráis) para:
model: el modelo de datos, es decir, las clasesviews o pages: las páginas que tendrá nuestra SPA a las que se navega desde el router (aunque en realidad sólo hay una)components: web components que usemos para construir las páginasservices: métodos síncronos que proporcionan funcionalidadapi: acceso a la API que usemos. Sólo deben conectarse al servidor y transmitir los datos recibidos al resto de la aplicación. También podemos crearla dentro de servicesusecases donde guardarlos. Cada uno debería tener un único método llamado run o executetest: carpeta donde guardar los ficheros de testmain.js: es el punto de entrada a la aplicación. Importa los ficheros CSS, imágenes y ficheros JS con funciones o clases y establece el contenido de la página principalxxxx.js: módulos JS que exportan funciones que son usadas en el main.jsstyle.css: fichero donde poner nuestros estilos, con CSS de ejemplo
node_modules: librerías de las dependencias (si usamos alguna). Se creará al instalar las dependencias con npm installNOTA: todos los ficheros javascript de un proyecto con Vite son módulos y en ellos, igual que en las clases, no es necesario poner 'use strict' porque por defecto los módulos ya funcionan así.
Aquí se configura nuestra aplicación. Contiene varios apartados importantes:
npm install nombre-del-paquete -S (la opción -S la añade a package.json como dependencia de producción).npm install nombre-del-paquete -D (la opción -D la añade a package.json pero como dependencia de desarrollo).Si queremos usar un nuevo paquete en nuestra aplicación lo instalaremos con npm:
npm install nombre-paquete
Este comando además de instalar el paquete en node-modules lo añade a las dependencias del package.json. La opción --save o -S lo añadirá como dependencia de producción y --dev o -D como dependencia de desarrollo. Si no ponemos nada se añade como una dependencia de producción. Ej.:
npm install -S bootstrap
Para usarlo debemos importarlo y registrarlo tal y como se indique en su documentación. Lo normal es hacerlo en el main.js (o en algún fichero JS que importemos en main.js como en el caso de los plugins) si queremos poder usarlo en cualquier módulo.
Para empezar a trabajar ejecutamos desde la terminal el script
npm run dev
Este script de Vite funciona como ya vismo en el bloque de Javascript: compila el código, muestra si hay errores, lanza un servidor web (normalmente en el puerto 5173) y carga el proyecto en el navegador (http://localhost:5173). Si cambiamos cualquier fichero del directorio src recompila y recarga la página automáticamente.
import y exportUna de las razones de usar un bundler es que podemos repartir el código entre varios ficheros de forma que quede más organizado. Con Vite podemos dividir nuestro código en ficheros y comunicarlos usando la sintaxis estándar de módulos ES.
Para que un fichero pueda tener acceso a código de otro fichero hay que hacer 2 cosas:
ES6 nos proporciona 2 formas de exportar/importar código:
exportexport defaultDe esta manera puedo exportar tantos elementos (funciones, variables, clases, …) de un fichero como quiera. Por ejemplo, si es un fichero con una única función a exportar:
// Fichero cuadrado.js
export function cuadrado (value) {
return value * value
}
En el caso de querer exportar muchas funciones lo más sencillo es exportarlas juntas en un objeto como en el fichero functions.js:
function letras () {
...
}
function palabras () {
...
}
function maysc () {
...
}
...
export {
letras,
palabras,
maysc
}
Para importarlo lo hacemos poniendo lo que queremos importar entre { }. Si se trata de una única función:
import { cuadrado } from './cuadrado.js'
console.log('El cuadrado de 2 es ' + cuadrado(2))
También podríamos usar un nombre diferente para lo que importamos:
import { cuadrado as cuad} from './cuadrado.js'
console.log('El cuadrado de 2 es ' + cuad(2))
Si es un fichero con muchas funciones exportadas a un objeto podemos importar sólo las que queramos o todas:
import { letras, maysc } from './functions.js'
console.log('Las letras de "Hola" son ' + letras("Hola"))
También podemos importarlas todas a un objeto sin indicar sus nombres, con *:
import * as myFunctions from './functions.js'
console.log('Las letras de "Hola" son ' + myFunctions.letras("Hola"))
De esta manera sólo puedo exportar un elemento por fichero, y a la hora de importarlo le doy el nombre que quiera. Por ejemplo, si es un fichero con una única función a exportar:
// Fichero cuadrado.js
export default function cuadrado (value) {
return value * value
}
Y donde vaya a usarlo:
import myCuadrado from './cuadrado.js'
console.log('El cuadrado de 2 es ' + myCuadrado(2))
En el caso de una clase normalmente se hará de esta manera, exportando la clase por defecto:
export default class Product {
constructor() {
}
...
}
Y para importarla:
import Product from './product.class'
const myProd = new Product()
En resumen, si exporto con export importo con { } y si exporto con export default importo sin { } pero sólo puedo exportar 1 elemento.
Si se trata de imágenes estáticas lo más sencillo es ponerlas dentro de la carpeta public y hacer referencia a ellas usando ruta absoluta. Todo lo que está en public se referencia como si estuviera en la raíz de nuestra aplicación:
<img src="/vite.png" height="100px" alt="Logo de Vite">
También podemos poner las imágenes en la carpeta assets, pero antes de usarlas deberemos imnportarlas. Ejemplo:
import viteLogo from './assets/vite.png'
...
const logoHtml = `<img src="${viteLogo}" height="100px" alt="Vite logo">`
document.body.prepend(logoHtml)
Con Vite también podemos importarlas usando import.meta.url, lo que es útil si no conocemos previamente el nombre del fichero con la imagen (más información en la documentación de Vite):
function getImage(fileName, height, alt) {
const imgUrl = new URL(fileName, import.meta.url).href
const imgHtml = `<img src="${imgUrl}" height="${height}" alt="${alt}">`
return imgHtml
}
Ejemplo: new URL(“../assets/logo.png”, import.meta.url).href // → “http://localhost:5173/assets/logo.png”
Para usar Bootstrap en nuestro proyecto con Vite debemos instalarlo como dependencia de producción:
npm install bootstrap
y luego importarlo en nuestro fichero main.js, preferiblemente antes de importar nuestro propio CSS para que nuestras reglas tengan prioridad:
import 'bootstrap/dist/css/bootstrap.min.css'
Para usar los iconos de Bootstrap debemos instalarlos:
npm install bootstrap-icons
y luego importarlos en nuestro fichero main.js:
import 'bootstrap-icons/font/bootstrap-icons.css'
Para usarlos en nuestro código HTML:
<i class="bi bi-alarm"></i>
Para más información sobre los iconos de Bootstrap podéis consultar la documentación oficial.
A veces necesitamos guardar valores que cambian entre entornos (desarrollo, producción): URLs de APIs, claves, etc. Para eso usamos ficheros .env:
# fichero .env
VITE_API_URL=https://api.ejemplo.com
VITE_API_KEY=mi-clave-secreta
IMPORTANTE: en Vite todas las variables de entorno que queramos usar en el código deben empezar por VITE_. Las accedemos así:
const url = import.meta.env.VITE_API_URL
El fichero .env nunca se sube a Git si contiene información sensible. En su lugar se sube un .env.example con los nombres de las variables pero sin los valores reales.
Cuando lo hayamos acabado y queramos subirlo a producción ejecutaremos
npm run build
que crea la carpeta /dist con los ficheros que debemos subir al servidor web de producción:
index.htmlassets con
Si queremos testear el proyecto deberemos usar una herramienta de testing y crear los tests adecuados. Lo más sencillo es usar Vitest que es muy similar a Jest pero preparado para interacutar fácilmente con Vite.
Lo primero es importarlo como dependencia de desarrollo (no lo usaremos en producción)
npm install --save-dev vitest
o abreviado
npm i -D vitest
Debemos añadir un nuevo script en el package.json que le indique a vite que queremos usarlo para testear:
"scripts": {
...
"test": "vitest"
},
Crearemos los tests en una carpeta en la raíz de nuestro proyecto llamada /test y en ella crearemos los diferentes fichero cuya extensión será .spec.js o .test.js. Cada vez que queramos pasar los tests ejecutaremos
npm run test
Podéis obtener más información en infinidad de páginas de internet, como el Curso DWEC de Jose Castillo, y en la web oficial de vite.