Polyfills y Transpilación: JavaScript Moderno y Compatible con Todos los Navegadores

¿Alguna vez has experimentado la frustración de que tu código corra en un navegador pero no en otro? ¿Has tratado de utilizar una funcionalidad que no se encuentra disponible en todos los navegadores?

Para quienes están aprendiendo a programar en JavaScript, este problema es muy frustrante y confuso. En este artículo voy a responder las siguientes preguntas:

  • ¿Por qué parece que cada compañía de tecnología tiene su propia implementación de JavaScript?
  • ¿Por qué hay tantos problemas de compatibilidad con JavaScript entre diferentes navegadores?
  • ¿Qué es transpilar código y por qué es tan popular?
  • ¿Qué son los Polyfills?
  • ¿Es bueno tener tantas variaciones e implementaciones del lenguaje?

Empecemos por estudiar un poco la historia de JavaScript.

¿De dónde viene JavaScript?

Netscape creó JavaScript en 1995 con el propósito de permitir que la web fuera más interactiva y dinámica. En esos tiempos, al igual que hoy, había mucha competencia en el mercado entre los nevagadores más populares. Los dos competidores más grandes eran Netscape Navigator y Internet Explorer.

La rápida adopción de JavaScript por la comunidad de programadores puso a Microsoft en una posición difícil. La razón fue que Explorer no era capaz de ejecutar Javascript, lo cual no permitía que sus usuarios navegaran la web con toda su funcionalidad.

En respuesta al crecimiento en el uso de JavaScript, Microsoft se vio forzado a incluir su propia implementación del lenguaje en Internet Explorer, sin embargo, como no existían los estándares de la web ellos crearon su propia versión haciéndole “Reverse-Egineering” a Netscape. Así nació la segunda implementación de JavaScript, conocida como JScript.

JavaScript y JScript eran muy distintos. Microsoft no logró replicar todos los detalles de forma correcta, por lo que la experiencia de navegar en la web dependía del navegador que uno escogiese.

Diseño por Comité: ECMAScript

Los problemas de compatibilidad entre las implementaciones de JavaScript eran un dolor de cabeza tanto para los usuarios de la web como para los programadores. La respuesta de Netscape a este gran caos fue buscar a una organización que se encargara de estandarizar a JavaScript.

¿Qué significa estandarizar? Pues básicamente definir exactamente cuál es la sintaxis y semánticas del lenguaje, de forma que usuarios y compañías puedan crear su propio interpretador del lenguaje.

Netscape encargó a una organización llamada ECMA International con esta tarea. Debido a conflictos de Propiedad Intelectual, ECMA llama a sus especificaciones del lenguaje con el nombre ECMAScript o ES. En 1997 crearon la primera edición del estándar.

Inicia el proceso de estandarización

Gracias a los estándares de ECMA, la compatibilidad de JavaScript entre los navegadores ha mejorado mucho en comparación a unas décadas atrás. Sin embargo, debido a que no todos los navegadores están al día con la última versión de ECMAScript todavía existen incompatibilidades.

¡Internet Explorer no ha implementado casi ninguna característica de ECMAScript 6 (ES6)! (La implementación empieza a partir de Microsoft Edge). Si queremos que nuestra aplicación web sea accessible por los usuarios de estos navegadores viejos tenemos que evitar usar características de ES6. ¿O hay una mejor solución?

JavaScript Moderno: Transpilación de Código

¿Cuál es el escenario ideal para un programador de JavaScript?

Poder utilizar las últimas características especificadas en ECMAScript y lograr que ese código corra en cualquier navegador.

¡Esto es posible! Gracias a librerías como Babel podemos escribir JavaScript ultra-moderno y lograr que sea transpilado a código compatible con todos los navegadores. Por ejemplo, el código de abajo usa las funciones flecha de ES6:

[1,2,3].map(n => n + 1);

Luego de transpilarlo usando Babel obtenemos el siguiente resultado:

"use strict";
[1, 2, 3].map(function (n) {
  return n + 1;
});

Este código utiliza las viejas funciones de JavaScript — ¡puede ser ejecutado en cualquier navegador!

