Beyond Console.log, Episode III: aangepaste formatters in Devtools

Dit artikel maakt deel uit van een reeks artikelen over de Chrome Console;
Eerder op "Beyond console.log"
Ben je het zat om te zien dat je objecten altijd op dezelfde manier in de console worden gelogd? U houdt van de Chrome Dev Tools, maar u wilt de naam van de instanties van Eleve wordt weergegeven in rood, oranje of groen, afhankelijk van de waarde? Blijf op deze pagina, u hoeft niet verder te gaan.

Vereiste: aangepaste formatters inschakelen

Ga in DevTools naar instellingen en vink vervolgens het vakje "aangepaste formatters inschakelen" in het gedeelte "Console" aan.

Wat zijn aangepaste formatteerders?

de Aangepaste formatteerders zijn een array van objecten die zijn opgeslagen in object window. Ze stellen ons in staat om de weergave van een bepaald object naar wens aan te passen. Zo kunnen ze de leesbaarheid van onze logboeken aanzienlijk verbeteren. Of beter : de ogen van onze collega's laten bloeden (zie hieronder).
screenshot van wanneer we een object loggen() met de aangepaste formatters: hier verschijnen de letters in brand!
Ondanks hun bruikbaarheid, heb ik niet het gevoel dat dit een algemeen bekend onderwerp is, er is een zeer klein aantal artikelen over dit onderwerp op het internet, allemaal in het Engels. Laten we zonder verder oponthoud dit onrecht herstellen door onze handen vuil te maken.

het doel

  • Ten eerste zullen we ervoor zorgen dat de instanties van onze toekomstige studentenklas hun naam weergeven in het formaat voornaam + NAAM, en deze zal rood naar groen moeten worden gekleurd volgens het gemiddelde van zijn cijfers.
  • Dan zorgen wij voor een makkelijk te onderhouden code

Laten we coderen

Laten we eerst de klasse Student coderen:

class Student {
    constructor(firstname, lastname, notations) {
        this.firstname = firstname;
        this.lastname = lastname;
        this.notations = notations;
    }
    getAverageNotation() {
        return this.notations.reduce((total, notation) => total += notation, 0) / this.notations.length;
    }
}

... Laten we dan onze formatter declareren en aan de array toevoegen:

const studentFormatter = {
    header: (x) => {
        if (x instanceof Student) {
            const moyenne = x.getAverageNotation();
            const color = (moyenne > 15) ? 'limegreen' : (moyenne > 5) ? 'orangered' : 'firebrick';
            return [
                'span',
                {
                    style: 'color: ' + color
                },
                x.lastname.toUpperCase() + ' ' + x.firstname
            ];
        }
    },
    hasBody: x => x instanceof Student,
    body: (x) => {
        return [
            'table',
            {},
            ['tr', {},
                ['td', {style: 'color: burlywood'}, 'Prénom: '],
                ['td', {}, `${x.firstname}`],
            ],
            ['tr', {},
                ['td', {style: 'color: burlywood'}, 'Nom: '],
                ['td', {}, `${x.lastname}`],
            ],
            ['tr', {},
                ['td', {style: 'color: burlywood'}, 'Notes: '],
                ['object', {object: x.notes}],
            ],
        ];
    }
};
window.devtoolsFormatters = [ studentFormatter ];

Nu kunnen we een reeks studenten loggen:

const ducobu = new Student('Élève', 'Ducobu', [2, 5, 3]);
const willHunting = new Student('William', 'Hunt', [18, 20, 19]);
const nicolasLePetit = new Student('Nicolas', 'Le Petit', [10, 10, 10]);
console.info([ducobu, willHunting, nicolasLePetit]);

screenshot van devtools bij het loggen van een object met Custom Formatters

Korte code-analyse

