# Babel

Babel (opens new window) es una herramienta de Javascript que nos permite transpilar el código de versiones modernas del lenguaje a código que cualquier plataforma (navegador/Node (opens new window)) pueda entender. Te muestro un ejemplo sacado de la documentación oficial:

Babel example

De lado izquierdo es el código de ECMAScript2020 usando el nullish coalescing operator (opens new window) y de lado derecho el código transpilado por Babel.

WTF

Aunque el código generado no es tan legible para humanos, la verdad es que no interesa porque ese código es para el intérprete, no para nosotros. Babel nos da la oportunidad de escribir código legible y él se encargará de generar el código que sea necesario para que corra donde sea.

Hoy te mostraré una pequeña configuración que utilizó para mis proyectos backend en Node. Para el frontend te recomiendo usar algún framework como Vue (opens new window), React (opens new window) o Svelte (opens new window), ellos ya se encargan de la configuración por ti.

TIP

Usé la palabra "transpilar" porque a pesar de que se hace una compilación de código, la diferencia es que la transformación se aplica entre lenguajes de similar nivel de abstracción (en este caso versiones diferentes de JS). Si conoces Typescript (opens new window), podríamos decir que también transpila el código porque sigue siendo JS. Por el contrario, el código de Java se compila a lenguaje máquina.

Te dejo unos links que espero despejen tus dudas:

# Requerimientos

npm se instala junto con Node.

# Creación del proyecto

  1. Crea una carpeta para el proyecto y entra en ella.
$ mkdir babel-prueba
$ cd babel-prueba

Si te quieres ver pro, puedes ejecutar mkdir babel-prueba && cd $_. Solo funciona en UNIX.

TIP

Puedes abrir este proyecto en tu editor de código preferido. En lo personal, yo uso Visual Studio Code (opens new window).

  1. Inicia un proyecto con npm.
$ npm init -y

-y nos evita ingresar manualmente la configuración y utiliza todos los valores por defecto.

# Instalación

Necesitamos 3 librerías base de Babel:

# Puedes usar -D como atajo para --save-dev
# Puedes usar `i` como atajo para `install`
$ npm i -D @babel/core @babel/cli @babel/preset-env

Las instalamos como dependencias de desarrollo porque son necesarias para generar el código de producción pero no para que funcione.

# Uso

Ahora crearemos una carpeta src en la que guardaremos todo el código de la aplicación.

$ mkdir src
$ cd src

Y dentro crearemos un archivo index.js con el siguiente contenido:

// src/index.js
console.log('Hola Mundo');

Para que Babel compile nuestros archivos, necesitaremos crear un archivo babel.config.json en la raíz del proyecto (fuera de src) y agregar un script en el package.json.

// babel.config.json
{
  "presets": ["@babel/env"]
}
// package.json
{
  ...
  "scripts": {
    "build": "babel src --out-dir dist"
  }
  ...
}

En el primer archivo le estamos indicando a Babel que queremos que use un preset adicional para que entienda la sintaxis de ES6+. En el build le indicamos que src es la única carpeta que queremos que compile y que el resultado lo guarde en un directorio dist.

Ahora nos movemos a la ruta donde esté el package.json para ejecutar el comando para la compilación:

# En caso de que estuvieramos en `src`, subimos un directorio.
$ cd ..
$ npm run build

Cuando termine la ejecución de este comando, verás que se crea un nuevo directorio dist y dentro un archivo index.js con este contenido:

// dist/index.js
'use strict';

console.log('Hola Mundo');

Hasta aquí no se ve realmente un cambio significativo, solo le agregó una línea al código original 🙃. Pero es porque el console.log está más que soportado por todas las plataformas.

TIP

Si quieres saber más del modo estricto, hablé sobre él en mi artículo de "Buenas prácticas".

Pero agreguemos algo interesante en nuestro src/index.js para que veamos el poder de Babel. Crearemos una pequeña app con Express (opens new window), así que primero instalemos la librería:

# Se agregará como dependencia de producción.
$ npm i express

Y copia este código en tu index. Sin entrar en tanto detalle, se levanta un pequeño servidor que escuchará las peticiones en el puerto 3000, y cuando entres a http://localhost:3000 te responderá con un "Hola Mundo".

// src/index.js
import express from 'express';

const main = async () => {
  const app = express();

  app.get('/', (req, res) => {
    res.send('Hola Mundo');
  });

  await app.listen(3000);
  console.log('Servidor escuchando en http://localhost:3000');
};

main();

DANGER

Siempre modifica los archivos de src, nunca los de dist ya que estos últimos serán sobreescritos en cada compilación.

Ejecuta npm run build para compilar los nuevos archivos. Si ahora revisas el dist/index.js, verás un código muy raro y difícil de entender, pero es la versión del código que cualquier plataforma (navegador/Node) puede entender. Para correr el programa, simplemente ejecuta:

$ node dist/index.js

WARNING

Si al correr el programa obtienes el siguiente error, sigue estos pasos para solucionarlo:

ReferenceError: regeneratorRuntime is not defined

  1. Instala el plugin de Babel @babel/plugin-transform-runtime (opens new window).
$ npm i -D @babel/plugin-transform-runtime
  1. Agrega el plugin en el archivo de configuración de Babel.
{
  "presets": ["@babel/env"],
  "plugins": ["@babel/plugin-transform-runtime"]
}
  1. Vuelve a compilar el proyecto.
$ npm run build

Después de esto ya no deberías tener ningún problema 😉.

# Aliases (Bonus)

Hasta aquí ya puedes trabajar sin ningún problema en tu proyecto con JS moderno, pero te daré un tip que lo tomé de los proyectos de Vue y es el uso de aliases. En realidad, es una configuración de Webpack (opens new window) que viene por defecto cuando creas un proyecto con la Vue CLI (opens new window) pero en este caso lo haremos con Babel.

  1. Primero debemos instalar un plugin de Babel llamado babel-plugin-module-resolver (opens new window) (como dependencia de desarrollo):
$ npm i -D babel-plugin-module-resolver
  1. Modificamos el babel.config.json para agregar la configuración del plugin:
// babel.config.json
{
  "plugins": [
    // otros plugins
    [
      "module-resolver",
      {
        "root": ["."],
        "alias": {
          "@": "./src/"
        }
      }
    ]
  ]
}
  1. Si estás en VSCode (opens new window), agrega un archivo jsconfig.json en la raíz del proyecto.
// jsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

Supongamos que tienes la siguiente estructura en tu proyecto:

babel-prueba
|- babel.config.json
|- jsconfig.json
|- package.json
|- src/
   |- index.js
   |- modelos/
      |- carro-compras/
         |- Item.js
   |- servicios/
      |- carro-compras/
         |- item.js

Ahora dentro de servicios/item.js puedes importar el modelo Item de esta forma:

import Item from '@/modelos/carro-compras/Item';

Y evitar el uso de las rutas relativas usando los puntos ../../:

import Item from '../../modelos/carro-compras/Item';

Con esta configuración ahora podrás importar desde cualquier archivo de una manera más fácil y obtener ayudas del intellisense de VSCode (opens new window). También evitas tener que modificar tus importaciones si mueves tu archivo a un lugar diferente dentro de la estructura de tu proyecto.

# Conclusión

Espero te haya gustado esta útil herramienta del ecosistema de Javascript, te recomiendo que comiences a usarla para que siempre puedas aplicar las nuevas características del lenguaje sin tener que preocuparte por si el código será soportado por navegadores viejos o versiones antiguas de Node.

Happy coding! 🥸