Introdução
Hoje, os autores podem usar muitas abstrações para criar aplicativos da Web. Em vez de interagir diretamente com as APIs de nível inferior fornecidas pela plataforma da Web, muitos autores usam frameworks, ferramentas de build e compiladores para criar aplicativos de um ponto de vista mais alto.
Por exemplo, os componentes criados com base no framework Angular são criados em TypeScript com modelos HTML. Por trás, o Angular CLI e o webpack compilam tudo para JavaScript e para um pacote, que é enviado ao navegador.
Ao depurar ou criar perfis de aplicativos da Web no DevTools, você pode conferir e depurar essa versão compilada do código, em vez do código que você realmente escreveu. Como autor, isso não é o que você quer:
- Você não quer depurar o código JavaScript reduzido, mas sim o código JavaScript original.
- Ao usar o TypeScript, você não quer depurar o JavaScript, mas sim o código TypeScript original.
- Quando você usa modelos como Angular, Lit ou JSX, nem sempre é necessário depurar o DOM resultante. Talvez você queira depurar os componentes.
Em geral, é recomendável depurar seu próprio código conforme você o escreveu.
Embora os mapas de origem já reduzam essa lacuna, o Chrome DevTools e o ecossistema podem fazer mais nessa área.
Vamos dar uma olhada.
Código criado e código implantado
Atualmente, ao navegar pela árvore de arquivos no painel de fontes, você pode conferir o conteúdo do pacote compilado e, muitas vezes, minimizado. Esses são os arquivos que o navegador faz o download e executa. O DevTools chama isso de Código implantado.
Isso não é muito prático e, muitas vezes, é difícil de entender. Como autor, você quer ver e depurar o código que escreveu, não o código implantado.
Para compensar, agora é possível mostrar o Código criado na árvore. Isso faz com que a árvore se pareça mais com os arquivos de origem que você encontra no ambiente de desenvolvimento integrado, e esses arquivos agora estão separados do Código implantado.
Para ativar essa opção no Chrome DevTools, acesse Settings > Experiments e marque Group sources into Authored and Deployed trees.
"Apenas meu código"
Ao usar dependências ou criar em cima de um framework, os arquivos de terceiros podem atrapalhar. Na maioria das vezes, você só quer ver seu código, não o de alguma biblioteca de terceiros escondida na pasta node_modules
.
Para compensar isso, o DevTools tem uma configuração extra ativada por padrão: Adicionar automaticamente scripts conhecidos de terceiros à lista de ignorados. Ela está disponível em Ferramentas do desenvolvedor > Configurações > Lista de ignorados.
Com essa configuração ativada, o DevTools oculta qualquer arquivo ou pasta que uma estrutura ou ferramenta de build tenha marcado como ignorar.
A partir da Angular v14.1.0, o conteúdo das pastas node_modules
e webpack
foi marcado como tal. Portanto, essas pastas, os arquivos nelas e outros artefatos de terceiros não aparecem em vários lugares nas Ferramentas do desenvolvedor.
Como autor, você não precisa fazer nada para ativar esse novo comportamento. Cabe ao framework implementar essa mudança.
Código na lista de ignorados em stack traces
Um lugar em que esses arquivos na lista de ignorados não aparecem mais é nos stack traces. Agora, como autor, você pode conferir mais traces de pilha relevantes.
Se você quiser ver todos os frames de chamada do stack trace, clique no link Show more frames.
O mesmo se aplica às pilhas de chamadas que aparecem durante a depuração e a execução do código. Quando frameworks ou bundlers informam o DevTools sobre scripts de terceiros, o DevTools oculta automaticamente todos os frames de chamada irrelevantes e pula qualquer código ignorado durante a depuração passo a passo.
Código ignorado na árvore de arquivos
Para ocultar os arquivos e pastas da lista de ignorados da árvore de arquivos Código criado no painel Origens, marque Ocultar código da lista de ignorados na visualização de árvore de origens em Configurações > Experimentos nas Ferramentas do desenvolvedor.
No projeto Angular de exemplo, as pastas node_modules
e webpack
agora estão ocultas.
Código ignorado na lista do menu "Abrir rapidamente"
O código na lista de ignorados não é apenas oculto da árvore de arquivos, mas também do menu "Abrir rapidamente" (Control+P (Linux/Windows) ou Command+P (Mac)).
Mais melhorias nos stack traces
Além dos relevantes, o Chrome DevTools apresenta ainda mais melhorias nos rastros de pilha.
Stack traces vinculados
Quando algumas operações são programadas para acontecer de forma assíncrona, os rastros de pilha no DevTools atualmente mostram apenas parte da história.
Por exemplo, aqui está um programador muito simples em um arquivo framework.js
hipotético:
function makeScheduler() {
const tasks = [];
return {
schedule(f) {
tasks.push({ f });
},
work() {
while (tasks.length) {
const { f } = tasks.shift();
f();
}
},
};
}
const scheduler = makeScheduler();
function loop() {
scheduler.work();
requestAnimationFrame(loop);
};
loop();
… e como um desenvolvedor pode usar isso no próprio código em um arquivo example.js
:
function someTask() {
console.trace("done!");
}
function businessLogic() {
scheduler.schedule(someTask);
}
businessLogic();
Ao adicionar um ponto de interrupção no método someTask
ou ao inspecionar o rastro impresso no console, você não encontra nenhuma menção à chamada businessLogic()
que foi a "causa raiz" dessa operação.
Em vez disso, você só vai ver a lógica de programação do framework que levou à execução da tarefa e nenhum breadcrumb no stack trace para ajudar a descobrir os links causais entre os eventos que levaram a essa tarefa.
Graças a um novo recurso chamado "Marcação de pilha assíncrona", é possível contar toda a história vinculando as duas partes do código assíncrono.
A API Async Stack Tagging apresenta um novo método console
chamado console.createTask()
. A assinatura da API é a seguinte:
interface Console {
createTask(name: string): Task;
}
interface Task {
run<T>(f: () => T): T;
}
A chamada console.createTask()
retorna uma instância de Task
que pode ser usada mais tarde para executar o conteúdo f
da tarefa.
// Task Creation
const task = console.createTask(name);
// Task Execution
task.run(f);
A tarefa forma o vínculo entre o contexto em que foi criada e o contexto da função assíncrona que está sendo executada.
Aplicado à função makeScheduler
acima, o código fica assim:
function makeScheduler() {
const tasks = [];
return {
schedule(f) {
const task = console.createTask(f.name);
tasks.push({ task, f });
},
work() {
while (tasks.length) {
const { task, f } = tasks.shift();
task.run(f); // instead of f();
}
},
};
}
Graças a isso, o Chrome DevTools agora pode mostrar um stack trace melhor.
Observe que businessLogic()
agora está incluído no stack trace. Além disso, a tarefa tem um nome familiar, someTask
, em vez do requestAnimationFrame
genérico de antes.
Frames de chamada amigáveis
Os frameworks geralmente geram código de todos os tipos de linguagens de modelagem ao criar um projeto, como modelos Angular ou JSX que transformam código com aparência de HTML em JavaScript simples que é executado no navegador. Às vezes, esses tipos de funções geradas recebem nomes que não são muito amigáveis, como nomes de uma única letra após a minificação ou nomes obscuros ou desconhecidos, mesmo quando não são.
No projeto de exemplo, um exemplo disso é AppComponent_Template_app_button_handleClick_1_listener
, que aparece no stack trace.
Para resolver esse problema, o Chrome DevTools agora oferece suporte à renomeação dessas funções usando mapas de origem. Se um mapa de origem tiver uma entrada de nome para o início de um escopo de função, o frame de chamada vai mostrar esse nome no stack trace.
Como autor, você não precisa fazer nada para ativar esse novo comportamento. Cabe ao framework implementar essa mudança.
No futuro
Graças às adições descritas nesta postagem, as Ferramentas do desenvolvedor do Chrome podem oferecer uma melhor experiência de depuração. Há mais áreas que a equipe gostaria de explorar. Em particular, como melhorar a experiência de criação de perfil no DevTools.
A equipe do Chrome DevTools incentiva os autores de frameworks a adotar esses novos recursos. O Case Study: Better Angular Debugging with DevTools (link em inglês) oferece orientações sobre como implementar isso.