mos opgewonden
Wauw, het is magisch, de namen van de leerlingen verschijnen in hoofdletters en het is gekleurd volgens het gemiddelde! Hoe zou ik tot nu toe zonder kunnen leven? Mijn leven als programmeur is voor altijd veranderd!
Elk object in de array met aangepaste formatters moet drie methoden hebben: hoofd, die een JSONML-object moet weergeven dat wordt gebruikt om de naam van het object weer te geven wanneer het is samengevouwen, heeftBody, die aangeeft of het object uitvouwbaar is en tot slot lichaam die de HTML-sjabloon van de uitgevouwen hoofdtekst van het object moet weergeven in JSONML-indeling. De enige toegestane HTML-elementen zijn echter: tafel, tr, ts, ol, li, div et span
Hier controleer ik of x is een voorbeeld van Student avec instanceof. Merk op dat dit zal terugkeren true voor elke subklasse van Student. Als we de formatter alleen willen inschakelen als het object precies een instantie is van Student, hadden we kunnen schrijven:
if (x.constructor === Student)

Ga verder

Dat is allemaal niet erg. Maar in een groot project zie ik niet dat mensen de klasse die ze zojuist hebben gemaakt handmatig aan de array window.devtoolsFormatters toevoegen. Het zou beter zijn als Student's CustomFormatter in de klas zelf werd gedefinieerd. Maar dat zou een nadeel zijn: het zou onze studenten vervuilen, het zou kunnen leiden tot aanrijdingen. Met dit soort problemen in het achterhoofd zullen we gebruik maken van symbolen:

const CustomFormatterToken = Symbol('CustomFormatter');
// en ajoutant cette propriété à Symbol, ça permet à notre
// fonctionnalité d'être accessible partout :
Symbol.customFormatter = CustomFormatterToken;
// Voici la nouvelle version de la classe Eleve :
class Student {
    constructor(firstname, lastname, notations) {
        this.firstname = firstname;
        this.lastname = lastname;
        this.notations = notations;
    }
    get [CustomFormatterToken]() {
        return {
            header: () => {
                const averageNotation = this.getAverageNotation();
                const color = (moyenne > 15) ? 'limegreen' : (moyenne > 5) ? 'orangered' : 'firebrick';
                return [
                    'span',
                    {
                        style: 'color: '+ color + '}'
                    },
                    this.lastname.toUpperCase() + 'this.firstname'
                ];
            },
            hasBody: () => true,
            body: () => [
                'table',
                {},
                ['tr', {},
                    ['td', {style: 'color: burlywood'}, 'prenom: '],
                    ['td', {}, `${this.firstname}`],
                ],
                ['tr', {},
                    ['td', {style: 'color: burlywood'}, 'nom: '],
                    ['td', {}, `${this.lastname}`],
                ],
                ['tr', {},
                    ['td', {style: 'color: burlywood'}, 'notes: '],
                    ['object', {object: this.notations}],
                ],
            ]
        };
    }
    getAverageNotation() {
        return this.notations.reduce((total, notation) => total += notation, 0) / this.notations.length;
    }
}
// Dorénavant, devtoolsFormatters n'aura qu'une seule valeur : AllPurposeFormatter
const AllPurposeFormatter = {
    header: x => {
        const formatter = x[Symbol.customFormatter];
        if (formatter) {
            return formatter.header();
        }
    },
    hasBody: x => {
        const formatter = x[Symbol.customFormatter];
        if (formatter) {
            return formatter.hasBody();
        }
    },
    body: x => {
        const formatter = x[Symbol.customFormatter];
        if (formatter) {
            return formatter.body();
        }
    },
};
window.devtoolsFormatters = [ AllPurposeFormatter ];
const ducobu = new Student('Élève', 'Ducobu', [2, 5, 3]);
const willHunting = new Student('William', 'Hunt', [18, 20, 19]);
const nicolasLePetit = new Student('Nicolas', 'Le Petit', [10, 10, 10]);
console.info([ducobu, willHunting, nicolasLePetit]);
// les propriétés qui ont pour clé un symbole n'apparaissent pas...
// Notre objet n'est pas pollué \o/
console.log(Object.keys(ducobu)); // => ["firstname", "lastname", "notations"]

sneakers
Nou, dat was alles voor vandaag. Tot snel voor nieuwe avonturen met Chromes Dev Tools!