Mapas de origen de JavaScript, ¿Podemos hacerlo mejor?

This ad is not shown to multipass and full ticket holders
JSNation US
JSNation US 2025
November 17 - 20, 2025
New York, US & Online
See JS stars in the US biggest planetarium
Learn More
In partnership with Focus Reactive
Upcoming event
JSNation US 2025
JSNation US 2025
November 17 - 20, 2025. New York, US & Online
Learn more
Bookmark
Rate this content

La revisión actual de la especificación de Mapas de origen de JavaScript tiene más de 12 años. A lo largo de este tiempo, todo el ecosistema ha evolucionado enormemente, pero por alguna razón, no hemos hecho nada para mejorar la experiencia de depuración y todavía estamos atascados en la versión 3 de la especificación. ¿Podemos hacerlo mejor?

This talk has been presented at JSNation 2023, check out the latest edition of this JavaScript Conference.

FAQ

En Sentry, los mapas de origen se utilizan para la depuración post hoc, donde se analiza el código que realmente se utilizó en el momento de un error para identificar y resolver problemas específicos del código minimizado o transpilado.

Un identificador de depuración es un UUID generado a partir del hash de un mapa de origen. Se inserta tanto en el archivo minimizado como en el propio mapa de origen para asegurar que ambos correspondan y facilitar la identificación del código exacto que causó un error.

Los servidores de símbolos son servidores donde se almacenan archivos de depuración, incluidos los mapas de origen, con sus ID de depuración correspondientes. Permiten acceso rápido a estos archivos durante la depuración, facilitando la resolución de errores.

Los desafíos incluyen la falta de identidad de archivos, la resolución de nombres y rutas complicadas, y las diferencias en cómo los navegadores manejan la colocación de errores debido a la codificación de caracteres. Además, la estandarización y conformidad con las especificaciones son áreas que necesitan mejora.

Sentry utiliza identificadores de depuración para vincular de manera única los archivos minimizados y los mapas de origen, asegurando que el archivo que causó el error sea el mismo que se está analizando para la depuración.

Un error críptico es un mensaje de error que no proporciona información clara sobre su causa debido a la minimización o transpilación del código. Los mapas de origen ayudan a revertir este código a su forma original, facilitando la comprensión y corrección del error.

Un mapa de origen es una herramienta que permite mapear el código fuente transpilado, empaquetado o minimizado de vuelta a su código original. Esto es útil para entender cómo se produjo el código fuente y para facilitar la depuración mostrando errores más comprensibles.

Kamil Ogórek
Kamil Ogórek
27 min
05 Jun, 2023

Comments

Sign in or register to post your comment.
Video Summary and Transcription
Los mapas de origen permiten comprender el código transpilado, empaquetado o minificado. La depuración con identificadores post hoc y de depuración ayuda a identificar archivos. Los problemas con los mapas de origen incluyen colisiones de hash y nombres de funciones faltantes. Se pueden utilizar diversas técnicas para determinar la función que causó un error. Los mapas de origen pueden almacenar información adicional y se pueden realizar mejoras en la resolución de rutas y posiciones de columnas. Los puntos de código y las posiciones de tokens pueden diferir entre navegadores. Detectar mapas de origen puede ser desafiante sin un esquema JSON estandarizado.

1. Introducción a los mapas de origen

Short description:

Los mapas de origen te permiten transpilar, empaquetar o minimizar el código fuente, o más bien, comprender cómo se produjo el código fuente transpilado, empaquetado o minimizado. Una vez que tenemos los mapas de origen, necesitamos combinarlos con el archivo minimizado. Esto se puede hacer a través de un comentario al final del archivo o un encabezado de solicitud. La depuración ad hoc te permite ver el error a medida que ocurre y utilizar el código exacto que desencadenó el error.

Hola a todos. Mi nombre es Kamil Ugurek y soy un ingeniero de software senior en Sentry, donde actualmente trabajo en el equipo de procesamiento, donde una de las cosas en las que estamos trabajando es procesar mapas de origen. También soy miembro del equipo principal de TRPC y, como probablemente puedas notar, realmente, realmente me encantan los mapas de origen, lo que me lleva al título opcional de esta charla, que es por qué los mapas de origen son tan difíciles de hacer correctamente.

No entraremos en muchos detalles sobre cómo funcionan los mapas de origen. Hay muchas otras fuentes que puedes utilizar para esto. Sin embargo, necesitamos entender algunas ideas muy básicas. Los mapas de origen te permiten transpilar, empaquetar o minimizar el código fuente, o más bien, comprender cómo se produjo el código fuente transpilado, empaquetado o minimizado. Lo que hace es mapear los tokens del código minimizado de vuelta al código original, lo cual te permite ver errores más utilizables, en lugar de algo como undefined X no es la función funcional, o algo por el estilo. Si quieres entender más a fondo cómo se codifica en realidad, hay una excelente publicación de blog de un amigo mío, Arpad, en su blog. Realmente te animo a que lo leas detenidamente.

