Eu adoro pontos de interrupção condicionais. É verdade! Eles são minha ferramenta de depuração favorita.
Quando comecei a trabalhar com desenvolvimento web, “depuração” para mim significava criar um <pre id='log'></pre>
e anexar strings ao seu conteúdo para funcionar como um registro. Mas quando Firebug e depois quando os navegadores começaram a incorporar suas próprias ferramentas de desenvolvimento, foi como passar de um skate para um jato particular. Breakpoints, watches, pilhas de chamadas, profilers, monitores de atividade de rede – todos eles são úteis e eu não gostaria de perder nenhum deles.
Mas os pontos de interrupção condicionais são os meus favoritos, e não é nem um pouco difícil. Veja como eu os utilizo:
Quebrando somente em determinadas condições
O caso óbvio é o que está documentado em todos os lugares: criar um ponto de interrupção que só interrompe a execução quando uma determinada expressão é avaliada como true
.
Usar pontos de interrupção condicionais dessa forma é bom quando estou tentando rastrear algum comportamento estranho em uma seção de código que é executada com frequência, mas cujo comportamento é interrompido somente na presença de combinações específicas de dados. Um ponto de interrupção normal apenas pausaria a execução todas as vezes e a depuração seria entediante, mas um ponto de interrupção condicional permite que o usuário faça uma pausa apenas quando os dados corretos estiverem presentes, para que possa parar e dar uma olhada. Muito bom.
Mas esse é o uso mais comum. Honestamente, essa é provavelmente a maneira menos comum de usá-los. Como o senhor vê, os pontos de interrupção condicionais são um bisturi. Eles são um de macaco sonho.
Exportação de variáveis para o escopo global
O senhor já esteve em uma situação em que queria ter acesso ao console de uma variável definida localmente em uma função, mas de um contexto de execução fora da função? Isso acontece comigo o tempo todo; quero deixar meu aplicativo carregar e executar até um estado ocioso e, em seguida, poder inspecionar, digamos, propriedades ou métodos em algum objeto bloqueado em um fechamento. Pontos de interrupção condicionais para o resgate!
O principal truque aqui é usar o humilde operador de vírgula para garantir que a atribuição não seja avaliada como verdadeira, pois isso faria com que o ponto de interrupção pausasse a execução. Em vez disso, a expressão do ponto de interrupção é avaliada como false
e o aplicativo passa direto por ela e é executado até ficar ocioso, e então o senhor pode inspecionar o valor no console o quanto quiser apenas digitando seu nome.
Nota: Tenho o hábito de fazer window.varName
em vez de apenas varName
para que eu não modifique acidentalmente uma variável que existe em um escopo externo em relação ao local do ponto de interrupção.
Dica: Em um navegador habilitado para ES2015+, exporte uma série de variáveis rapidamente com nomes de propriedades abreviados: window.dealyBob = {var1, var2, otherVar}, false
Usar o operador de vírgula dessa forma é a chave para criar pontos de interrupção condicionais cantar.
Como adicionar registro sem editar o código
Meu caso de uso mais comum para breakpoints condicionais é o registro. Sei que é comum entre os desenvolvedores profissionais zombar do console.log
-mas poder instrumentar seu código sem precisar reconstruir ou mesmo recarregar, ver tudo ser executado em tempo real e obter uma saída de diagnóstico detalhada é fantástico.
O que é maravilhoso sobre isso é que as Dev Tools salvarão as associações dos pontos de interrupção com o(s) arquivo(s) em questão (pelo menos no Chrome, onde costumo trabalhar com mais frequência atualmente), de modo que eles ainda estarão lá na próxima vez que eu carregar o aplicativo em uma sessão diferente, sem que eu realmente tenha que salvar quaisquer alterações no código do meu aplicativo! Isso me dá uma espécie de tempo de execução Orientado a aspectos sistema de registro de logs que reside exclusivamente no navegador. O que o senhor acha da separação de preocupações?
Modificação de dados
Digamos que o senhor tenha um bug em que a reprodução é para ter uma combinação específica de dados carregados e, para chegar a esse estado, é necessário seguir uma série de etapas tediosas. Agora não mais! Como leitor atento, tenho certeza de que o senhor notou anteriormente que, se for possível modificar propriedades em window
para criar novas variáveis globais em uma expressão de ponto de interrupção condicional, não há nada que o impeça de modificar qualquer outra coisa.
Então, vá em frente e cole um monte de JSON em um ponto de interrupção condicional e atribua-o às variáveis de que o senhor precisa. Bum! Diga adeus à tediosa reprodução.
Dica: o operador de vírgula permite que o senhor encadeie mais do que apenas dois portanto, se o senhor tiver um conjunto completo de atribuições a fazer, vá em frente e diga: (var1 = x; var2 = y; var3 = z), console.log('overriding with', x, y, z), false
Dica relacionada: Não se esqueça de que é possível definir valores em qualquer objeto global a partir do console; se tiver objetos particularmente grandes para usar como substituições, ou se quiser alterar os dados que um ponto de interrupção condicional usará sem precisar modificar o ponto de interrupção real, vá até o console e diga window.bigOverrideObject = {pasteYourObjectHere}
e, em seguida, na expressão do ponto de interrupção condicional, var1 = window.bigOverrideObject, false
Injetando e testando novos códigos
Como leitor perspicaz que é, o senhor provavelmente já percebeu que as expressões de ponto de interrupção condicional são apenas código JavaScript que é executado no escopo e no contexto em que são colocadas. Se é possível fazer atribuições ou gravar no console em um ponto de interrupção condicional, por que não usar um para testar o novo código do aplicativo? Sim.
Insira um ponto de interrupção condicional em qualquer lugar que desejar e execute o que quiser! Há algumas limitações – por exemplo, o senhor não pode return
da função atual diretamente na expressão do ponto de interrupção, mas, na maioria das vezes, o senhor pode fazer as transformações ou os cálculos de que seu aplicativo precisa.
É aqui que entra o aspecto do monkey patching: o senhor pode combinar todas essas técnicas e usar pontos de interrupção condicionais para sobrescrever funções inteiras, mesmo quando elas estão dentro de uma closure. Confira:
Muito sorrateira, irmã! (aviso: referência aos garotos dos anos 80)
Dica: Suas ferramentas de desenvolvimento obviamente não estão modificando o código do aplicativo implantado, portanto, essa é uma ótima maneira de experimentar coisas em seu sistema de produção sem fazer todo um ciclo de compilação/implantação. No entanto, tenha cuidado para não ajustar as coisas de tal forma que elas acabem destruindo seus dados de produção!
Conclusão
Eu adoro breakpoints condicionais. E agora espero que o senhor também goste!
PS: agradecimentos especiais ao meu amigo e colega entusiasta do breakpoint condicional Brian Sinclair por revisar este artigo e pela conversa que o inspirou. Seu amor pelos pontos de interrupção condicionais é realmente incondicional.