Full Stack

Come configurare Prettier ed ESLint

Autore

Manuel Ricci

La gestione del codice può diventare complessa, soprattutto nei team di sviluppo, dove coerenza e leggibilità sono essenziali. Prettier ed ESLint sono due strumenti indispensabili per semplificare questo processo: automatizzano la formattazione, rilevano errori e garantiscono uno stile uniforme. In questo articolo scoprirai come configurarli e integrarli per ottenere un flusso di lavoro più efficiente.

Cos’è Prettier?

Prettier è uno strumento che formatta automaticamente il codice in modo uniforme, supportando linguaggi come JavaScript, TypeScript, CSS, HTML e molti altri. La sua funzione principale è quella di eliminare le discrepanze nello stile, trasformando il codice in una versione pulita e conforme a regole specifiche, senza bisogno di interventi manuali.

Lanciato nel 2017 durante il React Conf da James Long, Prettier ha rivoluzionato il modo in cui i team gestiscono la formattazione del codice, diventando uno standard di fatto per molti sviluppatori.

Perché usare Prettier?

La standardizzazione dello stile è fondamentale per garantire coerenza all'interno dei progetti, ma far sì che tutti rispettino le regole può essere una sfida. Prettier risolve questo problema applicando automaticamente uno stile uniforme, senza lasciare spazio a interpretazioni soggettive.

Che tu sia un programmatore esperto o alle prime armi, Prettier semplifica la gestione del codice:

  • Per i team di sviluppo: elimina discussioni inutili sullo stile del codice.
  • Per i principianti: aiuta a mantenere il codice ordinato, riducendo il rischio di errori dovuti alla disorganizzazione.

Cos’è ESLint?

Se Prettier si occupa della formattazione, ESLint entra in gioco per garantire che il codice rispetti le regole e le best practice. Creato nel 2013 da Nicholas C. Zakas, ESLint è un linter altamente configurabile per JavaScript che aiuta a identificare e correggere problemi legati a bug, qualità del codice e aderenza agli standard.

Perché usare ESLint?

Grazie alla sua flessibilità e personalizzazione, ESLint consente di definire regole specifiche per il progetto o il team, come l'obbligo di utilizzare il punto e virgola o il divieto di variabili inutilizzate. Inoltre, i file di configurazione di ESLint possono essere condivisi facilmente, favorendo la coerenza tra i progetti.

Un altro vantaggio è l’estensibilità: grazie ai plugin, ESLint può essere adattato per funzionare con framework come Angular, Vue o React, coprendo un ampio spettro di esigenze.

Cosa accomuna Prettier ed ESLint?

Anche se Prettier ed ESLint hanno scopi diversi, possono essere integrati per ottenere il meglio di entrambi. Mentre Prettier gestisce la formattazione, ESLint si occupa delle regole e delle best practice, garantendo codice leggibile, ordinato e conforme agli standard del team.

Nella lezione che segue, ti guiderò passo passo nella configurazione e integrazione di questi strumenti, mostrando come farli lavorare insieme per semplificare il tuo workflow.

Alla fine, troverai anche un approfondimento tecnico su come funzionano Prettier ed ESLint. Se sei curioso di esplorare i dettagli più avanzati, non perderti questa sezione extra!

Come si installa ed esegue Prettier

Prettier è uno strumento fondamentale per mantenere il codice ordinato e leggibile. Ecco come configurarlo e utilizzarlo nel tuo progetto in pochi passaggi.

Per iniziare, installa Prettier come dipendenza di progetto. Questo richiede che il progetto sia già stato inizializzato con npm o yarn.

Esegui uno dei seguenti comandi nella root del tuo progetto:

1# Con npm
2npm install --save-dev prettier
3
4# Con yarn
5yarn add --dev prettier

Nota: La documentazione ufficiale consiglia di utilizzare anche il flag --exact, per garantire che venga installata una versione specifica di Prettier. A te la scelta se adottarlo.