Una vez que tenemos los mapas de origen, necesitamos combinarlos de alguna manera con el archivo original, o más bien, lo siento, el archivo minimizado. Una de las formas de hacer esto es a través del comentario al final del archivo con un pragma especial, que es source mapping URL, o el encabezado de solicitud, que adjuntas a la solicitud HTTP saliente. Ahora que tienes ambas cosas, en lugar de ver este mensaje de error muy críptico puedes ver algo mucho más utilizable, como fetch user data en lugar de ver una función X. Puedes ver esto directamente en tus DevTools, lo cual se llama depuración ad hoc, lo que significa que ves el error a medida que ocurre y puedes utilizar el código exacto, que se carga dentro del motor de JavaScript, y puedes estar seguro de que es el mismo código que desencadenó el error.

2. Depuración con Post Hoc y Identificadores de Depuración

Short description:

Existe otra forma de depuración llamada depuración post hoc. El principal problema es la falta de identidad, ya que no podemos determinar qué archivo se utilizó. El uso de una versión como identificador único ayuda, pero no es suficiente. Podemos utilizar identificadores de depuración, que son hashes únicos basados en los mapas de origen, para asegurarnos de que los archivos sean los mismos.

Sin embargo, existe otra forma de depuración, que es la depuración post hoc, que es lo que Sentry está haciendo en realidad, lo que significa que cuando ocurre un error, se nos envía y ahora necesitamos averiguar qué código se utilizó realmente cuando se produjo el error, que acaba de suceder después del hecho.

Esto me lleva a los problemas que existen en este momento. El primero y el más grande es la falta de identidad, lo que significa que no podemos saber qué archivo se utilizó realmente. Incluso si lo subes a nosotros, lo cual describiré muy brevemente cómo funciona. Produces algunos archivos, tienes archivos minimizados, tienes mapas correspondientes. Los pasas a través de una de las herramientas que proporcionamos, que es el binario de la CLI o los complementos para tus empaquetadores. Si quieres, puedes usar solo una llamada a la API y almacenarlos en Sentry. Necesitas usar la versión, que es un identificador único para tu compilación. Y necesitamos esto porque es la única forma en que realmente podemos tener algún tipo de identidad del archivo. Porque aparte del nombre de archivo, no hay nada más que lo haga realmente especial.

Con el tiempo, puedes tener 10 archivos MinJS empaquetados cargados para la misma versión, y no podemos saber cuál es cuál, básicamente. Es por eso que tenemos algo que también se llama un disco, que puedes pensar como directorios o el contenedor de archivos. Entonces podemos tener los mismos nombres de archivo para múltiples entornos, como producción o desarrollo o preparación. Sin embargo, aún no es suficiente, porque básicamente puedes tener el mismo nombre de archivo, algo como MinJS empaquetado, que es muy, muy común, pero producido en momentos completamente diferentes, como hoy y un mes de antelación, seis meses después, y así sucesivamente, y esos nombres pueden seguir siendo los mismos. Puedes usar nombres de hash, pero esto no siempre es posible porque a algunas personas les gusta encargarse de la memoria caché utilizando encabezados HTTP, y a veces es molesto lidiar con eso.

Entonces digamos que tenemos todos los archivos. Ahora ocurre el error. Aquí está el error. El primer marco apunta a HTTPS DRPC.IO. Assets MinJS empaquetado, que es esta línea, y realmente no nos importa el nombre del host. Podemos omitirlo para la parte de procesamiento, lo que nos deja con MinJS empaquetado. Sin embargo, la parte problemática es que se ha servido desde algún lugar. El MinJS empaquetado se encuentra dentro de Assets. Sin embargo, ¿qué sucede si la estructura de tu proyecto, cuando lo cargaste, era algo como esto, lo que significa que si solo incluiste el directorio dist para cargarlo, significa que tu archivo se encontrará en dist front-end MinJS empaquetado. Este no es el mismo camino y no coincidirán, lo que significa que no podemos decir que este archivo que acabas de servir, que en realidad causó el error, es el mismo archivo exacto que se cargó. Sería solo una suposición.

Entonces, ¿cuál es la solución a esto? ¿Cómo podemos asegurarnos de que esos archivos sean los mismos archivos, verdad? En realidad, podemos usar algo que se llama identificadores de depuración, que en el mundo nativo, es muy, muy común. Tienes algo que se llama archivos de depuración y en nuestro caso lo llamamos ID de depuración porque es muy fácil de recordar. Cómo funciona es de manera muy similar a la URL de asignación de origen, sin embargo, en lugar de usar rutas, hasheas todo el mapa de origen producido y utilizas este hash o más bien el identificador único basado en el hash, que es UUID en este caso, y lo insertas dentro del archivo minimizado y dentro del propio mapa de origen. Debes hashear el mapa de origen en lugar de solo el origen en sí porque hay una forma en que el código fuente original puede producir los mismos hashes para diferentes contenidos.

3. Problemas con los Mapas de Origen y la Depuración

Short description:

