Os mapas de origem são uma ferramenta crucial no desenvolvimento da Web moderno que facilitam a depuração muito mais fácil. Esta página explora os fundamentos dos mapas de origem, como eles são gerados e como eles melhoram a experiência de depuração.
A necessidade de mapas de origem
Os primeiros aplicativos da Web eram desenvolvidos com baixa complexidade. Os desenvolvedores implantaram HTML, CSS, e JavaScript diretamente para a Web.
Aplicativos da Web mais modernos e complexos podem precisar de diversas ferramentas em sua desenvolvimento de software. Exemplo:
- Linguagens de modelo e pré-processadores de HTML: Pug, Nunjucks Marcação.
- Pré-processadores de CSS: SCSS, MENOS, PostCSS.
- Frameworks JavaScript: Angular, React, Vue, Svelte.
- Metaframeworks JavaScript: Next.js, Nuxt, Astro.
- Linguagens de programação de alto nível: TypeScript (em inglês). Dart, CoffeeScript.
Essas ferramentas exigem um processo de build para transcompilar o código em HTML padrão, JavaScript e CSS que os navegadores possam entender. Também é uma prática comum para otimizar o desempenho, minimizando e combinando esses arquivos, usando uma ferramenta como Terser (em inglês).
Por exemplo, usando ferramentas de build, podemos transcompilar e compactar o seguinte TypeScript em uma única linha de JavaScript. Você pode testar por conta própria esta 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, a compactação do código pode dificultar a depuração. Mapas de origem pode remover esse problema: mapeando seu código compilado de volta para o código original, eles podem ajudar você a encontrar rapidamente a origem de um erro.
Gerar mapas de origem
Os 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
ferramentas, incluindo Vite, webpack,
Rollup, Parcel e
esbuild.
Algumas ferramentas incluem mapas de origem por padrão. Outros podem precisar de recursos configuração 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 mapeia para o código original. Aqui está um exemplo 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 o 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 de base 64 VLQ
para mapear linhas e locais no arquivo compilado para o arquivo original
. É possível visualizar esse mapeamento usando um visualizador de mapa de origem como
source-map-visualization ou
Visualização do mapa de origem.
A coluna gerado à esquerda mostra o conteúdo compactado, e a a coluna original mostra a fonte original.
O visualizador codificada por cores cada linha na coluna original com sua código correspondente na coluna generated.
A seção mappings mostra os mapeamentos decodificados do código. Por exemplo, o
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.
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 na depuração de problemas rapidamente no navegador.
Extensões do 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
do DevTools. Ver 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 fonte nem sempre são tão completos quanto o necessário.
No primeiro exemplo, a variável greet
foi otimizada durante o build.
mesmo que seu valor seja incorporado diretamente na saída da string final.
Nesse caso, quando você depura o código, as ferramentas para desenvolvedores podem não conseguir inferir e exibir o valor real. Esse tipo de erro pode fazer seu código o monitoramento e a análise.
Esse é um problema que precisa ser resolvido no design dos mapas de origem. Um solução possível é incluir informações de escopo nos mapas de origem no 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 especificação e implementação do mapa de origem. Para acompanhar a melhorar a capacidade de depuração com mapas de origem, consulte a proposta Maps de origem v4 no GitHub.