¿Qué son los mapas de origen?

Los mapas de fuentes son una herramienta fundamental para el desarrollo web moderno que facilita considerablemente la depuración. En esta página, se exploran los conceptos básicos de los mapas de origen, cómo se generan y cómo mejoran la experiencia de depuración.

La necesidad de los mapas de origen

Las primeras aplicaciones web se desarrollaron con baja complejidad. Los desarrolladores implementaron archivos HTML, CSS y JavaScript directamente en la Web.

Las apps web más modernas y complejas pueden necesitar una variedad de herramientas en su flujo de trabajo de desarrollo. Por ejemplo:

Una breve descripción general de varias herramientas.
Algunas de las herramientas comunes para el desarrollo de aplicaciones web.

Estas herramientas requieren un proceso de compilación para transpilar tu código a HTML, JavaScript y CSS estándar que los navegadores puedan comprender. También es una práctica común optimizar el rendimiento mediante la reducción y combinación de estos archivos con una herramienta como Terser.

Por ejemplo, con las herramientas de compilación, podemos transpilar y comprimir el siguiente archivo TypeScript en una sola línea de JavaScript. Puedes probarlo en esta demostración en GitHub.

/* A TypeScript demo: example.ts */

document.querySelector('button')?.addEventListener('click', () => {
  const num: number = Math.floor(Math.random() * 101);
  const greet: string = 'Hello';
  (document.querySelector('p') as HTMLParagraphElement).innerText = `${greet}, you are no. ${num}!`;
  console.log(num);
});

Una versión comprimida sería la siguiente:

/* A compressed JavaScript version of the TypeScript demo: example.min.js  */

document.querySelector("button")?.addEventListener("click",(()=>{const e=Math.floor(101*Math.random());document.querySelector("p").innerText=`Hello, you are no. ${e}!`,console.log(e)}));

Sin embargo, comprimirlo puede dificultar la depuración. Los mapas de fuentes pueden quitar este problema: si vuelven a asignar el código compilado al código original, pueden ayudarte a encontrar rápidamente la fuente de un error.

Genera mapas de orígenes

Los mapas de origen son archivos cuyos nombres terminan con .map (por ejemplo, example.min.js.map y styles.css.map). Se pueden generar con la mayoría de las herramientas de compilación, como Vite, webpack, Rollup, Parcel y esbuild.

Algunas herramientas incluyen mapas de orígenes de forma predeterminada. Otros pueden necesitar una configuración adicional para producirlos:

/* Example configuration: vite.config.js */
/* https://vitejs.dev/config/ */

export default defineConfig({
  build: {
    sourcemap: true, // enable production source maps
  },
  css: {
    devSourcemap: true // enable CSS source maps during development
  }
})

Comprende el mapa de fuentes

Para ayudar con la depuración, estos archivos de mapa de origen contienen información esencial sobre cómo el código compilado se asigna al código original. Este es un ejemplo de un mapa de fuentes:

{
  "mappings": "AAAAA,SAASC,cAAc,WAAWC, ...",
  "sources": ["src/script.ts"],
  "sourcesContent": ["document.querySelector('button')..."],
  "names": ["document","querySelector", ...],
  "version": 3,
  "file": "example.min.js.map"
}

Para comprender cada uno de estos campos, puedes leer la especificación del mapa de fuentes o La anatomía de un mapa de fuentes.

La parte más importante de un mapa de fuentes es el campo mappings. Usa una cadena codificada en base 64 VLQ para asignar líneas y ubicaciones del archivo compilado al archivo original correspondiente. Puedes ver esta asignación con un visualizador de mapa de fuentes, como source-map-visualization o la visualización del mapa de fuentes.

Visualización de un mapa de origen.
Una visualización del ejemplo de código anterior, generado por un visualizador.

En la columna generado de la izquierda, se muestra el contenido comprimido, mientras que en la columna original, se muestra la fuente original.

El visualizador codifica por color cada línea en la columna original con su código correspondiente en la columna generated.

En la sección mappings, se muestran las asignaciones decodificadas del código. Por ejemplo, la entrada 65 -> 2:2 significa lo siguiente:

  • Código generado: La palabra const comienza en la posición 65 en el contenido comprimido.
  • Código original: La palabra const comienza en la línea 2 y la columna 2 del contenido original.
Asignando entrada.
La visualización del mapeo, que se enfoca en la entrada 65 -> 2:2

Esto permite a los desarrolladores identificar rápidamente la relación entre el código reducido y el código original, lo que simplifica el proceso de la depuración.

Las herramientas para desarrolladores del navegador aplican estos mapas de origen para ayudarte a identificar rápidamente los problemas de depuración en el navegador.

Herramientas para desarrolladores que aplican un mapa de fuentes.
Ejemplo de cómo las herramientas para desarrolladores del navegador aplican mapas de origen y muestran las asignaciones entre archivos.

Extensiones de mapas de origen

Los mapas de orígenes admiten campos de extensiones personalizadas que comienzan con un prefijo x_. Un ejemplo es el campo de extensión x_google_ignoreList que propone Chrome DevTools. Consulta x_google_ignoreList para obtener más información sobre cómo estas extensiones te ayudan a enfocarte en el código.

Desventajas del mapa de fuentes

Desafortunadamente, las asignaciones de fuentes no siempre son tan completas como necesitas. En nuestro primer ejemplo, se optimizó la variable greet durante el proceso de compilación, aunque su valor está incorporado directamente en el resultado final de la cadena.

No se asignó la variable saludo.
Falta la variable greet en el código original en la asignación.

En este caso, cuando depuras el código, es posible que las herramientas para desarrolladores no puedan inferir ni mostrar el valor real. Este tipo de error puede dificultar la supervisión y el análisis de tu código.

La variable greet no está definida.
La herramienta para desarrolladores no puede encontrar un valor para greet.

Este es un problema que debe resolverse dentro del diseño de los mapas de origen. Una solución posible es incluir información de alcance en los mapas de origen de la misma manera que otros lenguajes de programación lo hacen con su información de depuración.

Sin embargo, esto requiere que todo el ecosistema trabaje en conjunto para mejorar la especificación y la implementación del mapa de fuentes. Para seguir el proceso en curso sobre cómo mejorar la depuración con mapas de origen, consulta la propuesta de Source Maps v4 en GitHub.