Si tu empaquetador elimina comentarios, inlinea funciones o colapsa llamadas de funciones, el archivo minificado resultante puede tener el mismo hash para diferentes códigos fuente originales, lo que hace que los mapas de origen sean inútiles. Para solucionar esto, hasheamos el contenido del mapa de origen y lo asociamos con un ID de depuración. Mantenemos una lista de archivos en el paquete y sus ID de depuración correspondientes. Una solución mejor sería tener una lista de marcos con sus ID de depuración, lo que permitiría una depuración más precisa. Se pueden utilizar servidores de símbolos para almacenar archivos de depuración con sus ID correspondientes, eliminando la necesidad de adivinar nombres de archivos o rutas. Sin embargo, surge un problema con los nombres y alcances en los mapas de origen, ya que los nombres de las funciones pueden no estar incluidos. Esto puede hacer que los mensajes de error y las trazas de pila no sean útiles.

Por ejemplo, si tu bundler decide eliminar comentarios, inlinear algunas funciones o simplemente colapsar esas llamadas de funciones, algo como esto, si agregas una sola línea de nuevos comentarios a tu código fuente y luego lo compilas y luego eliminas todos los comentarios y lo compilas nuevamente, puede terminar siendo el mismo archivo minificado, lo que significa que tenías el mismo hash para diferentes códigos fuente originales, lo que significa que los mapas de origen no pueden usar sus mapeos porque las líneas y columnas estarán completamente desfasadas.

Por eso decidimos hashear el contenido del mapa de origen en sí. Sin embargo, eso no es todo porque aún necesitamos saber de alguna manera que el archivo minificado que causó el error, en realidad tiene algún ID de depuración, como recordar esta cosa, ¿verdad? Tenemos una ruta aquí, no hay ID de depuración en ninguna parte aquí. Lo que necesitamos en su lugar es alguna forma de preguntarle a la API, o más bien al motor de JavaScript, cuál es el ID de depuración para esta URL, para este archivo que se está cargando ahora mismo en el motor?

Esta API que ves aquí es completamente inventada. No hay nada como esto, pero este es uno de los requisitos que necesitamos. En este momento, lo que hacemos es simplemente mantener una lista de todos los archivos que producimos dentro del paquete, dentro del espacio de nombres global. Entonces, como el ID de depuración de la ventana, y tenemos una lista de mapeos de URL a ID de depuración, que definitivamente no es genial, no es perfecto, pero funciona con lo que tenemos en este momento, lo que nos permite validar nuestras ideas. Pero la solución perfecta sería algo como esto, donde el error no es solo una cadena de pila, sino una lista de marcos, lo que nos permitiría ir marco por marco y preguntar por su ID de depuración correspondiente, y luego enviarlo junto con el evento mismo.

Esto nos brinda otra ventaja muy, muy buena, que son los llamados servidores de símbolos. Los servidores de símbolos también se utilizan en el mundo nativo. Básicamente, lo que hacen es permitirte tener un servidor completamente separado de primera parte donde puedes almacenar todos tus archivos de depuración con sus ID de depuración correspondientes. En nuestro caso, podrían ser solo mapas de origen, por ejemplo, en un bucket de S3, y simplemente haces que tu herramienta sepa que allí está la URL, por favor, cada vez que necesites algunos mapas de origen, o cualquier otro archivo de depuración, simplemente ve allí. Simplemente ve allí, pregúntale si tiene el ID de depuración correspondiente, tiene el archivo, te dará toda la información que necesitas. Básicamente, configuras una URL en la configuración y listo, nada más. No necesitas adivinar los nombres de los archivos. No tienes que adivinar las rutas ni nada por el estilo.

Algo mucho más visible para el usuario final es un problema con los nombres y alcances. Porque los nombres y los nombres de las funciones originales dentro de los mapas de origen no son obligatorios. Puedes tener un mapa de origen completamente sin ellos, puedes omitir un array de nombres originales. Lo que puede suceder es que puedes tener una función que arroja un error y ver el error así. Tienes una función indefinida, y el único marco que ves está en x, en y, en z. Es completamente inútil. Ves que todo sucede en la línea número uno y la columna 21000, lo que sea. No es genial. Toma este código, por ejemplo. Hay una función tal vez que llama a la función llamame, que luego arroja un error. Y luego llamamos a la función. En esta forma minificada, es algo como esto. Todo se colapsa en una sola línea y algunas funciones. Lo siento, algunos nombres de funciones con solo una o dos letras.

4. Detectando la Función que Causó el Error

Short description:

Para determinar qué función causó un error, podemos utilizar el escaneo hacia atrás mediante la tokenización del código minificado y buscar el nombre minificado de la función. Otro truco es el nombramiento del llamador, donde subimos un paso en la pila de llamadas y obtenemos la columna y la línea del marco. Sin embargo, el mejor enfoque es la reconstrucción del AST, que proporciona toda la información necesaria pero puede ser ineficiente en memoria y costoso computacionalmente para archivos grandes.

¿Cómo podemos saber realmente que la función que lanzó el error fue llamada? El problema aquí es que el motor de JavaScript te dirá lo que realmente sucedió es que el primer marco fue un nuevo error. Porque, técnicamente, esto es lo que produjo el error. Pero esto no es útil. De lo contrario, solo veríamos en la mayoría de los casos simplemente nuevo error, nuevo error, nuevo error. Lo que queremos saber es cuál es la función que realmente lo causó.

