La lista de ignorados: el ajuste que hace usable el depurador
Cómo se configura el blackboxing, los patrones que funcionan, el campo ignoreList de los source maps, y los cinco comportamientos que cambia.
Depurar una aplicación con framework sin lista de ignorados es una experiencia mala: cada paso entra en el reconciliador, cada pila tiene treinta marcos de los cuales tres son tuyos, cada breakpoint de evento te deja en el manejador delegado, y la pausa en excepciones capturadas es inutilizable. Con la lista bien configurada, todo eso desaparece y el depurador se comporta como si tu código fuera lo único que hay. Es un único ajuste y cambia cinco comportamientos distintos a la vez.
- Configurar la lista de ignorados por patrón, por fichero y por carpeta.
- Enumerar los cinco comportamientos del depurador que cambia el blackboxing.
- Usar el campo
ignoreListde los source maps para que la configuración venga dada. - Reconocer cuándo hay que sacar temporalmente algo de la lista.
Las cuatro formas de añadir algo
Desde el menú contextual de un fichero en el árbol de Sources o en el editor: hay opciones para ignorar ese script y para ignorar toda la carpeta que lo contiene. Es la vía más rápida y la que se usa cuando ya te has topado con el código.
Desde el menú contextual de un marco en la pila de llamadas: ignorar ese script directamente desde donde te ha molestado. Es la más natural durante una sesión.
Desde los ajustes, en la sección de lista de ignorados, escribiendo patrones de expresión regular que se contrastan contra la URL completa del script. Es la vía para configuración permanente.
Automáticamente, con la opción de añadir los scripts de terceros conocidos, que se apoya en la información que los propios paquetes declaran.
Los patrones habituales que merece la pena tener puestos.
/node_modules/
/bower_components/
\.min\.js$
/vendor/
^chrome-extension://
/cdn\.
El de las extensiones es el que más ruido quita en un perfil que no sea limpio, y el de node_modules es el que cambia la vida en desarrollo local.
Los patrones son expresiones regulares contra la URL, no globs. Un patrón como node_modules/* no significa lo que crees: en expresión regular, el asterisco cuantifica el carácter anterior. La forma correcta de decir “cualquier cosa bajo node_modules” es simplemente /node_modules/, porque la coincidencia es por subcadena.
Los cinco comportamientos que cambia
Aquí está el motivo de que este ajuste rinda tanto. No hace una cosa: hace cinco.
Uno: el paso a paso no entra. Pasar por encima de una línea que llama a código ignorado ejecuta ese código sin detenerse en él. Entrar en una función ignorada te lleva a través de ella hasta el siguiente código no ignorado. Eso significa que puedes usar el paso a paso sobre código que llama a librerías sin acabar nunca dentro de ellas.
Dos: la pila se pliega. Los marcos ignorados se agrupan y se colapsan bajo una línea que indica cuántos hay. Una pila de treinta marcos pasa a mostrar cuatro tuyos y dos grupos plegados. La legibilidad cambia por completo.
Tres: los breakpoints de evento se saltan el intermediario. Cuando un evento se maneja primero por el framework y luego llega a tu código, el depurador salta los marcos ignorados y te presenta el primer marco tuyo. Es lo que hace que los breakpoints de evento sean prácticos con frameworks.
Cuatro: la pausa en excepciones ignora las de librerías. Este es el que convierte la pausa en excepciones capturadas de inservible a excelente, como se vio en el nivel anterior. Las excepciones que una librería lanza y captura internamente dejan de detenerte.
Cinco: las trazas de la consola se acortan. Las pilas que acompañan a console.warn, console.error y console.trace respetan la lista, así que apuntan a tu código en vez de a la librería que lo llamó.
El campo ignoreList de los source maps
La evolución natural del mecanismo: en vez de que cada desarrollador configure su lista a mano, el propio empaquetado declara qué ficheros son de terceros.
Un source map puede llevar un campo ignoreList con los índices, dentro de su array sources, de los ficheros que no son código de aplicación. Las herramientas de compilación modernas lo generan automáticamente marcando todo lo que venga de node_modules y todo lo que sea código auxiliar del propio empaquetador.
{
"version": 3,
"sources": ["webpack://app/src/main.js", "webpack://app/node_modules/libreria/index.js"],
"sourcesContent": ["...", "..."],
"names": [],
"mappings": "AAAA;;",
"ignoreList": [1]
}
Ese [1] dice que el segundo elemento de sources es de terceros. Con la opción automática activada en las DevTools, ese fichero queda ignorado sin que nadie haya escrito ningún patrón.
El campo tuvo un nombre anterior con prefijo de proveedor que todavía se encuentra en mapas generados por herramientas antiguas, y las DevTools siguen reconociéndolo. Si tu empaquetador no genera el campo, la lista manual sigue funcionando exactamente igual.
El beneficio de este enfoque es que la configuración viaja con el código: cualquiera que abra las DevTools sobre tu aplicación, incluido alguien de soporte o un compañero nuevo, obtiene la experiencia correcta sin configurar nada.
Cuándo sacar algo de la lista
La lista no es una decisión permanente. Hay tres momentos en los que hay que revertirla temporalmente.
Cuando sospechas que el bug está en la librería. Ocurre. Con la librería ignorada no puedes entrar en su código ni detenerte en sus excepciones, así que hay que sacarla para investigar.
Cuando quieres entender cómo funciona algo. Depurar el código de una librería es una de las mejores formas de aprender cómo está construida, y con ella ignorada no se puede.
Cuando la pila plegada esconde el marco que necesitas. El grupo plegado se puede expandir con un clic, así que este caso no exige tocar la configuración, solo recordar que se puede expandir.
Para el primer caso, el paso genérico del depurador —el cuarto modo, distinto del paso por encima— entra en código ignorado sin necesidad de cambiar nada.
Vale la pena decir esto sin rodeos porque explica un fenómeno muy extendido: buena parte de la gente que prueba el depurador de las DevTools y concluye que las trazas son mejores llegó a esa conclusión con la lista de ignorados sin configurar. Y con ella sin configurar, la conclusión es razonable. Pones un breakpoint en tu componente, das a entrar, y apareces en el planificador del framework. Sales, das a pasar por encima, y una excepción interna de una librería te detiene. Miras la pila y hay treinta y dos marcos con nombres de una letra. Cada operación produce fricción, y después de diez minutos de eso cualquiera vuelve a console.log, que al menos no le lleva a sitios donde no quiere estar. Lo relevante es que esa experiencia no es la del depurador: es la de un depurador mal configurado, y la diferencia entre las dos es literalmente un ajuste de treinta segundos. Con /node_modules/ en la lista y la opción automática activada, entrar en una función lleva a tu función, las pilas tienen cuatro marcos legibles, los breakpoints de evento paran en tu manejador, y la pausa en excepciones capturadas —que sin esto es inutilizable— pasa a ser la mejor herramienta que existe para encontrar errores tragados. Cinco comportamientos que van de molestos a excelentes con una casilla. Si hay una sola acción concreta que llevarse de todo este nivel, es abrir los ajustes ahora mismo, comprobar que la opción automática está activa, y añadir los dos o tres patrones que correspondan a tu proyecto. El resto de este tramo de la guía —los breakpoints sin línea, la pausa en excepciones, la lectura de pilas— asume esa configuración, y sin ella todo funciona notablemente peor.