Beyond console.log
Making the most of your developer tools
Session Agenda
console
methods beyond.log
- How to read a stack trace
- Using the step debugger
- Event Listener breakpoints
- blackboxing
- Surface overview of other parts of devtools
Session Goal
Spark the 🔥 in your 💗 to explore your dev tools
Who am I?
Who are you?
like follow subscribe at
brianloveswords.github.io/srccon-2016
shift+click to execute code blocks
if shit gets weird, refresh the page
Opening up DevTools
View → Developer → Developer Tools
Command + Option + I
Clearing the Console
clear()
Control + L
console.log()
Alternate call signatures & formatters
// Old standby
console.log('this is normal');
// Can take multiple arguments, will separate them with a space
console.log('prefix:', {x: 'some object', y: 10}, 'then some more');
// Displaying element as HTML vs as an object
console.log('HTML (%o) vs Object (%O)', document, document);
// Styling with CSS!
console.log('%ca friggin travesty', 'font-size: 10em; color: red;');
console.dir()
Alias for console.log('%O', thing)
When I'm logging objects, I tend to use this over console.log because I usually want to inspect properties and I care less about HTML representation.
// Explore the HTML contained in the document
console.log(document);
// Explore the JavaScript properties attached to the document object
console.dir(document);
console.info()
console.warn()
console.warn()
Some preset style, useful with filters
console.info('this is some information that might be useful, whatever');
console.warn('this could be an issue');
console.warn('%calso supports formatters', 'color: #f0f');
console.error()
console.trace()
console.trace()
Stack traces!
let foo = function() {
console.info('entering foo');
bar();
}
let bar = function() {
console.info('entering bar');
baz();
}
let baz = function() {
console.info('entering baz');
console.trace('from baz');
console.error('this should not have happened');
}
foo();
console.group()
console.groupCollapsed()
console.groupCollapsed()
Group logs into a collapsable object
// Until console.groupEnd() is called, every `console.*` call
// will end up in a collapsable group.
console.group('do the stuff');
console.log('this is how we do it');
console.trace();
// Groups can be nested & formatters work!
console.groupCollapsed('do more stuff');
console.info('this is some information');
console.error('oh shit');
console.groupEnd();
console.log('one last thing from the outside group');
// Always make sure to end your groups
console.groupEnd();
async, blegh
// Not ideal imo
setInterval(_ => {
console.group('time1');
console.log('this is a member of time1');
console.groupEnd('time1');
}, 997);
setInterval(_ => {
console.group('time2');
console.log('this is a member of time2');
console.groupEnd('time2');
}, 911);
A solution I have used
let debug = function (prefix, msg, ...rest) {
// Short-circuit on production. Use a build system
// system to include a script that sets this global state.
if (window.ENVIRONMENT === 'production') {
return true;
}
let style = 'font-weight: bold; color: #dcd;';
console.log(`%c:${prefix}:%c ${msg}`,
style, '', ...rest);
}
setInterval(_ => debug('noise', Date.now()), 2000);
setInterval(_ => debug('module1', 'this is something, eh? %O%', document.body), 3000);
setInterval(_ => debug('module2', 'something unrelated'), 4000);
setInterval(_ => debug('module3', 'definitely aliens on the ship'), 5000);
console.time()
console.timeEnd()
console.timeEnd()
console.time('social-construct');
// Multiple timers are totally fine as long as
// they have different names
console.time('message')
console.info('time is a social construct');
console.timeEnd('message')
setTimeout(_ => {
console.info('%c...or is it?', 'font-style: italic');
console.timeEnd('social-construct');
}, 2000)
console.table()
Sortable data in the console
// Remember to turn on async stack traces
fetch('albums.json')
.then(response => response.json())
.then(albums => {
// Show everything
console.table(albums);
// Show only selected fields
console.table(albums, ['year']);
})
.catch(e => console.error(e))
💸 Cache Problems 💸
- Network tab → Disable cache
- Application tab → Clear storage
debugger
// This program is broken, let's find out why
let foo = function(input) {
console.info('entering foo, once again');
bar(`${input} ${input}`);
}
let bar = function(input) {
console.info('entering bar, pump up the world');
let parts = input.split(' ');
parts.push(parts[0]);
baz(parts.join(' '));
}
let baz = function(input) {
console.info('entering baz, watch my flow');
console.log(`🎶 ${input} you know that I'll be back 🎶`);
}
foo('return of the mack');
Pause On Exception
// Make sure to turn on Pause on Exception first
let x = {howDoWeDoIt: this};
console.log('this is gonna happen');
undefined('i bet this is a function');
console.log('never gonna get here');
console.assert()
let x = {howDoWeDoIt: this};
console.assert(1 == 1, 'somehow math stopped working');
console.assert(1 == 2, 'yep I guess math did stop working');
console.log('assert does not cause abrupt completion');
Event Listener Breakpoints
document.body.addEventListener('mouseup', event => {
// remember to go into the Sources tab and turn on the mouseup
// event listener breakpoint. When it breaks, execution will be
// paused within this context.
let time = Date.now();
let element = event.target;
console.log(`${time}: %O`, element);
});
console.info('event listener added');
blackboxing
// This function is provided by the hot new 10x framework, 'chaos.js'.
// It flips a coin and `throws` some unwanted saxophones on heads
// To blackbox this dumb, dumb script, go to devtools settings,
// look for "blackboxing" on the right navigation.
chaos();
Standardization
For a long time there was no standard for the
console
API. There is an effort to change that
going on at github.com/whatwg/console