Du code bien formaté sans effort avec husky et lint-staged
Par Maxime Bréhin • Publié le 6 sept. 2021

Mise à jour le 29 novembre 2022, 12:00

Les règles de mise en forme du code sont souvent source de conflit au sein des équipes. N’avez-vous jamais été témoin d’une discussion houleuse sur l’indentation ? (2 espaces, 4 espaces, 1 tabulation ?) Peu importe l’issue du débat, cela apporte peu à la qualité du code produit et génère une perte de temps en conflits et arbitrages inutiles du code.

L’uniformisation des outils et éditeurs permet de palier à ce type de problème. Mais si l’outillage fonctionne mal ? Si un membre de l’équipe refuse une partie de l’outillage ? Si cette personne préfère son éditeur à celui proposé à l’équipe, par exemple Nano contre VSCode ? Imposer une solution semble malvenu.

Pour plaire à tout le monde tout en garantissant la bonne application du formatage, on peut alors utiliser les hooks Git via husky pour exécuter en pre-commit l’outillage de mise en forme et d’analyse statique (autrement appelé linter).

Pour bien faire les choses, nous voulons que seuls les ajouts et modifications soient analysés et reformatés. Pour cela, nous allons utiliser le module npm lint-staged.

Vous préférez une vidéo ?

Si vous êtes du genre à préférer regarder que lire pour apprendre, on a pensé à vous :

Principes de fonctionnement de lint-staged

On ne souhaite analyser que le travail stagé (ajouté à Git avec git add …, mais pas encore commité), et au sein de ça, uniquement des fichiers spécifiques.

Lint-staged est conçu pour n’examiner que le travail stagé. En revanche, il nous incombe de lui dire quels fichiers traiter et avec quels outils. Pour cela, nous renseignons nos règles sous forme de motifs glob dans un fichier de configuration qui peut prendre plusieurs formats. Chez Delicious Insights, on a tendance à préférer les formats .js, souvent plus souples et qui permettent les commentaires et une configuration dynamique. On renseignera donc notre configuration dans un fichier lint-staged.config.js.

On peut ainsi travailler dans un projet multi-technos et demander l’application de règles différentes par cet unique outil 🤩 !

Mise en place

La procédure de mise en place de husky est décrite dans notre article « Gérer facilement les hooks Git avec husky ». Concentrons-nous ici sur son intégration avec lint-staged.

Comme pour tout module utile lors du développement du projet, ça s’installe comme ceci :

npm install --save-dev lint-staged

On configure dans le fichier lint-staged.config.js l’appel aux outils souhaités :

module.exports = {
  '<formats 1>': '<commandes 1>',
  '<formats 2>': '<commandes 2>',
}

Et on fait en sorte que ça soit appelé lors du pre-commit :

npx husky add .husky/pre-commit "npx --no-install lint-staged"

Cas classique d’utilisation : Prettier et ESLint

Ces deux outils très populaires dans l’univers du développement JavaScript et web vont nous permettre d’analyser le code (ESLint) et de le formater automatiquement (Prettier). Ils sont d’ailleurs cités en exemple dans la documentation de lint-staged.

Si ces outils ne sont pas déjà présents dans votre projet, il vous suffit de les installer, ça ne prendra qu’un instant :

# On couple ESLint à la convention StandardJS qu’on adore !
# On ajoute aussi la passerelle ESLint-Prettier pour éviter qu’ESLint
# couine sur des aspects de formatage que Prettier va de toutes façons régler.
npm install --save-dev eslint standard prettier eslint-config-prettier eslint-plugin-prettier

# Une fois installé, ESLint vous propose un assistant de configuration
# qui créera un fichier `.eslintrc.js` à la racine du projet.
npx eslint --init

✔ How would you like to use ESLint? · style
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · none
✔ Does your project use TypeScript? · No / Yes
✔ Where does your code run? · browser
✔ How would you like to define a style for your project? · guide
✔ Which style guide do you want to follow? · standard
✔ What format do you want your config file to be in? · JavaScript

Pour Prettier, une configuration par défaut existe mais vous pouvez choisir de spécifier vos préférences dans le fichier prettier.config.js à la racine du projet également :

module.exports = {
  arrowParens: 'always',
  jsxSingleQuote: true,
  semi: false,
  singleQuote: true,
  trailingComma: 'es5',
}

Il ne reste qu’une chose à faire : dire à lint-staged qu’on veut automatiser le recours à ces outils en pre-commit. On va donc éditer notre fichier lint-staged.config.js et renseigner une règle assez large (libre à vous d’ajouter/modifier ça pour y mettre vos règles) :

module.exports = {
  '*.{js,json,md,mdx,html,css,scss}': 'prettier --write',
}

Et voilà, il n’y a plus qu’à voir ce que ça donne !

Prenons l’exemple de code JavaScript et CSS mal formatés. Tout ça est ajouté à Git en premier lieu avec un git add …, et au moment du commit on va voir lint-staged qui donne la main à Prettier pour reformater tout ça avant de finaliser le commit.

Pour aller plus loin 🐱‍🏍

Vous pouvez combiner cette automatisation avec d’autres utilitaires pour gagner en qualité et en confort de développement :

Découvrez nos cours vidéo ! 🖥

Nos cours vidéo sont un complément idéal et bon marché à nos articles techniques et formations présentielles. Autour de Git, de JavaScript et d’autres sujets, retrouvez des contenus de très grande qualité à des prix abordables, spécialement conçus pour lever vos plus gros points de blocage.