Entonces, en este caso, sería llamada. Sin embargo, ¿cómo podemos saber que es realmente esto? Tenemos algunos trucos bajo la manga. El primero se llama escaneo hacia atrás, donde tomas el código fuente minificado, lo tokenizas y vas un token a la vez hacia atrás. Entonces, lo que haces es tener error, ir a nuevo, volver a throw, y lo haces mientras veas el nombre minificado de la función. O más bien, veas el token function precedido del nombre minificado. En nuestro caso aquí, era XY, ¿verdad? Una vez que tenemos esta función y los tokens XY, podemos preguntar cuál es la posición del token XY, en este caso, y luego preguntar al mapa de origen, oye, bien, ahora sé la nueva ubicación. Esto no es nuevo error. Sé la ubicación de XY. ¿Tienes un nombre correspondiente para esto? Y si es así, tenemos suerte, ahora podemos decir que fue realmente llamada y no nuevo error lo que causó el error en sí. Sin embargo, no siempre es posible. Si tienes una función anónima o una función flecha de ES6, simplemente no funcionará.

El segundo truco que podemos usar se llama nombramiento del llamador, que hace la suposición de que la función que nos llamó no modificó el nombre original. Por ejemplo, no lo reasignó en ningún lugar o no lo modificó de alguna manera extraña o no lo llamó dinámicamente, aquí está la pila de llamadas, la original, que es la función maybe, que llama a la función llamada, que produce el error, y la minificada, llamada VM llamando a XY, llamando a nuevo error. Lo que podemos hacer en lugar de preguntar cuál es la ubicación de nuevo error, podemos subir un paso hacia arriba, que es XY en este caso, y preguntarle a XY cuál es la columna y la línea correspondiente de este marco. Lo que requiere es que necesitas conocer toda la pila de antemano. Por ejemplo, si solo obtienes el primer marco, volvamos al ejemplo aquí, si solo conoces X asset bundle min JS, el primero, estás fuera de suerte, no puedes hacer esto porque lo que necesitas hacer es consultar el marco debajo de este, que es como una columna 2430, ¿verdad? Esto generalmente da algunas ideas, como podemos recurrir a esto, pero tampoco es genial. No siempre funciona, sigue siendo solo una suposición.

La mejor idea que se nos ocurrió y que usamos con éxito en este momento, y esto es lo que muchos DevTools están haciendo en este momento, es la reconstrucción del AST. Lo que hace es tomar el código fuente minificado y hacer el mismo trabajo que los empaquetadores y transpiladores ya hicieron, pero, nuevamente, es muy ineficiente en memoria, es pesado, básicamente requiere mucho trabajo. Sin embargo, la ventaja de esto es que obtenemos toda la información que podamos necesitar. Por ejemplo, podemos decir que aquí se lanzó un nuevo error dentro del método estático en la clase método bar de foo, ¿verdad? O en este caso, podemos decir exactamente que era solo un literal de objeto, asignado a la variable A mayúscula, y era un método, en realidad la propiedad, lo siento, el otro método, u otro getter personalizado llamado foo. Y aquí podemos decir que era el constructor de la clase B. Entonces podemos saber exactamente dónde estamos en el momento en que ocurrió el error, porque podríamos reconstruir todo. Sin embargo, el problema es que nuevamente, necesitas procesar todo el AST, lo que puede ser muy, muy costoso para archivos muy grandes. Y los empaquetadores y transpiladores ya tenían estos data.

5. Almacenando Información en Mapas de Origen

Short description:

Los mapas de origen pueden almacenar información en su interior, como el formato de pasta utilizado por los ingenieros de Bloomberg. Se pueden agregar ámbitos al archivo JSON del mapa de origen para codificar desplazamientos y nombres. La naturaleza anidada de los ámbitos permite una fácil reconstrucción y búsqueda binaria. También hay problemas más pequeños que podrían abordarse en la próxima revisión de la especificación, como pruebas de conformidad.

Básicamente, pueden almacenar esto de alguna manera dentro de un mapa de origen, que es otra idea que ya fue iniciada por los ingenieros de Bloomberg con su llamado formato de pasta, del cual puedes leer más aquí. Y también hay un RFC, del cual puedes leer en el propio repositorio de los nuevos RFC de mapas de origen.

En lugar de hacer este trabajo una y otra vez, lo que sucedería es que agregaríamos un nuevo atributo llamado ámbitos, o nombres de ámbito, algo así, dentro del archivo JSON del mapa de origen, y codificaría todos los desplazamientos, todos los desplazamientos en bytes y el nombre del ámbito en sí. Y debido a que los ámbitos están anidados, por ejemplo, tienes este ámbito externo, que puede contener un ámbito interno, que puede contener un ámbito interno y así sucesivamente. Es muy fácil reconstruir esto porque se superponen, ¿verdad? Como 15 está dentro de los límites de 10 y 30, 16 a 20 está dentro de los límites de 15 y 25, y así sucesivamente. Una vez que tienes esto, como una pirámide, puedes hacer una búsqueda binaria y encontrar la mejor coincidencia para tu caso.