Transpilación es una forma de compilación que toma código escrito en un lenguaje y lo convierte al código equivalente escrito en otro lenguaje. En el ejemplo de arriba transpilamos ES6 a ES5 (una versión de JavaScript que todos los navegadores de hoy implementan).

Nuevos horizontes — Lenguajes Transpilados

Con la popularidad de poder transpilar código han nacido muchísimas variaciones de JavaScript que traen nuevas características y paradigmas al mundo web. Por ejemplo, Microsoft creo un lenguaje llamado TypeScript que se transpila a JavaScript. Este lenguaje se enfoca en permitir construir aplicaciones de JavaScript de gran escala. Otros ejemplos incluyen a CoffeeScript, LiveScript, ClojureScript y Elm.

Máxima Compatibilidad: Polyfills

Entonces, mediante la transpilación podemos transformar ES6 a ES5. En el ejemplo de arriba observamos como la sintaxis de las funciones flecha es transformada a las viejas funciones que ya conocemos. Ahora, te pregunto, ¿Qué pasa cuando transpilamos el código de abajo?

new Promise(function(resolve, reject) {
  // Simular llamada asincrona. En 3 segundos resuelve la promesa.
  setTimeout(function() { resolve(10); }, 3000);
})
.then(function(result) {
  console.log(result);
});

¡Pues Babel genera exactamente el mismo código! En ES5 no existían las promesas, por ende no hay código equivalente que pueda ser generado. En otras palabras, no hay como transpilar las promesas a versiones anteriores de JavaScript.

¿Esto significa que no podemos usar las promesas de ES6 si queremos ser compatibles con navegadores que todavía corren ES5? ¡No! La solución se conoce como Polyfills.

Los Polyfills son código que permiten simular nuevas características de JavaScript en navegadores que no tienen soporte nativo para ellas.

Puedes pensar en Polyfills como el cemento que se usa para arreglar calles llenas de huecos y grietas. Los viejos navegadores necesitan Polyfills para cubrir todas las grietas que el tiempo les ha creado. Abajo puedes ver algunos ejemplos de características de ES6 que requieren Polyfills:

// La función estática Array.from
Array.from(new Set([1, 2, 3, 2, 1]));          // => [1, 2, 3]
 
// La función repeat de los Strings
'*'.repeat(10);                                // => '**********'
 
// Las promesas
Promise.resolve(32).then(x => console.log(x)); // => 32
 
// La función global setImmediate
setImmediate(x => console.log(x), 42);         // => 42
 
// La función estática Object.assign
var obj = { a: 1 };
var copia = Object.assign({}, obj);            // => { a: 1 }

¡Hay muchísimas partes de ES6 que requieren polyfills!

Ok, esto de la compatibilidad me da dolor de cabeza

¡No te preocupes! El ecosistema de JavaScript ha evolucionado para hacer que agregar Polyfills y transpilación sea fácil y eficiente. Librerías como Babel hacen que con unas líneas de configuración no tengas que pensar más en este problema. Y recuerda, el invertir un poco de tiempo configurando este sistema te abre las puertas al JavaScript más moderno (créeme, vale la pena).

Un largo Camino

JavaScript ha tenido una historia bastante compleja en cuanto a compatibilidad, pero estamos empezando a ver como el ecosistema se consolida en ciertas librerías que son consideradas el estándar. Realmente lo fantástico de este océano de problemas es que ha conducido a muchísima innovación. Es sorprendente lo mucho más fácil que es desarrollar aplicaciones complejas de JavaScript hoy en comparación a hace tan solo 5 años. ¡Es un gran momento para aprender este lenguaje!

Si te gustó este artículo, la mejor manera de apoyarnos es compartiéndolo con tus amigos. ¿Te interesa un video que explica cómo configurar Babel para usar polyfills y tanspilación? ¡Déjanos saber tu opinión!

¿Te gustó este artículo? ¡Por favor compártelo para que los demás lo encuentren!

Si estás interesado en aprender a programar APIs con Node.js visita el siguiente curso.

Suscríbete al newsletter para no perderte nuestro contenido. Jamás te enviaré spam.