El uso de polyfills al escribir aplicaciones de navegador cruzado

Recientemente, me pasó una historia divertida. Hice un proyecto web y amplié las capacidades de una aplicación existente, que mi personal usa en mi organización. Todo parecía estar bien, me alegré de que se lanzara el proyecto, esperando cartas de agradecimiento.

Pocos días después del primer lanzamiento, realmente comencé a recibir cartas. Pero gracias no se observaron en ellos. Los gerentes, los trabajadores de recursos humanos y todos los que intentaron usar mi programa me escribieron. Todos dijeron que su aplicación no funciona correctamente.



Cual es el problema Pero el hecho es que cuando creé el proyecto, lo probé en Chrome. Pero los usuarios de este proyecto usan constantemente Firefox e IE. Trabajar con mi aplicación no fue la excepción. Al final, estaba completamente descontento de que el proyecto, lanzado hace un par de días, tuviera que finalizarse.

De hecho, aquí los polyfills vinieron en mi ayuda.

Polyfills


Un polyfill (polyfill o polyfiller) es una pieza de código (o un cierto complemento) que implementa lo que el desarrollador espera entre las capacidades estándar del navegador. Polyfills permiten, por así decirlo, "suavizar" las irregularidades de las API del navegador.

En un entorno web, los polyfills generalmente están representados por código JavaScript. Este código se utiliza para equipar los navegadores heredados con características modernas que estos navegadores no admiten.

Por ejemplo, usando polyfill, puede simular la funcionalidad del elemento HTML Canvas en Microsoft Internet Explorer 7. Para esto, se utiliza el complemento Silverlight. Polyfill se puede usar para admitir unidades de medida rem en CSS, o el atributo de sombra de texto , o cualquier otra cosa. Las razones por las que los desarrolladores no usan exclusivamente polyfills, sin prestar atención a las capacidades integradas de los navegadores, son que las capacidades estándar de los navegadores proporcionan una mejor funcionalidad y un mayor rendimiento. Las implementaciones propias del navegador de varias API tienen más funciones que los polyfills, y funcionan más rápido.

A veces, los polyfills se usan para resolver problemas asociados con el hecho de que diferentes navegadores implementan las mismas características de diferentes maneras. Dicho polyfill interactúa con algunos navegadores, usando sus características no estándar, y le da acceso a otros programas JavaScript a ciertos mecanismos que cumplen con los estándares. Cabe señalar que tales razones para usar polyfills hoy ya no son tan relevantes como antes. Los Polyfills fueron especialmente frecuentes en los días de IE6, Netscape y NNav, cuando cada navegador implementaba las capacidades de JavaScript de manera diferente a los demás.

Ejemplo


Recientemente publiqué una guía de desarrollo para una aplicación que convierte archivos CSV y Excel a JSON usando JavaScript. Aquí puedes ver la aplicación terminada.

Para tratar con lo que hablaremos a continuación, puede hacer todo lo que se discute en el manual o clonar mi repositorio con el siguiente comando:

 git clone https://github.com/YannMjl/jsdemo-read-cvs-xls-json cd jsdemo-read-cvs-xls-json 

Recomiendo usar VS Code en el proceso. Puede iniciar la aplicación web localmente utilizando la extensión para VS Code Live Server .

Modifiquemos esta aplicación web y observemos los problemas que surgen cuando se trabaja con diferentes navegadores.

Cree una rama de polyfill en el repositorio y cámbiela:

 git checkout -b polyfill 

Voy a investigar la situación en la que obtenemos datos de dos o más archivos CSV y, después de procesar los resultados de las solicitudes a las API correspondientes, enviamos estos datos a una tabla HTML.

▍ Finalización del proyecto.


Cree un nuevo archivo CSV ( team2.csv ) en el directorio raíz del proyecto, como resultado de lo cual debería haber dos archivos. Aquí está el archivo que agregué al proyecto.