Esos son dos problemas importantes, sin embargo, hay algunos más pequeños que aún no son críticos, pero sería bueno solucionar en la próxima revisión de la especificación. El primero son las pruebas de conformidad. Si nunca has oído hablar de ellas, son un conjunto de pruebas que confirman que tu herramienta, tu motor, tu implementación sigue la especificación al pie de la letra. Si pasa todas las pruebas de las pruebas de conformidad, significa que se ha implementado correctamente. Esto es lo que prueba 262, en realidad es lo que los navegadores y otros motores de JavaScript están ejecutando para asegurarse de que la especificación de ECMAScript se implemente correctamente.

6. Resolución de Rutas y Posiciones de Columna

Short description:

La resolución de rutas puede ser frustrante ya que es difícil determinar la ruta. Las fuentes originales suelen estar codificadas dentro del propio mapa de origen, pero esto es opcional. Algunas herramientas solo proporcionan la matriz de archivos y una ruta de origen, que puede tener varios formatos. Adivinar la ubicación real del archivo puede ser un desafío. Además, las posiciones de columna pueden diferir entre navegadores debido a la codificación y la falta de especificación.

El segundo, que es mucho más molesto, es la resolución de rutas, porque nunca puedes asegurar cuál es la ruta. Una de las características que tenemos en Sentry se llama líneas de contexto, lo que significa que para la ubicación donde ocurrió el error, queremos mostrarte algo así como un pequeño fragmento del editor. Así que si tus líneas anteriores, tus pocas líneas siguientes. Pero para hacer esto, necesitamos las fuentes originales de alguna manera.

Las fuentes originales suelen estar codificadas dentro de los contenidos de las fuentes dentro del propio mapa de origen, es solo un área de códigos fuente, básicamente. Sin embargo, también es opcional. Así que a veces tienes mala suerte y no tienes acceso a esto, lo que nos dificulta. Así que cuando uses Sentry CLI, probablemente lo incluiremos en línea. Lo arreglaremos por ti. Sin embargo, todavía hay algunas herramientas que no producen esto. Solo producen la matriz de archivos y una ruta de origen opcional mencionada, lo que significa que esas son las rutas que la herramienta utilizó para producir este paquete en caso de que quieras volver atrás y, ya sabes, ver dónde se encontraban esos archivos y la ruta de origen es como un prefijo común para todos esos archivos. Sin embargo, el problema es que pueden tener cualquier formato. Pueden ser absolutas, pueden ser relativas. Pueden tener un host personalizado, como por ejemplo, webpack está haciendo ahora mismo. Pueden tener espacios de nombres personalizados, lo que quieras. Es el salvaje Oeste. Así que puedes terminar con algo como esto. Tienes un error donde el marco apunta a example.com este bundle.js. Su correspondiente mapa de origen apunta a dos directorios, up slash assets slash bundle.js map porque sí, puedes tener viajes de ruta aquí. Y tus archivos apuntan a algo como webpack hosts slash, y luego el espacio de nombres que webpack produjo, que en este caso sería como alguna biblioteca de espacio de nombres y hay problemas con la API de origen. Y de alguna manera necesitas adivinar u entender dónde estaba realmente el archivo ubicado en caso de que alguien te haya enviado el archivo.

Un dato curioso, en este momento, nuestra función de unión de URL simple tiene más de 50 líneas de código y sigue creciendo. Es muy divertido. La posición de columna es algo que si lo piensas, no debería suceder, ya estamos en el año 2023, pero por alguna razón todavía sucede porque las codificaciones son complicadas y, ya sabes, no hay una especificación. Considerando este código muy trivial, es solo una función que lanza un error, sin embargo, puedes ver que hay un comentario que tiene algunos emojis en su interior. Y ¿qué sucede si ejecutas este código en todos los navegadores modernos en este momento, si lo llamas en Firefox, tendrás un informe de que el error fue lanzado en la columna 13, que es el inicio de la función en Chrome es la columna 16 y en Safari es la columna 19. ¿Qué sucede? Quiero decir, ¿qué sucede es que Firefox está contando. Unidades de código. Lo siento. O puntos de código, puntos de código.

7. Puntos de Código y Posiciones de Tokens

Short description:

Los puntos de código difieren en el recuento entre Chromium, que cuenta unidades de código, y Safari, que trata el paréntesis de apertura del token como la llamada a la función. Algunas herramientas producen dos tokens para una función, mientras que otras producen uno sin espacios en blanco. Para asegurar una ubicación de minificación precisa y un comportamiento de depuración adecuado, utiliza valores de posición iguales o mayores y considera la posibilidad de errores de uno en uno.

Sí. Puntos de código. Um, que en este caso es gratis porque es UTF 32. Entonces es como un solo punto de código para cada emoji de fuego, Chromium está contando unidades de código donde, um, es UTF 16, lo que significa que cada emoji de fuego está compuesto por dos unidades de código. Um, y Safari por alguna razón decidió que, uh, es mejor hacer, uh, tratar el paréntesis de apertura del token como el token que realmente llama a la función, no la función en sí, ¿verdad? Divertido. Um, aún es mejor que, uh, que este, que tiene un error de uno en uno, uh, que, por supuesto, también debemos tener en el mapa de origen. Si tienes esta función, que es una función que algunas herramientas producirán dos tokens donde el primer token es función espacio en blanco y el segundo es qué, que es el nombre de la función. Sin embargo, algunas herramientas producirán esto, que es funcional sin espacio en blanco. Y el segundo es espacio qué? A quién le importa ahora mismo, si quieres, uh, asegurarte de que tu ubicación de minificación apunte a un lugar muy específico en la ubicación original, simplemente puedes usar igual, necesitas usar igual o más por si acaso hay este error de uno en uno, error de uno en uno aquí, uh, producido. Y también se aplica al depurador porque si haces clic en debug, um, debug, la marca debug dentro de las herramientas de desarrollo en el token o el nombre de la función, necesita conocer la posición exacta del token.

