Aula 1 de 1

Aula 1 — Source maps: do CSS ao SCSS

Em 5 minutos você vai conseguir explicar como o DevTools do Chrome mostra _botao.scss:10 quando o navegador só recebeu style.css. Tudo aqui usa arquivos reais: abra em outra aba o laboratório da aula, que traz três arquivos SCSS compilados pelo Sass.

Onde o mapa entra

O Sass gera dois arquivos: o style.css e o style.css.map. Na última linha do CSS ele escreve o comentário /*# sourceMappingURL=style.css.map */. Para desenhar a página, o navegador trata essa linha como um comentário comum. Quem usa essa linha é o DevTools.

Com o painel aberto, o Chrome avisa pelo CDP (Chrome DevTools Protocol, o canal entre a página e o painel) que chegou uma folha de estilo com um sourceMapURL. A partir daí, é a interface do DevTools que baixa o .map e faz a tradução. O motor que desenha a página nunca usa o mapa.

A estrutura do JSON

O formato se chama Source Map versão 3 e virou a norma ECMA-426 em 2024. Este é o arquivo real do laboratório:

{
  "version": 3,
  "sourceRoot": "",
  "sources": [
    "../scss/_botao.scss",
    "../scss/_variaveis.scss",
    "../scss/style.scss"
  ],
  "names": [],
  "mappings": "AAEA;EACE;EACA,eCHK;EDIL,YCLa;EDMb;ECFA;;ADKA;ECLA;;ADSA;EACE;;;AEXJ;EACE;EACA;;AAEA;EACE,ODRW",
  "file": "style.css"
}
  • version: sempre 3.
  • file: o arquivo gerado que o mapa descreve.
  • sources: os originais. Os dois primeiros são parciais (arquivos que começam com sublinhado) trazidos pelo @use. Cada caminho é resolvido a partir da URL do próprio .map, com o sourceRoot na frente.
  • sourcesContent: opcional, embute o texto dos SCSS. Aqui ele não existe, então o DevTools baixa cada .scss pela rede.
  • names: usado por minificadores de JavaScript que renomeiam variáveis. O Sass deixa vazio.
  • mappings: toda a ligação entre os dois arquivos, numa string que parece lixo.

Como ler o mappings

  1. Cada ponto e vírgula separa uma linha do CSS gerado. Uma linha que não aponta para nada, como a do fecha-chaves, fica vazia: por isso aparece ;;.
  2. A vírgula separa segmentos dentro da mesma linha. Cada segmento liga uma posição do CSS a uma posição do SCSS.
  3. Cada segmento tem quatro números: coluna no CSS, qual arquivo de sources, linha no original e coluna no original. São diferenças em relação ao segmento anterior, e só a coluna do CSS volta a zero a cada linha nova. Tudo conta a partir de zero; o DevTools soma um para mostrar.

Os números vêm em Base64 VLQ (número de tamanho variável). Cada letra vale de 0 a 63 no alfabeto base64, ou seja, 6 bits. O bit mais alto diz se o número continua na letra seguinte, os outros cinco são dado, e o último bit do número montado é o sinal. Veja o segmento eCHK, na linha 3 do CSS (border-radius: 8px):

e = 30 = 0|11110 → +15    coluna no CSS    2 + 15 = 17
C =  2 = 0|00010 → +1     sources          0 + 1  = 1  (_variaveis.scss)
H =  7 = 0|00111 → −3     linha original   4 − 3  = 1
K = 10 = 0|01010 → +5     coluna original  2 + 5  = 7

Contando a partir de um: o 8px da linha 3, coluna 18 do CSS, vem da linha 2, coluna 8 de _variaveis.scss, que é $raio: 8px. O Dart Sass liga até o valor ao lugar onde a variável foi definida. No visualizador você clica em qualquer trecho do CSS e vê essa mesma conta, letra por letra.

Como o seletor chega ao .scss

No painel Styles, o CDP informa onde cada seletor e cada declaração começa no CSS. O DevTools procura, naquela linha do mappings, o segmento de maior coluna que não passa dessa posição, e mostra a origem dele.

  • .botao:hover (linha 8 do CSS) aparece como _botao.scss:10, o &:hover aninhado. O seletor gerado nem existe no SCSS: o mapa guarda só posições.
  • .cartao .titulo aparece como style.scss:8, o .titulo aninhado.
  • O box-shadow aparece como _variaveis.scss:5, dentro do mixin. No meio da mesma regra, o índice de arquivo muda de 0 para 1.

Ver no Chrome

No laboratório, abra o DevTools (Cmd+Option+I no Mac, F12 no Windows e no Linux) e siga a lista da própria página:

  • Em Elements, selecione o botão: o Styles mostra _botao.scss:3 em vez de style.css:1.
  • Cmd+clique (ou Ctrl+clique) numa declaração abre o SCSS no painel Sources.
  • O carregamento do mapa aparece em More tools → Developer resources, no menu de três pontos, com Status e Error. Por padrão quem pede o .map é o próprio DevTools, não a página (documentação oficial), então ele não entra na lista normal da aba Network.
  • Para baixar o mapa você mesmo, abra o style.css.map.
  • Desmarque Settings → Preferences → Sources → CSS source maps e recarregue: tudo volta a apontar para style.css.

Para praticar

Baixe o projeto, rode npm install e depois npm run explicar. Em seguida, rode node decode.mjs dist/style.min.css.map --explicar: no CSS minificado as colunas crescem e aparece número de duas letras, como qC, que vale 10 + 2×32 = 74 e vira +37. Por fim, npm test confere o decodificador escrito à mão contra a biblioteca source-map-js.