HTML, CSS y JavaScript nacieron como lenguajes simples, para crear documentos con un mínimo de interactividad (validar formularios y poco más). La mayor parte de la responsabilidad recaía en el servidor, que era el que se encargaba de hacerlo casi todo, dejando al navegador un papel secundario de visualización.
Con los años, la ubicuidad de Internet y gracias a la mejora de los navegadores, el hardware y los sistemas operativos, estos lenguajes han evolucionado para tener cada vez más potencia, hasta el punto de que, en la actualidad, no tienen casi nada que envidiar a lenguajes más tradicionales. Con HTML, CSS y JavaScript se pueden construir todo tipo de aplicaciones complejas, con casi las mismas capacidades que las nativas y que funcionan más allá de la Web: fuera del navegador en el escritorio, en dispositivos móviles, en servidores...
Al mismo tiempo se han creado inmensas comunidades alrededor de estos lenguajes, y han dado lugar a una explosión de herramientas especializadas, en su mayor parte gratuitas y de código abierto, que nos permiten acelerar mucho el trabajo, disminuir los errores, optimizar el código... y muchas otras cosas más.
Debido a todo esto, lejos quedan ya aquellos tiempos en los que, para crear una aplicación Web, lo único que hacía falta era un editor de texto más o menos avanzado y nada más. Hoy en día es complicado hasta, tan solo, seguirle la pista a todo lo que existe.
En esta guía voy a repasar contigo las principales categorías de herramientas para saber para qué se utilizan y cuáles son las más importantes.
Nota: algunas herramientas que menciono pueden estar en más de una categoría al mismo tiempo, ya que son muy versátiles. Por ejemplo, Webpack es un bundler pero también permite automatizar tareas y muchas cosas más. En esos casos las he colocado en la categoría que mejor encajan de entrada, aunque podrían mencionarse en otras partes también. El orden que he seguido va de lo más sencillo y obvio hasta lo más avanzado. Es posible que me deje algunas cosas en el tintero, ¡porque hay muchas!, pero sí que he querido incluir las más importantes y conocidas de cada categoría.
¡Allá vamos!
Gestores de plantillas
Si tenemos claro qué vamos a construir y con qué, antes de empezar con cualquier proyecto puede resultar muy útil no empezar en blanco y partir de algo ya hecho, que nos deje todos los componentes básicos en su sitio y una estructura de carpetas apropiada.
Por ejemplo, si vamos a crear una aplicación compleja, de nivel empresarial, basada en Angular, podemos usar las herramientas integradas que ofrece Angular Cli o partir de una estructura ya hecha que siga las reglas y buenas prácticas que aconseja el equipo de Angular.
O sea, se trata de conseguir algo parecido a lo que nos dan las plantillas de algunos IDE, como Visual Studio, pero para la Web, e independiente de cualquier editor o entorno de desarrollo.
En Front-End el gestor de plantillas por antonomasia es Yeoman. Se trata de un sistema con más de 3500 plantillas predefinidas en el que puedes encontrar casi de todo. La verdad es que a veces cuesta separar el grano de la paja, pero cuando encuentras tus 2 o 3 plantillas habituales, te ahorra mucho trabajo para arrancar con algunos proyectos.
Linters y formateadores de código
Tanto si se trabaja en equipo como si somos "llaneros solitarios" que trabajamos por nuestra cuenta, mantener la coherencia en el código que escribimos es muy importante a largo plazo. Si escribimos en cada lenguaje de una forma consistente, nos ayudará a entender mejor nuestro código y el de los demás, incluso aunque lo leamos varios meses más tarde, facilitará incorporar nuevas personas al equipo y sobre todo ayudará a que el mantenimiento y ampliaciones futuras no supongan un problema.
Cuando hablo de mantener la consistencia, no sólo me refiero a cosas simples de estilo como poner siempre el punto y coma al final, usar espacios y no tabuladores o que las llaves empiecen en la misma línea que la estructura que envuelven (que también), sino a cosas más complejas como la coherencia en los nombres de las variables y funciones, controlar que se siguen buenas prácticas o el modo estricto, que no se hacen llamadas innecesarias a call()
o apply()
, etc... O sea, reglas de estilo y de calidad.
Este tipo de herramientas nos permiten definir conjuntos de reglas (o incluso usar reglas de empresas conocidas, que ya están probadas), y luego comprueban el código a medida que se escribe de modo que no nos podamos salir del camino marcado. Consiguen aumentar la calidad de nuestros desarrollos, mantener la coherencia y en general evitar los problemas que comentaba al principio.
Las más conocidas y utilizadas son:
- ESLint: se trata de un linter para ECMAScript que es muy configurable y que trae de serie multitud de reglas preconfiguradas (a las que podemos añadir reglas propias). Nos permite reutilizar reglas en el equipo e incluso partir de reglas ya probadas en otras empresas (como AirBnB o Facebook, por ejemplo) y construir sobre ellas.
- JSHint: se trata de otro linter bastante utilizado que es más sencillo de emplear que ESLint, pero que nos proporciona menos flexibilidad y capacidad de ampliación y configuración. Poco a poco se está abandonando su uso por ESLint, pero conviene tenerlo en el radar porque todavía tiene muchos adeptos.
- Prettier: es un formateador de código, no un linter. Esto quiere decir que, como su propio nombre indica, se encarga de asegurar que el código "luce bonito" en cuanto a formato, en lo que se pisa un poco con los linters y es muy importante también, pero no nos ayuda con la calidad. Prettier es el más utilizado y el mejor con diferencia, y está integrado con la práctica totalidad de editores de código avanzados. Soporta más lenguajes que JavaScript, como HTML, CSS, JSX o Markdown, y ofrece muchos plugins para cosas concretas. Un "must have".
Verificadores de tipos estáticos
Como ya sabes, aunque JavaScript dispone de varios tipos de datos nativos y podemos crear nuestros propios tipos, se trata de un lenguaje débilmente tipado. Esto quiere decir, básicamente, que podemos definir una variable (que no lleva tipo alguno asociado) y luego le podemos asignar cualquier valor que deseemos, incluso varias veces, cambiando en cada ocasión el tipo utilizado. Obviamente, esto es una mala práctica, pero la realidad es que es muy fácil confundirse y luego tener problemas por cambios de tipo inesperados o porque le pasamos a una función algo para lo que inicialmente no estaba diseñada.
Los verificadores de tipos estáticos se ocupan de verificar la seguridad de los tipos de datos en nuestro código. Para entendernos, hacen que JavaScript se pueda comportar como un lenguaje tipado, de modo que podamos identificar directamente en el código, ciertos tipos de errores que, por regla general, sólo detectaríamos en ejecución. Como efecto secundario tendremos también mayor facilidad a la hora de escribir el código, ya que si el editor ofrece soporte para alguna de las herramientas que veremos a continuación, obtendremos ya información en línea sobre los tipos esperados, facilitándonos el trabajo. Aunque siempre hay quien no está de acuerdo con esto.
El verificador más conocido y utilizado es Flow. Se trata de un verificador creado por Facebook para uso interno y luego liberado al público en general. Está tomando un gran impulso en los últimos tiempos. Ofrece soporte para inferencia y seguimiento de tipos a partir del código existente, un sistema de tipos opcional, feedback a medida que modificamos el código, anotaciones de tipos, hace linting... Además es muy fácil de poner en marcha y está integrado con los editores más importantes (por ejemplo Atom, Sublime Text, Vim, Emacs, WebStorm... y por supuesto mi favorito, Visual Studio Code).
Además de Flow, el otro gran adalid de los tipos estáticos es TypeScript. En realidad, TypeScript va mucho más allá y es todo un lenguaje + compilador por encima de JavaScript, como veremos más adelante, pero su principal objetivo cuando nació era precisamente dotar de un sistema de tipos para JavaScript (de ahí su nombre), y por eso lo incluyo también en esta categoría.
Aquí te dejo una comparativa entre Flow y TypeScript, pero en mi opinión, ya de invertir en aprender uno de los dos, en la actualidad es más interesante aprender TypeScript, que está ganando muchísima popularidad y cada vez lo usan más empresas. Luego volveré sobre él.
Transpiladores de código
Un transpilador es un programa especializado en transformar código de un lenguaje o variante de lenguaje a otra. En contraste con un compilador tradicional, que transforma código fuente en código máquina listo para ser utilizado por el sistema operativo, un transpilador transforma código en otro código diferente.
¿Y para qué me vale esto? Pues fundamentalmente para dos cosas:
- Para poder utilizar otros lenguajes por encima de JavaScript
- Para poder usar versiones modernas de JavaScript sin problemas con navegadores antiguos
En el primer caso podrás utilizar superconjuntos de JavaScript como TypeScript o CoffeeScript para programar tus aplicaciones con muchas ventajas, y el transpilador correspondiente se encargará de convertir el código que has escrito a JavaScript/ECMAScript que funcione en cualquier navegador.
En el segundo caso, como sabes, JavaScript está evolucionando constantemente a través del organismo de estandarización ECMA, sacando cada año una nueva versión de ECMAScript. Las nuevas características que van apareciendo a veces son muy interesantes para aplicar en los desarrollos, pero los navegadores tardan un tiempo en incorporarlas y además hay usuarios que no tienen su navegador actualizado. Así que, un transpilador nos permite también compilar código moderno de ECMAScript a cualquier versión anterior del lenguaje, incluyendo los "parches" o polyfills que sean necesarios para que funcione. Esto nos da la oportunidad de utilizar las técnicas más modernas sin preocuparnos por posibles incompatibilidades.
Aunque todos los lenguajes superconjunto de JavaScript como los mencionados incluyen su propio transpilador, existe un transpilador predominante que es el que todo el mundo usa: Babel.
Babel nació como una manera de usar características modernas de ECMAScript en navegadores antiguos, pero con el tiempo se ha convertido en el transpilador universal para JavaScript, pudiendo incluso transformar el código con otros propósitos y también transpilar otros lenguajes directamente. Por ejemplo, puedes transpilar TypeScript a JavaScript usando Babel y sin necesidad de usar tsc.exe, el compilador/transpilador de TypeScript.
Lo usarás mucho más de lo que te imaginas, ya que a medida que usas ciertas bibliotecas o frameworks, verás que lo necesitas o que lo integran en su proceso de compilación.
Gestores de dependencias
En la actualidad, es casi imposible desarrollar una aplicación web no trivial sin hacer uso de componentes y bibliotecas externas, además de muchas de las herramientas que estamos viendo en este artículo.
Pero el uso de estas dependencias externas de nuestro proyecto conlleva una serie de complejidades adicionales. En primer lugar, mantenernos actualizados a medida que salen nuevas versiones que añaden funcionalidad, arreglan bugs y problemas de seguridad. Por otro lado, las interacciones y dependencias complejas que se pueden dar entre todo lo que utilizamos, ya que unas bibliotecas dependerán de otras y a veces lo hacen de una versión concreta. Finalmente, un tercer problema principal a solucionar, es el poner en común con todo nuestro equipo que trabaja en la aplicación todas estas dependencias. Es decir, que todos usemos siempre las mimas herramientas, componentes y bibliotecas, en las mismas versiones y con las mismas actualizaciones.
Para lograr estos objetivos necesitamos un buen gestor de dependencias, que nos ayude a llevar cuenta de todas ellas, a actualizarlas automáticamente y que sea capaz de compartir esta información de manera sencilla y transparente con todos los involucrados en el desarrollo.
Los gestores de dependencias más conocidos y utilizados en desarrollo Web Front-End son:
- npm: es hoy en día, con diferencia, el más popular. Si lo relacionas más con el desarrollo de lado servidor... tienes toda la razón: se empezó a utilizar como gestor de dependencias y paquetes de Node.js para aplicaciones de servidor, pero con los años se extendió hasta dominar por completo el Front-End también. Se utiliza, como todos, desde la línea de comandos y volveremos a verlo enseguida porque es capaz de hacer mucho más que gestionar dependencias, siendo en la actualidad una herramienta indispensable para todo desarrollador Web. Tiene un registro online de paquetes en su web y una herramienta de línea de comandos para instalarlos y gestionarlos.
- Yarn: es un proyecto que lanzó Facebook en 2016 para atajar algunas de las limitaciones que tenía npm por aquel entonces. Es 100% compatible con el registro de npm pero lo dota de más velocidad y seguridad de npm, por eso es bastante utilizado por muchos desarrolladores y empresas. Cuando se lanzó aportaba más que ahora, ya que npm se ha puesto "las pilas" y ha mejorado mucho, pero aún así es más rápido, genera menos archivos innecesarios, es más seguro y ofrece cosas únicas muy interesantes, como los Workspaces para poder crear subproyectos gestionados de manera independiente dentro de un único repositorio.
- Bower: es el gestor de paquetes clásico para Front-End ya que nació antes de que npm pudiera gestionarlos. Desde entonces ha ido cayendo en desgracia a favor de npm y Yarn, pero sigue siendo muy utilizado.
- pnpm: se trata de una utilidad relativamente reciente, pero con mucha actividad. Su objetivo es ser compatible con npm pero ser mucho más eficiente y rápido utilizando el espacio de los archivos, yendo más allá de Yarn. Si te preocupa el espacio consumido en disco por las carpetas de dependencias, pnpm merece la pena.
Ejecutores de tareas o Task Runners
Cuando trabajas en un proyecto de cierta envergadura existen infinidad de pequeñas tareas que vas a necesitar realizar una y otra vez. Desde cosas sencillas como copiado de archivos o limpieza de carpetas, hasta compilación/transpilación (como hemos visto), pasando por concantenación de archivos, minimización y ofuscación de código, linting (ver más arriba), optimización de imágenes, vigilancia de archivos, recarga de páginas mientras depuras, ejecución de pruebas/test, etc...
Todas estas tareas se pueden hacer a mano, pero cuando hay que hacerlas constantemente, en un orden determinado y/o en paralelo, y sobre todo después de cada cambio en el código para poder depurar, es necesario recurrir a alguna herramienta que las automatice.
Las herramientas más conocidas y utilizadas son:
- Gulp: que se basa en código JavaScript que escribes en un archivo para describir las diferentes tareas y enlazarlas. Se utiliza, como todos, desde la línea de comandos y dispone de miles de plugins para hacer cualquier cosa que se te ocurra, aunque puedes programar más cosas y combinaciones de los existentes. Es muy utilizado.
- Grunt: otro ejecutor de tareas de código abierto y basado en JavaScript, aunque en este caso prima la configuración frente al código a la hora de definir las tareas. Con miles de plugins para hacer cualquier cosa, tuvo su época dorada hace unos años y ahora está en declive, pero conviene al menos saber que existe porque te lo puedes encontrar por ahí.
- npm: sí, otra vez. El gestor de paquetes es también una excelente herramienta de ejecución de tareas puesto que nos permite crear pequeños scripts que se ejecutan con el comando
npm run
y que sacan partido al apabullante directorio de paquetes que tiene, con decenas de miles de paquetes para hacer cualquier cosa que se te ocurra. En la actualidad es el que se está llevando el gato al agua, siendo utilizado en muchísimos proyectos en detrimento de Gulp. Gran parte del éxito es también que nos ahorramos tener que instalar una nueva herramienta, puesto que npm, sí o sí, lo vamos a tener instalado, así que ¿por qué no aprovecharlo para esto también si puedes?
Otras opciones que han ido surgiendo pero cuya adopción es pequeña y de momento van por detrás de los mencionados en funcionalidad o flexibilidad son:
- Brunch: trata de competir con Gulp haciendo que la configuración y el código sean mucho más sencillos y breves.
- Broccoli.js: es muy sencillo de utilizar y usa instrucciones sencillas de JavaScript en una línea.
Estos no hay que perderlos de vista.
Empaquetadores de módulos o bundlers
Los bundlers nacieron hace unos años como una forma de incluir en un solo archivos múltiples recursos necesarios para una aplicación Web. Por ejemplo, mezclando en un solo archivo todas las bibliotecas JavaScript que usa tu aplicación, de modo que en lugar de tener que descargar 10 archivos, sólo se descarga uno. Esto tenía su lógica en aquel momento pre-HTTP2 porque cada descarga individual de archivos añadía retraso al renderizado de la página y la ejecución de la aplicación, y en aplicaciones grandes y orientadas a móviles cada décima de segundo cuenta.
En la actualidad eso es lo menos importante gracias a HTTP2 (que multiplexa la descarga de archivos a través de una misma conexión), pero los bundlers siguen llevando a cabo tareas importantes para optimizar el código: para empezar son capaces de gestionar dependencias entre partes de la aplicación aunque no usemos módulos, también pueden empaquetar recursos que no son JavaScript dentro de los "bundles" finales, y además ofrecen capacidades de "tree-shaking" del código, es decir, son capaces de eliminar automáticamente todo aquel código que no usa nuestra aplicación reduciendo enormemente el tamaño de la aplicación final.
Además, nos facilitan el uso de las dependencias gestionadas con npm y otros gestores de paquetes (ver más arriba) de modo que, aunque se encuentren en la carpeta node_modules
podamos utilizarlos igualmente y aparezcan en los archivos de la aplicación final. De todos modos, si eso es lo único que necesitamos, ahora existen herramientas como Pika o SystemJS que están empezando a pisar fuerte y tienen una orientación completamente diferente (casi podría haber hecho una categoría aparte en este artículo con ellos, pero lo voy a dejar así 😉).
Finalmente, en la actualidad también incluyen muchas de las atribuciones tradicionales de los ejecutores de tareas que hemos visto antes, ya que son capaces de hacer muchas de las cosas que hacen éstos, incluyendo la transpilación de código usando plugins.
Es por esto que cada vez están ganando más aceptación, aunque generalmente debemos combinarlos con todo lo anterior, en cualquier caso.
Los más conocidos y utilizados son:
- Webpack: es sin duda el rey de los bundlers y la herramienta avanzada que todo desarrollador web Front-End debe conocer. Hace de todo: bundling, transpilación, modularización de código y de recursos (incluyendo dependencias de CSS, fuentes tipográficas o imágenes), optimización, automatización, code splitting, lazy loading, tree shaking, sustitución de módulos en caliente, monitorización automática de dependencias, trabajo para depuración... Puede llegar a ser compleja, pero es la "herramienta total", y muy, muy utilizada. En este artículo, hace tiempo, te explicaba con más detalle qué es y para qué sirve.
- Browserify: el bundler clásico un poco "de capa caída" debido a WebPack. Su principal y mayor objetivo es poder utilizar módulos de Node.js en el navegador. Muchas de las librerías Front-End que se incluían en el directorio de npm están encapsuladas con el sistema de módulos de Node.js, no con el estándar de ECMAScript, y con Browserify utilizarlos era sencillo y directo. Con el soporte nativo para el sistema de módulos de ECMAScript que tienen ya todos los navegadores modernos y el uso de herramientas com Webpack y Pika, su utilidad ahora es menor, pero hay que conocerlo.
- Parcel: es una seria competencia de Webpack que hace hincapié sobre todo en la velocidad y en la facilidad de configuración, y que está ganando mucho terreno en los últimos tiempos.
- Rollup: otro competidor en alza de Webpack que es especialmente bueno con el tree shaking.
En resumen
Todo lo anterior es tan sólo el "tooling", pero hay muchas otras cosas de base que debemos conocer. Sin duda, el mundo actual del desarrollo Web Front-End es mucho más complejo de lo que era hace años, pero a cambio obtenemos más velocidad de desarrollo, mayor calidad y mejora del trabajo en equipo.
Tan solo mantenerse al día de todo lo que hay en el mundillo ya da su trabajo, pero lo principal que debes conocer es lo que te he resumido en este (largo) artículo. He repasado las principales categorías de herramientas que existen, explicando para qué sirven y cuáles son las principales que debes conocer.
Espero que te sirva para ubicarte y saber qué opciones tienes. Y si quieres aprender a dominar las principales herramientas anteriores y dar un salto cualitativo en la profesionalización de tu carrera como desarrollador Web Front-End, ya sabes.