Cree una herramienta Node.js para registrar y comparar informes de Google Lighthouse
- ¿Qué es el faro de Google?
- configuración
- Abrir Chrome con Node.js
- Ejecutando Faro programáticamente
- Guardar informes de Lighthouse
- Creando el directorio
En este tutorial, te mostraré paso a paso cómo crear una herramienta sencilla en Node.js para ejecutar auditorías de Google Lighthouse a través de la línea de comandos, guardar los informes que generan en formato JSON y luego compararlos para poder monitorear el rendimiento web. a medida que el sitio web crece y se desarrolla.
Espero que esto pueda servir como una buena introducción para cualquier desarrollador interesado en aprender cómo trabajar con Google Lighthouse mediante programación.
Pero primero, para los no iniciados…
¿Qué es el faro de Google?
Google Lighthouse es una de las herramientas mejores automatizadas disponibles en el cinturón de herramientas de un desarrollador web. Le permite auditar rápidamente un sitio web en una serie de áreas clave que, en conjunto, pueden formar una medida de su calidad general. Estos hijo:
- Actuación
- Accesibilidad
- Mejores practicas
- SEO
- Aplicación web progresiva
Una vez completada la auditoría, se genera un informe sobre lo que hace bien… y no tan bien su sitio web, con la intención de que esto último sirva como indicador de cuáles deben ser sus próximos pasos para mejorar la página.
Así es como se ve un informe completo.
Junto con otros diagnósticos generales y métricas de rendimiento web, una característica realmente útil del informe es que cada una de las áreas clave se agrega en evaluación codificadas por colores entre 0 y 100.
Esto no sólo permite a los desarrolladores evaluar rápidamente la calidad de un sitio web sin necesidad de realizar más análisis, sino que también permite que personas sin conocimientos técnicos, como las partes interesadas o los clientes, también lo comprendan.
Por ejemplo, esto significa que es mucho más fácil compartir la victoria con Heather de marketing después de dedicar tiempo a mejorar la accesibilidad del sitio web, ya que es más capaz de apreciar el esfuerzo después de ver que la puntuación de accesibilidad de Lighthouse subió 50. puntos hasta el verde.
Pero igualmente, es posible que Simon, el director del proyecto, no entienda lo que significa Índice de velocidad o Primera pintura con contenido, pero cuando ve el informe Lighthouse que muestra la puntuación de rendimiento del sitio web hasta las rodillas en números rojos, sabe que todavía tiene trabajo por hacer.
Si está en Chrome o en la última versión de Edge, puede ejecutar una auditoría de Lighthouse ahora mismo usando DevTools. Así es cómo:
También puedes ejecutar una auditoría Lighthouse en línea a través de PageSpeed Insights o mediante herramientas de rendimiento populares, como WebPageTest.
Sin embargo, hoy solo estamos interesados en Lighthouse como módulo de Nodo, ya que esto nos permite usar la herramienta mediante programación para auditar, registrar y comparar métricas de rendimiento web.
Averigüemos cómo.
configuración
En primer lugar, si aún no lo tiene, necesitará Node.js. Hay un millón de formas diferentes de instalarlo. Usa el administrador de paquetes Homebrew, pero también puedes descargar un instalador directamente desde el sitio web de Node.js si lo prefieres. Este tutorial se escribió teniendo en cuenta Node.js v10.17.0, pero es muy probable que funcione bien en la mayoría de las versiones lanzadas en los últimos años.
También necesitarás tener Chrome instalado, ya que así es como ejecutaremos las auditorías de Lighthouse.
A continuación, cree un nuevo directorio para el proyecto y luego cd
acceda a él en la consola. Luego npm init
para ejecutar a crear un package.json
archivo. En este punto, recomendaría simplemente presionar la tecla Enter una y otra vez para omitir la mayor cantidad de esto posible hasta que se cree el archivo.
Ahora, creamos un nuevo archivo en el directorio del proyecto. Llamé al mío lh.js
, pero siéntete libre de llamarlo como quieras. Esto contendrá todo el JavaScript de la herramienta. Ábralo en el editor de texto de su elección y, por ahora, escriba una console.log
declaración.
console.log('Hello world');
Luego, en la consola, asegúrese de que su CWD (directorio de trabajo actual) sea el directorio de su proyecto y ejecute node lh.js
, reemplazando mi nombre de archivo por el que haya usado.
Debería ver:
$ node lh.jsHello world
De lo contrario, verifique que la instalación de Node esté funcionando y que definitivamente esté en el directorio del proyecto correcto.
Una vez aclarado esto, podemos continuar con el desarrollo de la herramienta en sí.
Abrir Chrome con Node.js
Instalamos la primera dependencia de nuestro proyecto: el propio Lighthouse.
npm install lighthouse --save-dev
Esto crea un node_modules
directorio que contiene todos los archivos del paquete. Si estás usando Git, lo único que querrás hacer con esto es agregarlo a tu .gitignore
archivo.
En lh.js
, a continuación querrás eliminar la prueba console.log()
e importar el módulo Lighthouse para poder usarlo en tu código. Al igual que:
const lighthouse = require('lighthouse');
Debajo, también necesitarás importar un módulo llamado chrome-launcher, que es una de las dependencias de Lighthouse y permite que Node inicie Chrome por sí solo para que se pueda ejecutar la auditoría.
const lighthouse = require('lighthouse');const chromeLauncher = require('chrome-launcher');
Ahora que tenemos acceso a estos dos módulos, creemos un script simple que simplemente abre Chrome, ejecuta una auditoría de Lighthouse y luego imprime el informe en la consola.
Cree una nueva función que acepte una URL como parámetro. Debido a que ejecutamos esto usando Node.js, podemos usar la sintaxis ES6 de manera segura ya que no tenemos que preocuparnos por esos molestos usuarios de Internet Explorer.
const launchChrome = (url) = {}
Dentro de la función, lo primero que debemos hacer es abrir Chrome usando el módulo iniciador de Chrome que importamos y enviarlo a cualquier argumento que se pase a través del url
parámetro.
Esto lo podemos hacer usando su launch()
método y su startingUrl
opción.
const launchChrome = url = { chromeLauncher.launch({ startingUrl: url });};
Al llamar a la función siguiente y pasar una URL de su elección, Chrome se abre en la URL cuando se ejecuta el script de Node.
launchChrome('https://www.lukeharrison.dev');
La función de inicio en realidad devuelve una promesa que nos permite acceder a un objeto que contiene algunos métodos y propiedades útiles.
Por ejemplo, usando el siguiente código, podemos abrir Chrome, imprimir el objeto en la consola y luego cerrar Chrome tres segundos después usando su kill()
método.
const launchChrome = url = { chromeLauncher .launch({ startingUrl: url }) .then(chrome = { console.log(chrome); setTimeout(() = chrome.kill(), 3000); });};launchChrome("https://www.lukeharrison.dev");
Ahora que hemos resuelto Chrome, pasamos a Lighthouse.
Ejecutando Faro programáticamente
En primer lugar, cambiemos el nombre de nuestra launchChrome()
función a algo que refleja más su funcionalidad final: launchChromeAndRunLighthouse()
. Una vez superada la parte difícil, ahora podemos usar el módulo Lighthouse que importamos anteriormente en el tutorial.
En la función entonces del iniciador de Chrome, que solo se ejecuta una vez que el navegador está abierto, pasaremos a Lighthouse el url
argumento de la función y activaremos una auditoría de este sitio web.
const launchChromeAndRunLighthouse = url = { chromeLauncher .launch({ startingUrl: url }) .then(chrome = { const opts = { port: chrome.port }; lighthouse(url, opts); });};launchChromeAndRunLighthouse("https://www.lukeharrison.dev");
Para vincular la instancia de Lighthouse a la ventana de nuestro navegador Chrome, debemos pasar su puerto junto con la URL.
Si ejecuta este script ahora, aparecerá un error en la consola:
(node:47714) UnhandledPromiseRejectionWarning: Error: You probably have multiple tabs open to the same origin.
Para solucionar este problema, solo necesitamos eliminar la startingUrl
opción de Chrome Launcher y dejar que Lighthouse maneje la URL de navegación de ahora en adelante.
const launchChromeAndRunLighthouse = url = { chromeLauncher.launch().then(chrome = { const opts = { port: chrome.port }; lighthouse(url, opts); });};
Si ejecuta este código, notará que definitivamente algo parece estar sucediendo. Simplemente no recibimos ningún comentario en la consola que confirme que la auditoría de Lighthouse definitivamente se haya ejecutado, ni que la instancia de Chrome se cierre sola como antes.
Afortunadamente, la lighthouse()
función devuelve una promesa que nos permite acceder a los resultados de la auditoría.
Eliminamos Chrome y luego imprimamos esos resultados en la terminal en formato JSON a través de la propiedad de informe del objeto de resultados.
const launchChromeAndRunLighthouse = url = { chromeLauncher.launch().then(chrome = { const opts = { port: chrome.port }; lighthouse(url, opts).then(results = { chrome.kill(); console.log(results.report); }); });};
Si bien la consola no es la mejor manera de mostrar estos resultados, si los copiara en su portapapeles y visitara Lighthouse Report Viewer, al pegarlos aquí se mostrará el informe en todo su esplendor.
En este punto, es importante ordenar un poco el código para que la launchChromeAndRunLighthouse()
función devuelva el informe una vez que termine de ejecutarse. Esto nos permite procesar el informe más tarde sin generar una pirámide desordenada de JavaScript.
const lighthouse = require("lighthouse");const chromeLauncher = require("chrome-launcher");const launchChromeAndRunLighthouse = url = { return chromeLauncher.launch().then(chrome = { const opts = { port: chrome.port }; return lighthouse(url, opts).then(results = { return chrome.kill().then(() = results.report); }); });};launchChromeAndRunLighthouse("https://www.lukeharrison.dev").then(results = { console.log(results);});
Una cosa que quizás hayas notado es que nuestra herramienta solo puede auditar un único sitio web en este momento. Cambiemos esto para que pueda pasar la URL como argumento a través de la línea de comando.
Para aliviar el dolor de trabajar con argumentos de línea de comandos, los manejaremos con un paquete llamado yargs.
npm install --save-dev yargs
Luego, impórtalo en la parte superior de tu secuencia de comandos junto con Chrome Launcher y Lighthouse. Sólo necesitamos su argv
función aquí.
const lighthouse = require('lighthouse');const chromeLauncher = require('chrome-launcher');const argv = require('yargs').argv;
Esto significa que si pasará un argumento de línea de comando en la terminal así:
node lh.js --url https://www.google.co.uk
…puedes acceder al argumento en el script de esta manera:
const url = argv.url // https://www.google.co.uk
Editemos nuestro script para pasar el argumento URL de la línea de comando al url
parámetro de la función. Es importante agregar una pequeña red de seguridad a través de la if
declaración y el mensaje de error en caso de que no se pase ningún argumento.
if (argv.url) { launchChromeAndRunLighthouse(argv.url).then(results = { console.log(results); });} else { throw "You haven't passed a URL to Lighthouse";}
¡Tada! Tenemos una herramienta que inicia Chrome y ejecuta una auditoría Lighthouse mediante programación antes de imprimir el informe en el terminal en formato JSON.
Guardar informes de Lighthouse
Tener el informe impreso en la consola no es muy útil ya que no se puede leer fácilmente su contenido ni se guarda para uso futuro. En esta sección del tutorial, cambiaremos este comportamiento para que cada informe se guarde en su propio archivo JSON.
Para evitar que se mezclen informes de diferentes sitios web, los organizaremos así:
- lukeharrison.dev
- 2020-01-31T18:18:12.648Z.json
- 2020-01-31T19:10:24.110Z.json
- cnn.com
- 2020-01-14T22:15:10.396Z.json
- lh.js
Nombraremos los informes con una marca de tiempo que indique la fecha y hora en que se generó el informe. Esto significará que nunca habrá dos nombres de archivos de informes iguales y nos ayudará a distinguir fácilmente entre informes.
Hay un problema con Windows que requiere nuestra atención: los dos puntos ( :
) son un carácter ilegal para los nombres de archivos. Para mitigar este problema, reemplazaremos los dos puntos con guiones bajos ( _
), por lo que un nombre de archivo de informe típico se verá así:
- 2020-01-31T18_18_12.648Z.json
Creando el directorio
Primero, necesitamos manipular el argumento URL de la línea de comando para poder usarlo para el nombre del directorio.
Esto implica algo más que simplemente eliminar el archivo www
, ya que debe tener en cuenta las auditorías ejecutadas en páginas web que no se encuentran en la raíz (por ejemplo: www.foo.com/bar
), ya que las barras diagonales son caracteres no válidos para los nombres de directorio.
Para estas URL, reemplazaremos nuevamente los caracteres no válidos con guiones bajos. De esa manera, si ejecuta una auditoría en https://www.foo.com/bar
, el nombre del directorio resultante que contiene el informe seríafoo.com_bar.
Para facilitar el manejo de las URL, usaremos un módulo nativo de Node.js llamado url. Esto se puede importar como cualquier otro paquete y sin tener que agregarlo package.json
ni extraerlo a través de npm.
const lighthouse = require('lighthouse');const chromeLauncher = require('chrome-launcher');const argv = require('yargs').argv;const url = require('url');
A continuación, usémoslo para crear una instancia de un nuevo objeto URL.
if (argv.url) { const urlObj = new URL(argv.url); launchChromeAndRunLighthouse(argv.url).then(results = { console.log(results); });}
Si imprimiera urlObj
en la consola, vería muchos datos de URL útiles que podemos usar.
$ node lh.js --url https://www.foo.com/barURL { href: 'https://www.foo.com/bar', origin: 'https://www.foo.com', protocol: 'https:', username: '', password: '', host: 'www.foo.com', hostname: 'www.foo.com', port: '', pathname: '/bar', search: '', searchParams: URLSearchParams {}, hash: ''}
Cree una nueva variable llamada dirName
y use el replace()
método de cadena en la propiedad host de nuestra URL para deshacerse del protocolo www
además https
:
const urlObj = new URL(argv.url);let dirName = urlObj.host.replace('www.','');
Hemos usado let
aquí, que a diferencia const
se puede reasignar, ya que necesitaremos actualizar la referencia si la URL tiene un nombre de ruta, para reemplazar las barras diagonales con guiones bajos. Esto se puede hacer con un patrón de expresión regular y tiene este aspecto:
const urlObj = new URL(argv.url);let dirName = urlObj.host.replace("www.", "");if (urlObj.pathname !== "/") { dirName = dirName + urlObj.pathname.replace(///g, "_");}
Ahora podemos crear el directorio en sí. Esto se puede hacer mediante el uso de otro módulo nativo de Node.js llamado fs (abreviatura de "sistema de archivos").
const lighthouse = require('lighthouse');const chromeLauncher = require('chrome-launcher');const argv = require('yargs').argv;const url = require('url');const fs = require('fs');
Podemos usar su mkdir()
método para crear un directorio, pero primero debemos usar su existsSync()
método para verificar si el directorio ya existe, ya que de lo contrario Node.js arrojaría un error:
const urlObj = new URL(argv.url);let dirName = urlObj.host.replace("www.", "");if (urlObj.pathname !== "/") { dirName = dirName + urlObj.pathname.replace(///g, "_");}if (!fs.existsSync(dirName)) { fs.mkdirSync(dirName);}
Probar el script en ese momento debería dar como resultado la creación de un nuevo directorio. Pasar https://www.bbc.co.uk/news
como argumento URL daría como resultado un directorio llamado bbc.co.uk_news
.
Guardando el informe
En la then
función para launchChromeAndRunLighthouse()
, queremos reemplazar la existente console.log
con lógica para escribir el informe en el disco. Esto se puede hacer usando el writeFile()
método del módulo fs.
launchChromeAndRunLighthouse(argv.url).then(results = { fs.writeFile("report.json", results, err = { if (err) throw err; });});
El primer parámetro representa el nombre del archivo, el segundo es el contenido del archivo y el tercero es una devolución de llamada que contiene un objeto de error en caso de que algo salga mal durante el proceso de escritura. Esto crearía un nuevo archivo llamado que report.json
contiene el objeto JSON del informe Lighthouse que regresa.
Aún necesitamos enviarlo al directorio correcto, con una marca de tiempo como nombre de archivo. Lo primero es simple: pasamos la dirName
variable que creamos anteriormente, así:
launchChromeAndRunLighthouse(argv.url).then(results = { fs.writeFile(`${dirName}/report.json`, results, err = { if (err) throw err; });});
Sin embargo, esto último requiere que recuperemos de alguna manera una marca de tiempo de cuándo se generó el informe. Afortunadamente, el informe en sí captura esto como un punto de datos y se almacena como fetchTime
propiedad.
Sólo debemos recordar cambiar los dos puntos ( :
) por guiones bajos ( _
) para que funcione bien con el sistema de archivos de Windows.
launchChromeAndRunLighthouse(argv.url).then(results = { fs.writeFile( `${dirName}/${results["fetchTime"].replace(/:/g, "_")}.json`, results, err = { if (err) throw err; } );});
Si ejecutara esto ahora, en lugar de un timestamped.json
nombre de archivo, probablemente vería un error similar a:
UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'replace' of undefined
Esto sucede porque Lighthouse actualmente devuelve el informe en formato JSON, en lugar de un objeto consumible por JavaScript.
Afortunadamente, en lugar de analizar el JSON nosotros mismos, podemos pedirle a Lighthouse que devuelva el informe como un objeto JavaScript normal.
Esto requiere editar la siguiente línea de:
return chrome.kill().then(() = results.report);
…a:
return chrome.kill().then(() = results.lhr);
Ahora, si vuelve a ejecutar el script, el archivo tendrá el nombre correcto. Sin embargo, cuando se abre, desafortunadamente su único contenido será...
[object Object]
Esto se debe a que ahora tenemos el problema opuesto al anterior. Estamos intentando representar un objeto JavaScript sin convertirlo primero en un objeto JSON.
La solución es sencilla. Para evitar tener que desperdiciar recursos analizando o codificando este enorme objeto, podemos devolver ambos tipos desde Lighthouse:
return lighthouse(url, opts).then(results = { return chrome.kill().then(() = { return { js: results.lhr, json: results.report }; });});
Luego podemos modificar la writeFile
instancia a esto:
fs.writeFile( `${dirName}/${results.js["fetchTime"].replace(/:/g, "_")}.json`, results.json, err = { if (err) throw err; });
¡Ordenado! Al finalizar la auditoría de Lighthouse, nuestra herramienta ahora debería guardar el informe en un archivo con un nombre de archivo único con marca de tiempo en un directorio que lleva el nombre de la URL del sitio web.
Esto significa que los informes ahora están organizados de manera mucho más eficiente y no se anulan entre sí sin importar cuántos informes se guarden.
Comparación de informes Lighthouse
Durante el desarrollo diario, cuando me concentro en mejorar el rendimiento, la capacidad de comparar informes muy rápidamente directamente en la consola y ver si voy en la dirección correcta podría ser extremadamente útil. Teniendo esto en cuenta, los requisitos de esta funcionalidad de comparación deberían ser:
- Si ya existe un informe anterior para el mismo sitio web cuando se completa una auditoría de Lighthouse, realice automáticamente una comparación con él y muestre cualquier cambio en las métricas clave de rendimiento.
- También debería poder comparar métricas clave de rendimiento de dos informes cualesquiera, de dos sitios web cualesquiera, sin tener que generar un nuevo informe Lighthouse que quizás no necesite.
¿Qué partes de un informe deben compararse? Estas son las métricas numéricas clave de rendimiento recopiladas como parte de cualquier informe Lighthouse. Proporcionan información sobre el rendimiento objetivo y percibido de un sitio web.
Además, Lighthouse también recopila otras métricas que no figuran en esta parte del informe pero que aún se encuentran en un formato adecuado para incluirlas en la comparación. Estos son:
- Tiempo hasta el primer byte: el tiempo hasta el primer byte identifica el momento en que su servidor envía una respuesta.
- Tiempo total de bloqueo: suma de todos los períodos de tiempo entre FCP y Time to Interactive, cuando la duración de la tarea superó los 50 ms, expresada en milisegundos.
- Latencia de entrada estimada: la latencia de entrada estimada es una estimación de cuánto tiempo tarda su aplicación en responder a la entrada del usuario, en milisegundos, durante la ventana de 5 segundos más ocupada de carga de la página. Si su latencia es superior a 50 ms, los usuarios pueden percibir que su aplicación está retrasada.
¿Cómo se debe enviar la comparación de métricas a la consola? Crearemos una comparación simple basada en porcentajes utilizando las métricas antiguas y nuevas para ver cómo han cambiado de un informe a otro.
Para permitir un escaneo rápido, también codificaremos con colores las métricas individuales dependiendo de si son más rápidas, más lentas o no cambian.
Apuntaremos a este resultado:
Comparar el nuevo informe con el informe anterior
Comencemos creando una nueva función llamada compareReports()
justo debajo de nuestra launchChromeAndRunLighthouse()
función, que contendrá toda la lógica de comparación. Le daremos dos parámetros ( from
y to
) para aceptar los dos informes utilizados para la comparación.
Por ahora, como marcador de posición, simplemente imprimiremos algunos datos de cada informe en la consola para validar que los reciba correctamente.
const compareReports = (from, to) = { console.log(from["finalUrl"] + " " + from["fetchTime"]); console.log(to["finalUrl"] + " " + to["fetchTime"]);};
Como esta comparación comenzaría después de la creación de un nuevo informe, la lógica para ejecutar esta función debe ubicarse en la then
función for launchChromeAndRunLighthouse()
.
Si, por ejemplo, tiene 30 informes en un directorio, debemos determinar cuál es el más reciente y configurarlo como el informe anterior con el que se comparará el nuevo. Afortunadamente, ya decidimos usar una marca de tiempo como nombre de archivo para un informe, por lo que esto nos da algo con qué trabajar.
En primer lugar, debemos recopilar los informes existentes. Para facilitar este proceso, instalaremos una nueva dependencia llamada glob, que permite la coincidencia de patrones al buscar archivos. Esto es fundamental porque no podemos predecir cuántos informes existirán ni cómo se llamarán.
Instálalo como cualquier otra dependencia:
npm install glob --save-dev
Luego impórtalo en la parte superior del archivo de la misma manera que de costumbre:
const lighthouse = require('lighthouse');const chromeLauncher = require('chrome-launcher');const argv = require('yargs').argv;const url = require('url');const fs = require('fs');const glob = require('glob');
Lo usaremos glob
para recopilar todos los informes en el directorio, cuyo nombre ya conocemos a través de la dirName
variable. Es importante configurar su sync
opción en true
ya que no queremos que la ejecución de JavaScript continúe hasta que sepamos cuántos otros informes existen.
launchChromeAndRunLighthouse(argv.url).then(results = { const prevReports = glob(`${dirName}/*.json`, { sync: true }); // et al});
Este proceso devuelve una serie de rutas. Entonces, si el directorio de informes se viera así:
- lukeharrison.dev
- 2020-01-31T10_18_12.648Z.json
- 2020-01-31T10_18_24.110Z.json
…entonces la matriz resultante se vería así:
[ 'lukeharrison.dev/2020-01-31T10_18_12.648Z.json', 'lukeharrison.dev/2020-01-31T10_18_24.110Z.json']
Debido a que solo podemos realizar una comparación si existe un informe anterior, usemos esta matriz como condicional para la lógica de comparación:
const prevReports = glob(`${dirName}/*.json`, { sync: true});if (prevReports.length) {}
Tenemos una lista de rutas de archivos de informes y necesitamos comparar sus nombres de archivo con marca de tiempo para determinar cuál es el más reciente.
Esto significa que primero debemos recopilar una lista de todos los nombres de archivos, recortar cualquier dato irrelevante, como los nombres de directorios, y tener cuidado de reemplazar los guiones bajos ( _
) con dos puntos ( :
) para convertirlos nuevamente en fechas válidas. La forma más sencilla de hacerlo es utilizando path
, otro módulo nativo de Node.js.
const path = require('path');
Pasando la ruta como argumento de su parse
método, así:
path.parse('lukeharrison.dev/2020-01-31T10_18_24.110Z.json');
Devuelve este útil objeto:
{ root: '', dir: 'lukeharrison.dev', base: '2020-01-31T10_18_24.110Z.json', ext: '.json', name: '2020-01-31T10_18_24.110Z'}
Por lo tanto, para obtener una lista de todos los nombres de archivos de marca de tiempo, podemos hacer esto:
if (prevReports.length) { dates = []; for (report in prevReports) { dates.push( new Date(path.parse(prevReports[report]).name.replace(/_/g, ":")) ); }}
Lo cual nuevamente si nuestro directorio se viera así:
- lukeharrison.dev
- 2020-01-31T10_18_12.648Z.json
- 2020-01-31T10_18_24.110Z.json
Resultaría en:
[ '2020-01-31T10:18:12.648Z', '2020-01-31T10:18:24.110Z']
Una cosa útil acerca de las fechas es que son inherentemente comparables de forma predeterminada:
const alpha = new Date('2020-01-31');const bravo = new Date('2020-02-15');console.log(alpha bravo); // falseconsole.log(bravo alpha); // true
Entonces, al usar una reduce
función, podemos reducir nuestro conjunto de fechas hasta que solo quede la más reciente:
dates = [];for (report in prevReports) { dates.push(new Date(path.parse(prevReports[report]).name.replace(/_/g, ":")));}const max = dates.reduce(function(a, b) { return Math.max(a, b);});
Si imprimieras el contenido en max
la consola, arrojaría una marca de tiempo UNIX, por lo que ahora solo tenemos que agregar otra línea para convertir nuestra fecha más reciente nuevamente al formato ISO correcto:
const max = dates.reduce(function(a, b) { return Math.max(a, b);});const recentReport = new Date(max).toISOString();
Suponiendo que esta sea la lista de informes:
- 2020-01-31T23_24_41.786Z.json
- 2020-01-31T23_25_36.827Z.json
- 2020-01-31T23_37_56.856Z.json
- 2020-01-31T23_39_20.459Z.json
- 2020-01-31T23_56_50.959Z.json
El valor de recentReport
sería 2020-01-31T23:56:50.959Z
.
Ahora que conocemos el informe más reciente, lo siguiente que debemos hacer es extraer su contenido. Cree una nueva variable llamada recentReportContents
debajo de la recentReport
variable y asígnele una función vacía.
Como sabemos, esta función siempre deberá ejecutarse, en lugar de llamarla manualmente, tiene sentido convertirla en una IFFE (expresión de función invocada inmediatamente), que se ejecutará sola cuando el analizador de JavaScript la alcance. Esto se indica mediante el paréntesis adicional:
const recentReportContents = (() = {})();
En esta función, podemos devolver el contenido del informe más reciente utilizando el readFileSync()
método del fs
módulo nativo. Debido a que estará en formato JSON, es importante analizarlo en un objeto JavaScript normal.
const recentReportContents = (() = { const output = fs.readFileSync( dirName + "/" + recentReport.replace(/:/g, "_") + ".json", "utf8", (err, results) = { return results;
Deja un comentario