O que são os mapas de origem?

Os mapas de origem são uma ferramenta crucial no desenvolvimento moderno da Web que facilitam significativamente a depuração. Esta página explora os conceitos básicos dos mapas de origem, como eles são gerados e como eles melhoram a experiência de depuração.

Necessidade de mapas de origem

Os primeiros aplicativos da Web eram criados com baixa complexidade. Os desenvolvedores implantaram arquivos HTML, CSS e JavaScript diretamente na Web.

Apps da Web mais modernos e complexos podem precisar de uma variedade de ferramentas no fluxo de trabalho de desenvolvimento. Exemplo:

Uma breve visão geral das várias ferramentas.
Algumas das ferramentas mais comuns de desenvolvimento de apps da Web.

Essas ferramentas exigem um processo de build para transcompilar o código em HTML, JavaScript e CSS padrão que os navegadores consigam entender. Também é uma prática comum otimizar o desempenho reduzindo e combinando esses arquivos com uma ferramenta como Terser (link em inglês).

Por exemplo, usando ferramentas de build, podemos transcompilar e compactar o seguinte arquivo TypeScript em uma única linha do JavaScript. Teste por conta própria nesta demonstração no GitHub (em inglês).

/* 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);
});

Uma versão compactada seria:

/* 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)}));

No entanto, compactar o código pode dificultar a depuração. Os mapas de origem podem remover esse problema: ao mapear seu código compilado de volta para o código original, eles podem ajudar a encontrar rapidamente a origem de um erro.

Gerar mapas de origem

Mapas de origem são arquivos com nomes que terminam com .map (por exemplo, example.min.js.map e styles.css.map). Eles podem ser gerados pela maioria das ferramentas de build, incluindo Vite, webpack, Rollup, Parcel e esbuild.

Algumas ferramentas incluem mapas de origem por padrão. Outros podem precisar de configuração adicional para produzi-los:

/* 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
  }
})

Entender o mapa de origem

Para ajudar na depuração, esses arquivos de mapa de origem contêm informações essenciais sobre como o código compilado é mapeado para o código original. Veja um exemplo de um mapa de origem:

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

Para entender cada um desses campos, leia a especificação do mapa de origem ou A anatomia de um mapa de origem.

A parte mais importante de um mapa de origem é o campo mappings. Ele usa uma string codificada em base 64 do VLQ para mapear linhas e localizações no arquivo compilado para o arquivo original correspondente. Para isso, use um visualizador de mapa de origem, como o source-map-visualization ou a visualização de mapa de origem.

Uma visualização de mapa de origem.
Visualização do código de exemplo anterior, gerada por um visualizer.

A coluna gerado à esquerda mostra o conteúdo compactado, e a coluna original mostra a fonte original.

O visualizador codifica cada linha na coluna original por cor com o código correspondente na coluna generated.

A seção mappings mostra os mapeamentos decodificados do código. Por exemplo, a entrada 65 -> 2:2 significa:

  • Código gerado: a palavra const começa na posição 65 no conteúdo compactado.
  • Código original: a palavra const começa na linha 2 e na coluna 2 do conteúdo original.
Entrada de mapeamento.
A visualização de mapeamento, com foco na entrada 65 -> 2:2.

Isso permite que os desenvolvedores identifiquem rapidamente a relação entre o código minimizado e o código original, tornando a depuração um processo mais suave.

As ferramentas para desenvolvedores do navegador aplicam esses mapas de origem para ajudar você a identificar seus problemas de depuração rapidamente no navegador.

Ferramentas para desenvolvedores aplicando um mapa de origem.
Exemplo de como as ferramentas para desenvolvedores do navegador aplicam mapas de origem e mostram os mapeamentos entre arquivos.

Extensões de mapa de origem

Os mapas de origem são compatíveis com campos de extensão personalizados que começam com um prefixo x_. Um exemplo é o campo de extensão x_google_ignoreList proposto pelo Chrome DevTools. Consulte x_google_ignoreList para saber mais sobre como essas extensões ajudam você a se concentrar no código.

Desvantagens do mapa de origem

Infelizmente, os mapeamentos de origem nem sempre são tão completos quanto necessário. No nosso primeiro exemplo, a variável greet foi otimizada durante o processo de build, mesmo que o valor dela estivesse diretamente incorporado à saída da string final.

O cumprimento da variável não está mapeado.
A variável greet no código original está ausente do mapeamento.

Nesse caso, quando você depura o código, as ferramentas para desenvolvedores podem não conseguir inferir e mostrar o valor real. Esse tipo de erro pode dificultar o monitoramento e a análise do código.

O cumprimento da variável é indefinido.
A ferramenta para desenvolvedores não encontrou um valor para greet.

Esse é um problema que precisa ser resolvido no design dos mapas de origem. Uma possível solução é incluir informações de escopo nos mapas de origem da mesma forma que outras linguagens de programação fazem com as informações de depuração.

No entanto, isso exige que todo o ecossistema trabalhe em conjunto para melhorar a especificação e a implementação do mapa de origem. Para saber mais sobre como melhorar a capacidade de depuração com mapas de origem, consulte a proposta de Mapas de origem v4 no GitHub.