8. Detectando Mapas de Origen

Short description:

Para detectar si un archivo es un mapa de origen, actualmente nos basamos en la extensión del archivo y atributos específicos como 'versión' y 'mapeo'. Sin embargo, dado que los mapas de origen son solo archivos JSON, no hay bytes mágicos ni indicadores. Sería beneficioso crear un esquema JSON estandarizado para los mapas de origen para garantizar su identificación.

Y el último es, ¿estás seguro de que es un mapa de origen? Porque bueno, el mapa de origen es solo un archivo Jason, ¿verdad? Entonces, ¿cómo detectamos que realmente es un mapa de origen? Bueno, actualmente lo hacemos de dos formas. La primera es utilizando la extensión del archivo. Sin embargo, ya sabes, puedes llamar a cualquier archivo, uh, con la extensión .map. Entonces, lo que la mayoría de las herramientas hacen es buscar atributos de versión con la cadena literal `free`. Y si tienes este atributo, y tal vez también buscan atributos de mapeo, si tienes todas esas cosas, significa que es muy probable que sea un mapa de origen, pero. Solo es muy probable porque es solo un archivo Jason y porque es solo Jason, no podemos tener ningún byte mágico ni nada por el estilo predefinido o adjunto al archivo. Um, así que estamos sin suerte. Sería genial si pudiéramos hacer algo. Es crear un esquema Jason que luego se estandarizaría y todos podríamos usarlo en todas partes. Y esto aseguraría que el archivo que estamos mirando sea el mapa de origen. Entonces, ¿cuál es el futuro? Desafortunadamente, para este formato que se ha utilizado, ya sabes, durante casi todos, bueno, no casi en todos los navegadores y motores. Se ha hablado muy, muy, uh, bueno, no hubo mucha discusión, diría que esta es una buena manera de decirlo. Um, porque la revisión inicial, que fue la revisión uno, fue alrededor de 2009. Aunque no puedo confirmarlo, um, porque el documento original está bloqueado ahora mismo. Um, sin embargo, la revisión dos y la revisión tres fueron en algún momento entre 2010 y 2013, lo que significa que, uh, han pasado más de 10 años ahora desde que se realizaron cambios significativos. Y simplemente hemos lidiado con el hecho de que funciona como funciona. Un dato curioso durante los últimos 10 años, um, o diría que ahora son 12. Uh, esta fue toda la especificación. Si alguna vez has usado mapas de origen o has tenido que hacer algo con ellos, esto es lo que probablemente encontraste. Y esta fue realmente la especificación oficial del mapa de origen, uh, mapa de origen, uh, especificación, este documento de Google muy agradable. Afortunadamente, un amigo mío y yo lo hemos traducido al formato oficial o a otra forma estandarizada de escribir especificaciones, que puedes encontrar ahora mismo en esta URL y podemos evolucionar esto de alguna manera. Um, entonces, el siguiente paso aquí es que, a principios de este año, uh, algunos colegas míos y yo de Century participamos en este grupo de divulgación 39, que se centra en tooling y mapas de origen. Y lo que queremos hacer ahora es intentar impulsar este trabajo y básicamente hacer nuestras vidas más fáciles. Afortunadamente, hay muchas más personas interesadas en esto de las que pensábamos, cada persona está haciendo algún RFC, alguna investigación, algunos están proporcionando comentarios. Y tengo muchas esperanzas de que podamos hacer este trabajo más pronto que tarde. Si quieres unirte y contribuir también, hay un canal de métricas para esto. Puedes unirte a las reuniones directamente. Nos reunimos cada, um, cada mes en este momento, que es cada último miércoles del mes, creo. Y si tienes algún comentario directamente, puedes ir al repositorio de GitHub, allí hay RFC abiertos, hay discusiones abiertas. Um, ya sabes, y todos los comentarios son bienvenidos. Definitivamente deberías unirte. Gracias por tu tiempo. Y si tienes alguna pregunta, contáctame en Twitter. Gracias. Adiós.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Depuración Web Moderna
JSNation 2023JSNation 2023
29 min
Depuración Web Moderna
Top Content
This Talk discusses modern web debugging and the latest updates in Chrome DevTools. It highlights new features that help pinpoint issues quicker, improved file visibility and source mapping, and ignoring and configuring files. The Breakpoints panel in DevTools has been redesigned for easier access and management. The Talk also covers the challenges of debugging with source maps and the efforts to standardize the source map format. Lastly, it provides tips for improving productivity with DevTools and emphasizes the importance of reporting bugs and using source maps for debugging production code.
El Futuro de las Herramientas de Rendimiento
JSNation 2022JSNation 2022
21 min
El Futuro de las Herramientas de Rendimiento
Top Content
Today's Talk discusses the future of performance tooling, focusing on user-centric, actionable, and contextual approaches. The introduction highlights Adi Osmani's expertise in performance tools and his passion for DevTools features. The Talk explores the integration of user flows into DevTools and Lighthouse, enabling performance measurement and optimization. It also showcases the import/export feature for user flows and the collaboration potential with Lighthouse. The Talk further delves into the use of flows with other tools like web page test and Cypress, offering cross-browser testing capabilities. The actionable aspect emphasizes the importance of metrics like Interaction to Next Paint and Total Blocking Time, as well as the improvements in Lighthouse and performance debugging tools. Lastly, the Talk emphasizes the iterative nature of performance improvement and the user-centric, actionable, and contextual future of performance tooling.
Depuración de JS
React Summit 2023React Summit 2023
24 min
Depuración de JS
Top Content
Debugging JavaScript is a crucial skill that is often overlooked in the industry. It is important to understand the problem, reproduce the issue, and identify the root cause. Having a variety of debugging tools and techniques, such as console methods and graphical debuggers, is beneficial. Replay is a time-traveling debugger for JavaScript that allows users to record and inspect bugs. It works with Redux, plain React, and even minified code with the help of source maps.
De la Fricción al Flujo: Depuración con Chrome DevTools
JSNation 2024JSNation 2024
32 min
De la Fricción al Flujo: Depuración con Chrome DevTools
The Talk discusses the importance of removing frictions in the debugging process and being aware of the tools available in Chrome DevTools. It highlights the use of the 'Emulate a Focus Page' feature for debugging disappearing elements and the improvement of debugging tools and workflow. The Talk also mentions enhancing error understanding, improving debugging efficiency and performance, and the continuous improvement of DevTools. It emphasizes the importance of staying updated with new features and providing feedback to request new features.
Rome, ¡una cadena de herramientas moderna!
JSNation 2023JSNation 2023
31 min
Rome, ¡una cadena de herramientas moderna!
Top Content
Rome is a toolchain built in Rust that aims to replace multiple tools and provide high-quality diagnostics for code maintenance. It simplifies tool interactions by performing all operations once, generating a shared structure for all tools. Rome offers a customizable format experience with a stable formatter and a linter with over 150 rules. It integrates with VCS and VLSP, supports error-resilient parsing, and has exciting plans for the future, including the ability to create JavaScript plugins. Rome aims to be a top-notch toolchain and welcomes community input to improve its work.
Depuración con Chrome DevTools
JSNation Live 2021JSNation Live 2021
11 min
Depuración con Chrome DevTools
Top Content
Here are some tips for better utilizing DevTools, including using the run command, customizing keyboard shortcuts, and emulating the focus effect. Learn how to inspect memory, use the network panel for more control over network requests, and take advantage of console utilities. Save frequently used code as snippets and use local overrides for easy editing. Optimize images by using a more optimized format like AVIF and track changes in the network panel to see the reduced data size.