Se preferisci non installare Prettier come dipendenza di progetto, puoi eseguirlo con npx senza installazione permanente:

1npx prettier --write .

Dopo l’installazione crea un file .prettierrc nella directory principale del progetto. Ecco un esempio di configurazione base:

1{
2  "semi": true,
3  "singleQuote": true,
4  "tabWidth": 2,
5  "trailingComma": "es5"
6}

Cosa significano queste opzioni?

  • semi: aggiunge il punto e virgola alla fine delle istruzioni.
  • singleQuote: usa apici singoli invece di doppi.
  • tabWidth: imposta la larghezza del tab.
  • trailingComma: aggiunge una virgola finale in array e oggetti multi-linea.

Puoi anche creare un file .prettierignore per escludere determinati file o directory dalla formattazione. Ad esempio:

1node_modules/
2build/
3dist/

Aggiungi uno script al file package.json per eseguire Prettier facilmente:

1"scripts": {
2  "format": "prettier --write ."
3}

Ora puoi formattare tutto il progetto eseguendo:

1npm run format

Ovviamente cosa formatta se ancora non abbiamo un file?

Codice disordinato:

1const arr = [
21,
32,
43
5]
6
7function somma(a, b) {return a + b}

Eseguiamo quindi il comando con npm run format da terminale e diamo un’occhiata al nostro file JavaScript.

1const arr = [1, 2, 3];
2
3function somma(a, b) {
4  return a + b;
5}

Tutto è ora conforme alle regole specificate in .prettierrc.

Comandi utili per Prettier CLI

Prettier offre diversi comandi tramite CLI per situazioni specifiche:

  • --ignore-path: consente di specificare un file diverso da .prettierignore o .gitignore per escludere file.
  • --no-config: ignora il file .prettierrc e utilizza le impostazioni predefinite.
  • --cache: migliora le performance salvando informazioni sulle operazioni già eseguite (crea un file di cache in node_modules/.cache).

Anche se Prettier non supporta una modalità di watch nativa, puoi utilizzare package come onchange per eseguire la formattazione in tempo reale.

Come integrare Prettier nel proprio editor

Prettier può essere facilmente integrato con Visual Studio Code tramite l’estensione ufficiale Prettier - Code formatter.

Dopo averla installata, configura il formatter predefinito nel file di impostazioni di VS Code (settings.json):

1{
2  "editor.defaultFormatter": "esbenp.prettier-vscode",
3  "editor.formatOnSave": true
4}

Con questa configurazione, il codice verrà formattato automaticamente al salvataggio. Se vuoi disabilitare questa funzione per uno specifico linguaggio, usa:

1{
2  "[javascript]": {
3    "editor.formatOnSave": false
4  }
5}

Ecco un esempio di come disabilitare la formattazione al salvataggio solo per file JavaScript.

Integrare Prettier nel workflow Git con un hook di pre-commit

Un modo pratico per integrare Prettier nel flusso di lavoro è utilizzare un hook di pre-commit di Git. Questo approccio garantisce che tutti i file siano formattati automaticamente prima di ogni commit, mantenendo il codice sempre conforme alle regole stabilite.

Nella cartella .git/hooks si trova un file chiamato pre-commit.sample. Rinominatelo in pre-commit (rimuovendo l’estensione .sample).

Apri il file nel tuo editor e inserisci il seguente script:

1#!/bin/sh
2echo "Eseguendo Prettier sui file modificati..."
3
4# Ottieni l'elenco dei file modificati
5files=$(git diff --cached --name-only --diff-filter=ACM | grep -Ei '\.(js|ts|jsx|tsx)$)
6
7# Se ci sono file da formattare, esegui Prettier
8if [ -n "$files" ]; then
9  echo "$files" | xargs npx prettier --write
10  echo "Aggiungo i file formattati allo staging..."
11  echo "$files" | xargs git add
12else
13  echo "Nessun file da formattare."
14fi
15
16exit 0

Come funziona questo script?

  • git diff --cached --name-only --diff-filter=ACM: Ottiene la lista dei file aggiunti o modificati (staged).
  • grep -Ei '\.(js|ts|jsx|tsx)$: Filtra i file con estensioni JavaScript, TypeScript o simili.
  • npx prettier --write: Applica Prettier ai file filtrati.
  • git add: Rimette i file formattati nello staging area, pronti per il commit.

Quando eseguirai un commit, vedrai il messaggio:

1“Eseguendo Prettier sui file modificati…”

Seguito dagli output generati da Prettier durante la formattazione. Questo garantisce che il codice sia sempre pulito e conforme alle regole configurate.

Per ulteriori dettagli su questo approccio e su altre opzioni, consulta la documentazione ufficiale di Prettier.

Come si installa ed esegue ESLint

ESLint è uno strumento essenziale per individuare e correggere errori nel codice JavaScript. La nuova modalità di configurazione utilizza il comando npm init @eslint/config@latest, che semplifica notevolmente l'installazione e la configurazione.

Per iniziare, esegui il seguente comando nella root del tuo progetto:

1npm init @eslint/config@latest

Questo comando ti guiderà nella creazione del file di configurazione per ESLint. Durante il processo, ti verranno poste domande come:

  • Quale tipo di modulo stai usando? (CommonJS o ES Modules)
  • Quali framework utilizzi? (ad esempio, React, Vue, ecc.)
  • Vuoi supportare TypeScript?
  • Preferisci un file di configurazione in formato JavaScript, JSON o YAML?

Al termine, ESLint verrà installato automaticamente e verrà creato un file di configurazione predefinito, eslint.config.js.

Ecco un esempio di configurazione generata:

1import globals from "globals";
2import pluginJs from "@eslint/js";
3
4/** @type {import('eslint').Linter.Config[]} */
5export default [
6  {
7    languageOptions: { globals: globals.browser },
8  },
9  pluginJs.configs.recommended,
10];

Puoi arricchire la configurazione aggiungendo opzioni più specifiche:

1import pluginJs from "@eslint/js";
2import globals from "globals";
3
4/** @type {import('eslint').Linter.Config[]} */
5export default [
6  {
7    ignores: ["node_modules", "dist"], // Esclude directory dall'analisi
8  },
9  pluginJs.configs.recommended, // Applica le regole raccomandate di ESLint
10  {
11    files: ["**/*.js"], // Specifica i file su cui applicare ESLint
12    languageOptions: { globals: globals.browser },
13    rules: {
14      "no-unused-vars": "warn", // Avvisa per variabili inutilizzate
15      eqeqeq: "error", // Richiede l'uso di === invece di ==
16      quotes: ["error", "single"], // Enforce l'uso di apici singoli
17    },
18  },
19];

Spiegazione delle opzioni:

  • ‘ignores’: Esclude file o directory dall'analisi.
  • ‘files’: Specifica i file su cui ESLint deve lavorare.
  • ‘languageOptions’: Configura le opzioni del linguaggio (ad esempio, globals).
  • ‘rules’: Contiene le regole personalizzate.

Dopo aver configurato ESLint, puoi eseguirlo utilizzando il comando:

1npx eslint .

Per correggere automaticamente i problemi che possono essere risolti in modo sicuro, usa:

1npx eslint --fix .

Per semplificare l'utilizzo, puoi aggiungere uno script nel file package.json:

1"scripts": {
2  "lint": "eslint ."
3}

Esegui il comando con:

1npm run lint

Esempio pratico: \ Codice non conforme:

1const arr = [1, 2, 3];
2
3function somma(a, b) { return a + b; }
4console.log(somma(1, '1'));

Output di ESLint:

11:7   warning  'arr' is assigned a value but never used       no-unused-vars
23:10  warning  'somma' is defined but never used             no-unused-vars

Comandi utili per ESLint CLI

La CLI di ESLint offre diverse opzioni utili:

  • --fix: Corregge automaticamente i problemi.
  • --max-warnings: Imposta un limite massimo di warning prima di fallire.
  • --ignore-path: Specifica un file alternativo per escludere file o directory.

Come integrare ESLint nel proprio editor

Puoi integrare ESLint con Visual Studio Code utilizzando l'estensione ufficiale ESLint. Configura il file settings.json per abilitare il linting automatico al salvataggio:

1{
2  "editor.codeActionsOnSave": {
3    "source.fixAll.eslint": true
4  }
5}

Integrare ESLint nel proprio git workflow con un hook di pre-commit

Come visto per Prettier, puoi utilizzare un hook di pre-commit per eseguire ESLint automaticamente sui file modificati prima di ogni commit. Ecco uno script d’esempio per il file .git/hooks/pre-commit:

1#!/bin/sh
2echo "Eseguendo ESLint sui file modificati..."
3files=$(git diff --cached --name-only --diff-filter=ACM | grep '\.js\|\.ts$')
4
5if [ -n "$files" ]; then
6  echo "$files" | xargs npx eslint --fix
7  echo "$files" | xargs git add
8else
9  echo "Nessun file da controllare."
10fi
11
12exit 0

Nota: Questo script esegue ESLint sui file modificati e aggiunge automaticamente le correzioni allo staging. Tuttavia, se ci sono errori che non possono essere risolti, Git procederà comunque con il commit.

Combinare Prettier ed ESLint

Ora che abbiamo familiarizzato con Prettier ed ESLint, è giunto il momento di integrarli per sfruttare al meglio entrambi gli strumenti. Questo ci permetterà di ottenere un codice ben formattato e conforme alle regole di linting.

Per integrare Prettier con ESLint, dobbiamo aggiungere alcune dipendenze:

1npm install --save-dev eslint-config-prettier eslint-plugin-prettier

Cosa fanno queste dipendenze?

  • eslint-config-prettier: Disabilita le regole di ESLint che potrebbero confliggere con Prettier.
  • eslint-plugin-prettier: Aggiunge Prettier come regola di linting in ESLint, segnalando errori di formattazione.

Ecco come aggiornare la configurazione di ESLint per integrare Prettier:

1import pluginJs from "@eslint/js";
2import configPrettier from "eslint-config-prettier";
3import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
4import globals from "globals";
5
6/** @type {import('eslint').Linter.Config[]} */
7export default [
8  {
9    ignores: ["node_modules", "dist"], // Esclude directory dall'analisi
10  },
11  pluginJs.configs.recommended, // Regole raccomandate di ESLint
12  eslintPluginPrettierRecommended, // Plugin Prettier per ESLint
13  {
14    files: ["**/*.js"], // Specifica i file su cui applicare ESLint
15    languageOptions: { globals: globals.browser },
16    rules: {
17      ...configPrettier.rules, // Disabilita le regole in conflitto con Prettier
18      "no-unused-vars": "warn", // Avvisa per variabili inutilizzate
19      eqeqeq: "error", // Richiede l'uso di === invece di ==
20      quotes: ["error", "single"], // Enforce l'uso di apici singoli
21    },
22  },
23];

Cosa è cambiato?

  1. Nuovi import: Sono stati aggiunti eslint-config-prettier e eslint-plugin-prettier/recommended.
  2. Configurazione aggiornata:
    • La configurazione di Prettier è stata integrata direttamente in ESLint.
    • Le regole in conflitto tra ESLint e Prettier vengono disabilitate automaticamente.

Con questa configurazione, eseguendo un linting con ESLint, vedrai anche gli errori relativi alla formattazione di Prettier.

Miglioriamo l’hook di pre-commit

Per assicurarti che ogni commit contenga solo codice ben formattato e conforme, puoi aggiornare l’hook di pre-commit con una logica più robusta:

1#!/bin/sh
2
3echo "Eseguendo Prettier ed ESLint sui file modificati..."
4# Ottieni l'elenco dei file modificati
5files=$(git diff --cached --name-only --diff-filter=ACM | grep '\.js\|\.ts\|\.jsx\|\.tsx$')
6
7if [ -n "$files" ]; then
8  echo "Formattando i file con Prettier..."
9  echo "$files" | xargs npx prettier --write
10
11  if [ $? -ne 0 ]; then
12    echo "Prettier ha rilevato errori. Rimuovo i file dalla staging area..."
13    echo "$files" | xargs git restore --staged
14    exit 1
15  fi
16
17  echo "Aggiungo i file formattati allo staging..."
18  echo "$files" | xargs git add
19  echo "Validando i file con ESLint..."
20  echo "$files" | xargs npx eslint
21
22  if [ $? -ne 0 ]; then
23    echo "ESLint ha rilevato errori. Rimuovo i file dalla staging area..."
24    echo "$files" | xargs git restore --staged
25    exit 1
26  fi
27  echo "Tutti i controlli sono passati!"
28else
29  echo "Nessun file da controllare."
30fi
31
32exit 0

Cosa fa questo script?

  1. Prettier:
    • Formatta i file modificati.
    • Se Prettier rileva errori, rimuove i file dalla staging area e blocca il commit.
  2. ESLint:
    • Controlla i file per eventuali violazioni delle regole.
    • Se ci sono errori, rimuove i file dalla staging area e blocca il commit.

Giunti a questo punto possiamo tirare qualche conclusione…

Prettier ed ESLint sono strumenti potenti e indispensabili per mantenere il codice pulito, leggibile e conforme agli standard del team. Integrare questi tool permette di automatizzare gran parte del lavoro di formattazione e verifica, riducendo il tempo speso in attività ripetitive e migliorando la qualità complessiva del codice.

Grazie a una configurazione efficace e all'integrazione con Git e gli editor di testo, puoi garantire che ogni commit contenga solo codice ben formattato e privo di errori. La combinazione di Prettier ed ESLint offre una soluzione completa per gestire sia la formattazione che le regole di linting, favorendo un workflow più fluido e collaborativo.

Che tu stia lavorando in team o su un progetto personale, seguire queste best practice ti aiuterà a mantenere alta la qualità del codice, semplificando il processo di sviluppo e riducendo il rischio di errori. Ora che hai gli strumenti e la conoscenza per configurarli e integrarli, non ti resta che applicarli ai tuoi progetti per vedere la differenza!

Bonus: come funzionano ESLint e Prettier sotto al cofano

Come funziona Prettier

Prettier è un code formatter che si basa su un approccio deterministico: riceve in input un codice sorgente e lo trasforma in un output formattato seguendo regole predefinite.

  1. Parsing del codice: Prettier utilizza dei parser per analizzare il codice sorgente e trasformarlo in un AST (Abstract Syntax Tree). Un AST è una rappresentazione strutturata del codice che separa la sintassi dalle specifiche del linguaggio.
  2. AST Transformation: Una volta generato l'AST, Prettier non si preoccupa dello stile originale del codice. Invece, prende l'AST e lo "ricostruisce" applicando le sue regole di formattazione.
  3. Pretty Printing: Prettier converte l'AST formattato in codice sorgente leggibile, utilizzando il prisma di output (un sistema di calcolo delle lunghezze delle righe). Questo assicura che ogni riga sia conforme alla larghezza massima configurata (printWidth), spezzando il codice solo quando necessario.
  4. Output del codice: Infine, il codice formattato viene scritto nel file o mostrato a video. Prettier garantisce che l'output sia sempre deterministico: a parità di input e configurazione, l'output sarà identico.

Punti di forza del funzionamento di Prettier:

  • Non effettua l'analisi semantica: ignora il significato logico del codice e si concentra solo sullo stile.
  • Non richiede una configurazione complessa: le regole sono decise dal tool stesso, riducendo le discussioni tra i membri del team.

Come funziona ESLint

ESLint è un code linter che analizza il codice sorgente per individuare problemi e violazioni di regole. A differenza di Prettier, ESLint esegue sia un'analisi sintattica che semantica del codice.

  1. Parsing del codice: Come Prettier, ESLint utilizza dei parser per analizzare il codice sorgente e trasformarlo in un AST. Per JavaScript, il parser predefinito è Espree, basato su Acorn. Tuttavia, è possibile utilizzare parser alternativi come Babel-ESLint o @typescript-eslint/parser.
  2. Traversal dell'AST: ESLint attraversa l'AST nodo per nodo, applicando una serie di regole definite dall'utente o dai plugin installati. Ogni regola è associata a un'operazione specifica, come:
    • Controllare l'uso di variabili inutilizzate (no-unused-vars).
    • Verificare l'uso corretto degli operatori (eqeqeq).
    • Segnalare problemi di stile (indent, quotes).
  3. Analisi semantica: Durante il traversal, ESLint esegue controlli semantici utilizzando un sistema di scope analysis. Questo sistema identifica variabili, funzioni, parametri e altre entità nel codice, verificandone la validità e il corretto utilizzo.
  4. Emissione degli errori: Per ogni nodo dell'AST che viola una regola, ESLint genera un messaggio di errore o warning. Questi messaggi includono informazioni come:
    • Tipo di violazione.
    • Posizione del problema (riga e colonna).
    • Suggerimenti per risolvere l'errore.
  5. Fix automatico: Se una regola supporta il fix automatico, ESLint modifica direttamente il codice sorgente per correggere il problema (--fix). Tuttavia, non tutti i problemi possono essere risolti automaticamente, specialmente quelli legati alla logica del programma.

A questo punto è indubbio che la differenza tra i due tool è enorme, ma riepiloghiamole:

  • Focus:
    • Prettier: Formattazione del codice
    • ESLint: Linting (analisi di regole e best practice)
  • Parsing:
    • Prettier: Sintassi
    • ESLint: Sintassi e semantica
  • Configurazione:
    • Prettier: Minima
    • ESLint: Elevata personalizzazione
  • Correlazione:
    • Prettier: Tutte le regole sono fixabili
    • ESLint: Non tutte le regole supportano fix automatico
  • Ambito d’azione:
    • Prettier: Stile e leggibilità
    • ESLint: Logica, qualità del codice e aderenza agli standard

Integrazione tra Prettier ed ESLint

Quando Prettier ed ESLint sono integrati:

  1. Prettier si occupa della formattazione: Garantisce uno stile uniforme e leggibile.
  2. ESLint verifica il rispetto delle regole: Identifica problemi più complessi legati alla logica e alle best practice.
  3. Gestione dei conflitti: Grazie a eslint-config-prettier, le regole di ESLint che potrebbero interferire con la formattazione di Prettier vengono disabilitate automaticamente.

Questa visione tecnica ti consente di comprendere meglio cosa accade quando utilizzi questi strumenti, permettendoti di sfruttarli al massimo e, se necessario, personalizzarne il comportamento. Per ulteriori dettagli, puoi consultare le documentazioni di Prettier e ESLint.

Caricamento...

Diventiamo amici di penna? ✒️

Iscriviti alla newsletter per ricevere una mail ogni paio di settimane con le ultime novità, gli ultimi approfondimenti e gli ultimi corsi gratuiti puubblicati. Ogni tanto potrei scrivere qualcosa di commerciale, ma solo se mi autorizzi, altrimenti non ti disturberò oltre.

Se non ti piace la newsletter ti ricordo la community su Discord, dove puoi chiedere aiuto, fare domande e condividere le tue esperienze (ma soprattutto scambiare due meme con me). Ti aspetto!

Ho in previsione di mandarti una newsletter ogni due settimane e una commerciale quando capita.