Sourcemaps - Debugando JS e CSS minificados
Sabe quando você está usando uma lib qualquer (jQuery, bootstrap, etc), e abre o console do seu navegador, você percebe uma mensagem de erro 404, pois o browser está tentando baixar um arquivo jquery.js.map
ou bootstrap.css.map
? Afinal de contas: pra que serve esse arquivo .map
? Algum dia na MINHA VIDA eu vou precisar dele?
Vem descobrir! ;)
O problema
É praticamente impossível debugar JS e CSS minificados. Sempre que acontece um erro, e você precisa saber qual a linha de referência de um comando em um arquivo, você “desminifica” o CSS ou JS, e o inclui na sua aplicação para debugar.
Então qual é a solução?
Sourcemaps! Sim, aquele arquivo .map
que fica dando erro 404 no seu console é que vai resolver seu problema! :D
Como funcionam os sourcemaps
Quando você tem um código minificado, e adiciona a ele uma referência a um sourcemap, o sourcemap faz uma varredura no arquivo, e gera todas as referências a número de linha, nomes de variáveis e funções, etc., para que você possa debugar no arquivo “desminificado”.
Complicado? Com um exemplo prático vai ficar mais fácil de entender :D
Criando a estrutura de arquivos
Vamos criar a seguinte estrutura para o nosso teste com sourcemaps:
1 | . |
No diretório src
ficarão nossos fontes, e no public
, os arquivos concatenados e minificados.
Vamos utilizar o Gulp para fazer as tarefas de concatenação, minificação e geração do sourcemaps. Se você ainda não conhece o Gulp, e quer saber mais sobre, acesse: https://blog.da2k.com.br/tags/gulpjs/
Instalando os plugins do Gulp necessários
Instale os seguintes plugins:
1 | npm i --save-dev gulp gulp-concat gulp-uglify gulp-sourcemaps gulp-load-plugins |
Chamando os arquivos na index
Agora precisamos montar nossa index.html
para receber o arquivo JS minificado, para que possamos debugá-lo! A index deve ter esse código:
1 |
|
Bem básico! Só para que possamos ter o JS incluído :D
Códigos para os JS
Vamos agora colocar um pouco de código nos nossos arquivos JS. Primeiro o main.js
:
1 | ;(function( Module, undefined ) { |
Depois, o controllers/controller-home.js
:
1 | ;(function( win, doc, undefined ) { |
E então, vamos configurar nosso Gulpfile.
Configurando Gulpfile.js
1 | ; |
Esse gulpfile.js
vai concatenar e minificar todos os JS em um único arquivo. O gulp-load-plugins
vai carregar todos os plugins instalados que tem o prefixo gulp-*
, e vai colocar em um objeto, que nós chamamos de g
. O padrão para nome dos métodos é remover o prefixo gulp-
, remover o traço e usar camelCase.
Por exemplo: o plugin gulp-uglify pode ser chamado com g.uglify()
. Se estivéssemos usando CSS aqui, e adicionássemos o plugin gulp-minify-css
, ele poderia ser chamado com o comando g.minifyCss()
.
Executando o comando gulp
no terminal, os arquivos serão concatenados, minificados, e colocados nos diretório public/js
.
Acessando nossa index.html
, já podemos começar a ver como estão os arquivos. Antes de qualquer coisa, abra o console do seu navegador e então, clique no link. Será mostrado o seguinte erro:
Vamos então debugá-lo, clicando no link main.js
indicado:
Ops! Como faz pra achar o erro agora? O arquivo está minificado!
É hora de ver como funcionam os sourcemaps! Vamos modificar um pouco nosso Gulpfile, e adicionar o suporte aos sourcemaps no nosso JS:
1 | gulp.task( 'default', function() { |
Na linha 6
, logo após adicionar nossos source files, nós iniciamos o sourcemaps, para que ele tenha a referência de todos os arquivos. Após isso, concatenamos e minificamos o arquivo e, antes de gravá-lo em disco, executamos o método write
do sourcemaps
para que o arquivo main.js.map
seja salvo no mesmo local do main.js
.
Os plugins que ficam entre o sourcemaps.init()
e sourcemaps.write()
devem ter suporte para sourcemaps
. Para ver quais são todos os plugins do Gulp suportados, acesse esse link.
Feito isso, vamos gerar novamente nosso arquivo minificado, mas dessa vez, com o arquivo .map
. Execute gulp
no seu terminal.
Com o comando executado, se você abrir o diretório public/js
, verá que o arquivo main.js.map
está lá! E abrindo o main.js
, você pode ver, no final dele, um comentário com a referência ao seu .map
:
1 | //# sourceMappingURL=main.js.map |
Agora, recarregue a index.html
, e clique no link novamente. Vai continuar dando o mesmo erro. Mas perae, agora a referência de arquivo mudou:
O erro apontou para o arquivo controller-home.js
! E na linha 19
, exatamente onde acontece o erro! :D
Isso acontece porque o sourcemaps
guardou a referência desse arquivo, então ele sabe exatamente onde aconteceu o erro :D
Agora, clique no link com o nome do arquivo, e veja a mágica na aba Sources:
Agora chega de sofrer para debugar códigos :D
Lembrando que isso é uma feature do browser, e você pode desabilitá-la a qualquer momento, se não tiver o arquivo .map
de alguma lib que está dando erro 404 na sua aplicação. No Chrome, você pode clicar na Engrenagem, que aparece na Dev Tools, e desmarcar a opção Enable Javascript source maps.
Chega por hoje! Amanhã tem mais :D
Ficou com alguma dúvida? Comente!
Sobre o #1postperday: https://blog.da2k.com.br/2014/12/31/um-post-por-dia/
Tem alguma sugestão para os próximos posts do #1postperday? Deixe ela aqui: https://github.com/fdaciuk/fdaciuk.github.io/issues/1