Workshops on related topic

Masterclass de Depuración de Rendimiento de React
React Summit 2023React Summit 2023
170 min
Masterclass de Depuración de Rendimiento de React
Top Content
Featured Workshop
Ivan Akulov
Ivan Akulov
Los primeros intentos de Ivan en la depuración de rendimiento fueron caóticos. Vería una interacción lenta, intentaría una optimización aleatoria, vería que no ayudaba, y seguiría intentando otras optimizaciones hasta que encontraba la correcta (o se rendía).
En aquel entonces, Ivan no sabía cómo usar bien las herramientas de rendimiento. Haría una grabación en Chrome DevTools o React Profiler, la examinaría, intentaría hacer clic en cosas aleatorias, y luego la cerraría frustrado unos minutos después. Ahora, Ivan sabe exactamente dónde y qué buscar. Y en esta masterclass, Ivan te enseñará eso también.
Así es como va a funcionar. Tomaremos una aplicación lenta → la depuraremos (usando herramientas como Chrome DevTools, React Profiler, y why-did-you-render) → identificaremos el cuello de botella → y luego repetiremos, varias veces más. No hablaremos de las soluciones (en el 90% de los casos, es simplemente el viejo y regular useMemo() o memo()). Pero hablaremos de todo lo que viene antes - y aprenderemos a analizar cualquier problema de rendimiento de React, paso a paso.
(Nota: Esta masterclass es más adecuada para ingenieros que ya están familiarizados con cómo funcionan useMemo() y memo() - pero quieren mejorar en el uso de las herramientas de rendimiento alrededor de React. Además, estaremos cubriendo el rendimiento de la interacción, no la velocidad de carga, por lo que no escucharás una palabra sobre Lighthouse 🤐)
Tracing: Frontend Issues With Backend Solutions
React Summit US 2024React Summit US 2024
112 min
Tracing: Frontend Issues With Backend Solutions
Top Content
Featured WorkshopFree
Lazar Nikolov
Sarah Guthals
2 authors
Los problemas de frontend que afectan a tus usuarios a menudo son provocados por problemas de backend. En esta masterclass, aprenderás cómo identificar problemas que causan páginas web lentas y malos Core Web Vitals usando tracing.
Luego, pruébalo tú mismo configurando Sentry en un proyecto Next.js ya preparado para descubrir problemas de rendimiento, incluyendo consultas lentas a la base de datos en una sesión interactiva de programación en pareja.
Saldrás de la masterclass siendo capaz de:- Encontrar problemas de backend que podrían estar ralentizando tus aplicaciones de frontend- Configurar tracing con Sentry en un proyecto Next.js- Depurar y solucionar problemas de rendimiento deficiente usando tracing
Este será un evento en vivo de 2 horas donde tendrás la oportunidad de codificar junto con nosotros y hacernos preguntas.
Depuración del Rendimiento de React
React Advanced 2023React Advanced 2023
148 min
Depuración del Rendimiento de React
Workshop
Ivan Akulov
Ivan Akulov
Los primeros intentos de Ivan en la depuración de rendimiento fueron caóticos. Veía una interacción lenta, probaba una optimización aleatoria, veía que no ayudaba, y seguía probando otras optimizaciones hasta que encontraba la correcta (o se rendía).
En aquel entonces, Ivan no sabía cómo usar bien las herramientas de rendimiento. Hacía una grabación en Chrome DevTools o React Profiler, la examinaba, intentaba hacer clic en cosas al azar, y luego la cerraba frustrado unos minutos después. Ahora, Ivan sabe exactamente dónde y qué buscar. Y en esta masterclass, Ivan te enseñará eso también.
Así es como va a funcionar. Tomaremos una aplicación lenta → la depuraremos (usando herramientas como Chrome DevTools, React Profiler, y why-did-you-render) → identificaremos el cuello de botella → y luego repetiremos, varias veces más. No hablaremos de las soluciones (en el 90% de los casos, es simplemente el viejo y regular useMemo() o memo()). Pero hablaremos de todo lo que viene antes - y aprenderemos cómo analizar cualquier problema de rendimiento de React, paso a paso.
(Nota: Esta masterclass es más adecuada para ingenieros que ya están familiarizados con cómo funcionan useMemo() y memo() - pero quieren mejorar en el uso de las herramientas de rendimiento alrededor de React. Además, cubriremos el rendimiento de interacción, no la velocidad de carga, por lo que no escucharás una palabra sobre Lighthouse 🤐)
El Masterclass de Clinic.js
JSNation 2022JSNation 2022
71 min
El Masterclass de Clinic.js
Workshop
Rafael Gonzaga
Rafael Gonzaga
Aprende las formas de la suite de herramientas clinic, que te ayudan a detectar problemas de rendimiento en tus aplicaciones Node.js. Este masterclass te guiará a través de varios ejemplos y te proporcionará los conocimientos necesarios para hacer pruebas de rendimiento y solucionar problemas de E/S y del bucle de eventos.
Instrumentar, Monitorizar, Arreglar: Una Sesión Práctica de Depuración
React Summit 2025React Summit 2025
88 min
Instrumentar, Monitorizar, Arreglar: Una Sesión Práctica de Depuración
WorkshopFree
Lazar Nikolov
Lazar Nikolov
Acabas de lanzar una nueva característica. Las pruebas pasaron. CI está en verde. Todo está desplegado. La vida es buena... hasta que las alertas comienzan a llegar. Los usuarios informan de "cosas raras que suceden", fallos en la interfaz de usuario, informes vagos de "parece lento" y ese temido mensaje de "no se puede iniciar sesión". Bueno, esto parece ser un mal día. Pero... tal vez no.Mira esta sesión práctica para aprender cómo construirlo, romperlo, depurarlo y pasar de "no tengo idea de qué está mal" a solucionar problemas, todo de una vez. Dado que somos desarrolladores serios (obviamente), usaremos Next.js y:Configurar Sentry desde cero, incluyendo Errores, Reproducción de Sesiones y TrazadoAprender formas de usar Replays para entender la experiencia real del usuario, y cómo usar Trazado para depurar problemas de la aplicaciónAprovechar Sentry AI y el contexto de tu aplicación para entender qué está realmente roto, y usar Autofix para generar una solución, desde la causa raíz hasta el PR.Utiliza esta guía de la masterclass para seguir: Guía de Inicio Rápido.
Soluciona el 100% de tus errores: Cómo encontrar problemas más rápido con la Reproducción de Sesiones
JSNation 2023JSNation 2023
44 min
Soluciona el 100% de tus errores: Cómo encontrar problemas más rápido con la Reproducción de Sesiones
WorkshopFree
Ryan Albrecht
Ryan Albrecht
¿Conoces ese molesto error? ¿El que no aparece localmente? Y no importa cuántas veces intentes recrear el entorno, no puedes reproducirlo. Has revisado las migas de pan, leído la traza de pila y ahora estás jugando al detective para unir los tickets de soporte y asegurarte de que sea real.
Únete al desarrollador de Sentry, Ryan Albrecht, en esta charla para aprender cómo los desarrolladores pueden utilizar la Reproducción de Sesiones, una herramienta que proporciona reproducciones de video de las interacciones de los usuarios, para identificar, reproducir y resolver errores y problemas de rendimiento más rápido (sin golpear tu cabeza contra el teclado).