Cómo usar Webpack y Babel para hacer el transpilado del código Javascript y adaptarlo a cualquier navegador, así podrás usar las novedades de Javascript con la certeza que tu código se ejecutará correctamente en cualquier plataforma.
En un proyecto frontend es importante usar las últimas novedades del lenguaje Javascript. A veces porque es útil y productivo para el desarrollador, ya que generalmente las novedades del lenguaje permiten un código más resumido, que ofrece mayor facilidad de mantenimiento. A veces simplemente porque lo exige el stack de tecnologías y los frameworks utilizados.
Claro que no siempre todas las novedades del lenguaje están disponibles en todos los navegadores, por ello es fundamental la operación del transpilado de código. Seguramente a estas alturas todo el mundo sepa qué es transpilar, pero por si algún despistado lo desconoce, es una operación entre el compilado y la traducción, mediante la cual el código creado con versiones superiores de Javascript (o supersets de Javascript como TypeScript) es transformado en código compatible con todos los navegadores del mercado.
En este artículo te mostraremos cómo realizar la transpilación de Javascript con Webpack. Es una operación muy sencilla de realizar, que nos permitirá aprender algo nuevo en nuestro Manual de Webpack.
Babel loader
Los loaders de Webpack hacen una función importante dentro del sistema de empaquetado. Permiten reconocer y trabajar con distintos tipos de archivos, como por ejemplo CSS. Si bien es cierto que Webpack reconoce de manera predeterminada Javascript, si usamos Javascript de versiones modernas y lo queremos convertir a un Javascript compatible con navegadores más antiguos, es necesario disponer de Babel y cargar el loader de Webpack para trabajar con Babel.
Babel-loader se encargará de realizar el puente entre Babel y el propio Webpack, por lo tanto, tenemos que comenzar por instalarlo en nuestro proyecto.
npm i -D babel-loader
Instalar Babel
Para transpilar Javascript la herramienta que usaremos será BabelJS. No es una utilidad específica de Webpack, sino una herramienta autónoma que podemos usar en muchos flujos de desarrollo frontend. Para usarla dentro de Webpack usaremos el babel loader.
El primer paso será entonces instalar esta dependencia de desarrollo, con el siguiente comando de consola. Veremos cómo instalar las dependencias necesarias en versiones de Babel 6 y 7.
Instalación en Babel 6
Este es el comando para instalar Babel en la versión 6, que hoy no es la más actual, pero que permanece disponible por razones históricas.
Adicionalmente necesitamos instalar en el proyecto, también como dependencia de desarrollo, el propio Babel.
npm i -D babel-core
Cómo instalar babel 7
Actualización: Acaba de salir Babel 7. Esta release ha provocado un cambio en los nombres de las dependencias npm que necesitamos para usar Babel, por lo que vamos a dar los comandos de instalación que hoy deberías usar para proyectos nuevos. Los loader de Webpack, así como los plugins de Webpack que usan Babel por debajo, siguen siendo compatibles con Babel 7 y se instalan igual.
Este sería el comando para instalar babel-core para Babel 7:
npm install --save-dev @babel/core
Configuración en webpack.config.js
Una vez instalado, tenemos que configurar Webpack para hacer funcionar a Babel, mediante el archivo webpack.config.js.
El código que tendremos que usar será algo parecido al siguiente:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
}
]
}
}
Hasta aquí hemos realizado la configuración relativa a Webpack, pero aún nos queda algo de trabajo para configurar Babel.
Configurar Babel en el proyecto
Básicamente este procedimiento consiste en decirle a Babel el tipo de transpilado que debe realizar. Ahora en Babel se recomienda usar un "preset" que indica que la versión de nuestro código Javascript es ES2015, ES2016 y ES2017 (todo junto). De este modo conseguimos contar con todas las novedades del estándar de Javascript de los últimos años.
Consta de dos pasos, primero la instalación del preset y luego la configuración mediante un archivo llamado ".babelrc".
Tenemos que comenzar instalando la dependencia del preset "env", que es el recomendado para la mayoría de los casos y permite una configuración muy sencilla de los navegadores a los que nos dirigimos.
Instalar Preset-env en Babel 6
Primero veamos la alternativa de Babel 6:
npm i -D babel-preset-env
Instalar Preset-env en Babel 7
Ahora la alternativa de comando para instalar el preset "env" para Babel 7:
npm i -D @babel/preset-env
Configuración de los navegadores a los que nos dirigimos
Adicionalmente tenemos que crear un archivo de configuración de Babel, que colocaremos en la raíz de nuestro proyecto, justo en el lugar donde se encuentra el package.json. El archivo que tenemos que crear se llama ".babelrc".
El archivo de configuración .babelrc contiene código JSON. En él tenemos que indicar que vamos a usar el preset que se acaba de instalar "env".
Archivo de configuración de preset-env en Babel 6
La configuración es diferente dependiendo de la versión de Babel, ya que la dependencia ha cambiado de nombre. Este sería el código básico para Babel 6.
{
"presets": ["env"]
}
Archivo de configuración de preset-env en Babel 7
En el caso de Babel 7 el nombre del preset "env" ha cambiado y tendremos que actualizar también el .babelrc. Nos quedará así:
{
"presets": ["@babel/preset-env",]
}
Ahora veamos un archivo de código de .babelrc un poco más avanzado, en el que especificamos de manera más detallada el "target" de navegadores a los que nos dirigimos.
{
"presets": [[
"@babel/preset-env",
{
"targets": {
"browsers": [
">=1%",
"not ie 11",
"not op_mini all"
]
},
"debug": true
}
]]
}
Esta manera de trabajar con el preset-env es muy recomendada, puesto que nos permite indicar qué navegadores nos queremos dirigir, sin necesidad de especificar versiones concretas. Simplemente le estamos diciendo:
- Compila el código para dar soporte a navegadores con una cuota de uso de 1% o superior.
- No compiles para Internet Explorer 11 (not ie 11). Obviamente, esto lo tendrás que quitar si quieres dar soporte a ese dinosaurio :P
- No compiles para Opera mini (Opera Mini creo que no entraría como navegadores de uso superior a 1%, pero prefiero ser explícito, porque no soporta nada y no lo usa nadie!)
Esto sería suficiente en principio para funcionar.
Habilitados para usar código Javascript ES2015 (ES6) en adelante
Tal como hemos configurado nuestro proyecto, podemos usar ahora el código Javascript con las nuevas versiones. Veamos un poco de código que podríamos colocar en el archivo de nuestro "entry point".
class miClase {
constructor(x, y) {
this.x = x;
this.y = y;
}
muestraX() {
console.log(this.x);
}
sumar(...valores) {
let suma = 0;
for(let i in valores) {
suma += valores[i];
}
return suma;
}
}
const miObj = new miClase(2, 5);
miObj.muestraX();
console.log(miObj.sumar(2, 4, 5, 6));
Imports de ES6
Otra cosa interesante que podemos hacer ahora que estamos habilitados para trabajar con Javascript ES2015 es la realización de imports, con lo que nos podemos traer el código de otros módulos.
Esto es algo de vital importancia para el mantenimiento de las aplicaciones, ya que al poder dividir el código en diversos archivos, éstos quedan más reducidos, manejables y concisos. Podemos poner cada cosa en su sitio y resultará más sencillo de organizarnos.
Así, desde nuestro index.js podemos escribir:
import './miModulo.js';
Esto quiere decir que tenemos un archivo llamado miModulo.js que estará en la misma carpeta que el index.js. Al hacer el bundle, Webpack juntará el código del index.js con el código de miModulo.js en el Javascript de salida.
Importar librerías instaladas vía npm
Otra cosa que puedes importar de manera sencilla son las librerías de dependencias de terceros, que has instalado vía npm. La manera de hacerlo dependerá un poco de la organización de la librería, pero en líneas generales será más o menos así.
Primero instalar la correspondiente librería usando npm. Por ejemplo, así instalamos moment, una potente y popular librería para trabajo con fechas.
npm i moment
Ahora, desde el archivo Javascript donde quieras usar moment, lo tendrás que importar con el siguiente código de muestra.
import moment from 'moment';
import es from 'moment/locale/es';
En este caso tenemos que importar dos cosas. La primera es la propia librería moment y la segunda sirve para importar los "locales" para el español, es decir, todas las traducciones de la librería que usas para que los mensajes te salgan en español.
Posteriormente podrás usar la librería momentjs normalmente.
let tiempoDesde = moment("20180611", "YYYYMMDD").fromNow();
Ejecutar Webpack con transpilado
Este paso será igual que siempre. Recuerda que podemos ejecutar Webpack directamente desde la línea de comandos, con la siguiente instrucción.
webpack --mode production
Pero que generalmente tendrás tus scripts de npm para hacer algo como "npm run build", tal como ya explicamos en el artículo sobre configuración de Webpack.
Una vez se haya producido el bundle con nuestro código, tendremos todo unido en un único archivo de Javascript, que será compatible con todos los navegadores, incluso aquellos que sólo entienden ES5 (principalmente IE 11 y anteriores).
Al hacer los bundles, Webpack nos ofrecerá una salida como la siguiente. En ella podremos comprobar que se están uniendo varios archivos de código Javascript, los módulos distintos que hemos ido importando a lo largo de los ejemplos de este artículo.
Otra cosa que debes hacer, para verificar que está funcionando todo correctamente, es visualizar el código generado por Webpack, donde no deberían aparecer los códigos de ES6, como las clases, los imports, los "let" y "const", etc. Pero, por supuesto, la prueba de fuego será ejecutar ese código en un Internet Explorer, 11 o anterior, donde debería todo funcionar exactamente del mismo modo que en un navegador moderno (Chorme, Safari, Firefox) donde sí está disponible Ecmascript 2015.
Configuración de Babel en webpack.config.js
Como hemos indicado, el archivo webpack.config.js nos permite indicar que debemos procesar "babel-loader" para cada archivo Javascript. Además de esta configuración también podemos indicarle la opción del preset, lo que nos ahorraría crear el archivo babel.rc que hemos señalado anteriormente.
El código de configuración nos quedaría entonces más o menos como podemos ver a continuación, en webpack.config.js:En el caso de indicar el preset de Babel en la configuración de Webpack nos ahorraría el paso de de realizar el archivo babel.rc. Entonces, nuestro código de configuración para el caso de Babel, quedaría más o menos así.
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: { presets: [['@babel/preset-env']] }
}
}
]
Esta ventaja interesante que ofrece esta alternativa es que permite usar presets o configuraciones de transpilado diferentes dependiendo del archivo de configuración de Webpack que estemos cargando en cada momento.
En el siguiente artículo veremos un ejemplo muy interesante de uso de la configuración de babel en el archivo webpack.config.js, para distribuir código ES6 o ES5 dependiendo del navegador del usuario.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...