script.js archivo script.js para que lea datos de 2 archivos y muestre todos los datos en una tabla HTML. Aquí está mi script.js :

 // ******************************************************************** //                         * //   ,      * // ******************************************************************** var csv_file_API_1 = "./UsersSample.csv"; var csv_file_API_2 = "./team2.csv"; var APIs_array = [csv_file_API_1, csv_file_API_2]; //       $(document).ready(function () {    $("#headerTitle").hide(300).show(1500);    makeAPICalls(); }); // end: document.ready() function makeAPICalls() {    // ,      API    var calls = [];    //  API  CSV-     APIs_array.forEach(function (csv_file_API) {        //             calls.push(new Promise(function (resolve, reject) {            //   API   AJAX            $.ajax({                type: "GET",                url: csv_file_API,                dataType: "text",                cache: false,                error: function (e) {                    alert("An error occurred while processing API calls");                    console.log("API call Failed: ", e);                    reject(e);                },                success: function (data) {                    var jsonData = $.csv.toObjects(data);                    console.log(jsonData);                    resolve(jsonData);                } // end:       API            }); // end: AJAX-        })); // end:         }); // end:   API    //      API    Promise.all(calls).then(function (data) {        //           var flatData = data.map(function (item) {            return item;        }).flat();        console.log(flatData);        dislayData(flatData);    }); } function dislayData(data) {       $.each(data, function (index, value) {        $('#showCSV').append(            '<li class="list-group-item d-flex justify-content-between align-items-center">' +                '<span style="width: 15%; font-size: 1rem; font-weight: bold; color: #37474F">' +                    value['FIRST NAME'] +                '</span>' +                '<span style="width: 15%; font-size: 1rem; color: #37474F">' +                    value['LAST NAME'] +                '</span>' +                '<span class="badge warning-color-dark badge-pill">' +                    value['PHONE NUMBER'] +                '</span>' +                '<span class="badge success-color-dark badge-pill">' +                    value['EMAIL ADDRESS'] +                '</span>' +                '<span class="badge badge-primary badge-pill">' +                    value.CITY +                '</span>' +                '<span class="badge badge-primary badge-pill">' +                    value.STATE +                '</span>' +            '</li>'        );    }); } 

Ahora, después de copiar la dirección de la página, abra el proyecto en todos los navegadores que tenga. En mi caso, estos fueron Internet Explorer, Firefox Mozilla, Microsoft Edge y Google Chrome. Resultó que la aplicación dejó de funcionar normalmente en Internet Explorer y Microsoft Edge. Solo se mostraban los encabezados allí.


Página del proyecto de Chrome


Página del proyecto Microsoft Edge

Algunos navegadores no muestran datos en la página por dos razones:

  1. Usé promesas y devoluciones de llamada que no todos los navegadores admiten. Por ejemplo, entre estos navegadores están IE y Edge.
  2. Utilicé el método de matriz flat() para crear una nueva matriz "plana" a partir de una matriz existente. Este método no es compatible con algunos navegadores. Entre ellos, como en el caso anterior, IE y Edge.

▍ Aplicación de polyfills


Solucionamos el problema de las promesas y devoluciones de llamada utilizando la biblioteca Bluebird . Esta es una implementación JS completa de mecanismos relacionados con promesas. La característica más interesante de la biblioteca Bluebird es que le permite "sobreclasificar" otros módulos de Nodo, procesándolos para que pueda trabajar con ellos de forma asincrónica. Este tipo de procesamiento se puede aplicar al código que utiliza devoluciones de llamada.

Descargue la biblioteca Bluebird a la página utilizando el recurso CDN apropiado. Para hacer esto, coloque lo siguiente en el encabezado del archivo index.html (en el elemento head ):

 <script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.7.0/bluebird.min.js"></script> 

Para solucionar el problema relacionado con el método de matriz flat() , agregue el siguiente código en la parte superior del archivo script.js :

 Object.defineProperty(Array.prototype, 'flat',    {        value: function (depth) {            depth = 1;            return this.reduce(                function (flat, toFlatten) {                    return flat.concat((Array.isArray(toFlatten) && (depth > 1)) ? toFlatten.flat(depth - 1) : toFlatten);                }, []            );        },        configurable: true }); 

Ahora la aplicación debería funcionar en todos los navegadores como se esperaba. Aquí, por ejemplo, así es como se ve ahora en Microsoft Edge.


Página de proyecto refinada en Microsoft Edge

He desplegado este proyecto aquí . Puedes experimentarlo.

Si no logró que el proyecto funcionara, consulte mi repositorio .

Y aquí, por ejemplo, un par más de polyfills.

 //   String.prototype.startsWith() if (!String.prototype.startsWith) {    Object.defineProperty(String.prototype, 'startsWith', {        value: function (search, rawPos) {            pos = rawPos > 0 ? rawPos | 0 : 0;            return this.substring(pos, pos + search.length) === search;        }    }); } //   String.prototype.includes() if (!String.prototype.includes) {    String.prototype.includes = function (search, start) {        'use strict';        if (typeof start !== 'number') {            start = 0;        }        if (start + search.length > this.length) {            return false;        } else {            return this.indexOf(search, start) !== -1;        }    }; } 

Resumen


Los Polyfills fueron especialmente relevantes antes, pero incluso hoy pueden ayudar en el desarrollo de proyectos web entre navegadores. Esperamos que el ejemplo dado aquí permita a aquellos que no sabían sobre polyfill echar un vistazo nuevo al problema de crear sitios diseñados para diferentes navegadores.

Estimados lectores! ¿Usas polyfill?


Source: https://habr.com/ru/post/475248/


All Articles