Next.js & Typescript + ESLint

Publié il y a 11 mois~4 min

En tant que développeur web, difficile de ne pas entendre parler de Typescript... En tant que surcouche à Javascript, il permet de renforcer la robustesse de notre code tout en participant à sa documentation.

Next.js permet de démarrer un projet rapidement avec Typescript, mais qu'en est-il pour un projet existant ?

Sur la base d'un projet Next.js, nous allons voir comment configurer Typescript & ESLint en vue d'une migration Typescript !

Pré-requis

  1. Node.js (>= 10.13)
  2. Un projet Next.js (existant ou généré via npx create-next-app)

Ce site web a servi de base à cet article, n'hésitez donc pas à vous référer au code source pour plus de détails !

Typescript

Avec Next.js l'ajout de Typescript est grandement facilité, et pour commencer il nous suffira donc de créer un fichier tsconfig.json à la racine du projet. Sans oublier bien sûr l'ajout des packages de base :

1npm install -D typescript @types/react @types/node

Il suffira alors de (re)lancer le serveur de développement (next dev) : Next.js se chargera alors de compléter le fichier tsconfig.json et de créer le fichier de déclarations next-env.d.ts, nécessaire à la bonne prise en charge des types utiles au framework.

Pour finir, et pour bénéficier d'une expérience Typescript plus complète, il pourra être intéressant d'ajuster le fichier tsconfig.json, en passant la clé strict à true.

ESLint

Un linter a plusieurs objectifs : normaliser le code (guillemets, ...), et surtout détecter les erreurs liées à la syntaxe. Une mauvaise déclaration de variable, une erreur d'import, ... Toutes ces erreurs que nous sommes tous amenés à faire, un jour ou l'autre... :man-facepalming:.

Et c'est donc là qu'intervient ESLint : véritable béquille du développeur, cet outil est aujourd'hui devenu un incontournable dans tous les projets Javascript, et si ce n'est pas déjà le cas je ne peux que vous recommander de l'installer !

Voici un exemple de commande d'installation d'ESLint, avec les plugins principaux utilisés en environnement React :

1npm install -D eslint eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y

Pour une utilisation avec Typescript, il faudra compléter avec les paquets dédiés :

1npm install -D @typescript-eslint/parser @typescript-eslint/eslint-plugin

Reste maintenant à configurer notre linter, sans oublier de prendre en compte la nécessaire cohabitation de fichiers Javascript et Typescript, ne serait-ce que le temps de la migration : on ajustera donc notre configuration pour qu'elle puisse s'adapter à chaque type de fichier de notre codebase, via un fichier .eslintrc.json placé à la racine du projet :

1{
2 "settings": {
3 "react": {
4 "version": "detect"
5 }
6 },
7 "env": {
8 "browser": true,
9 "es2021": true,
10 "node": true
11 },
12 "extends": [
13 "eslint:recommended",
14 "plugin:react/recommended",
15 "plugin:react-hooks/recommended",
16 "plugin:jsx-a11y/recommended"
17 ],
18 "parserOptions": {
19 "ecmaFeatures": {
20 "jsx": true
21 },
22 "ecmaVersion": 12,
23 "sourceType": "module"
24 },
25 "plugins": [
26 "react",
27 "jsx-a11y"
28 ],
29 "rules": {
30 "react/react-in-jsx-scope": "off",
31 "jsx-a11y/anchor-is-valid": "off"
32 },
33 "overrides": [
34 {
35 "files": ["**/*.ts", "**/*.tsx"],
36 "parser": "@typescript-eslint/parser",
37 "plugins": [
38 "@typescript-eslint"
39 ],
40 "extends": [
41 "plugin:@typescript-eslint/recommended"
42 ],
43 "rules": {
44 "react/prop-types": "off",
45 "@typescript-eslint/no-unused-vars": "error",
46 "@typescript-eslint/explicit-function-return-type": [
47 "warn",
48 {
49 "allowExpressions": true,
50 "allowConciseArrowFunctionExpressionsStartingWithVoid": true
51 }
52 ],
53 "@typescript-eslint/ban-ts-comment": "warn"
54 }
55 }
56 ]
57}

Outre les déclarations liées à nos plugins, on notera la présence de la clé overrides : comme son nom l'indique, elle permet de définir une configuration complémentaire, spécifique à un type de fichier.

Notre configuration liée à Typescript prendra donc place à cet endroit, avec quelques règles spécifiques selon le besoin.

Pour finir, ne pas oublier d'indiquer à ESLint les fichiers à ignorer, comme ceux des node_modules par exemple, avec un fichier .eslintignore (placé lui aussi à la racine) :

1.next
2node_modules

Bonus: Prettier

Nous apprécions tous de lire un fichier clair et formaté de façon uniforme, que l'on soit seul ou en équipe... Il suffit de revenir sur un fichier après quelques mois d'absence pour s'en rendre compte ! 👀

C'est là qu'intervient Prettier, en parfait complément à l'incontournable ESLint. Avec cet outil en plus, plus besoin de réfléchir aux tabulations, retours à la ligne, ... Prettier se charge de tout ! :robot_face:

Pour l'installer, rien de plus simple :

1npm install -D prettier eslint-plugin-prettier eslint-config-prettier

On pourra ensuite préciser nos préférences de formatage via un fichier .prettierrc.json, placé à la racine de notre projet :

1{
2 "semi": false,
3 "trailingComma": "es5",
4 "singleQuote": true,
5 "printWidth": 85,
6 "tabWidth": 2,
7 "useTabs": false
8}

Et enfin, on pourra optimiser le parsing de Prettier en ajoutant un fichier .prettierignore, toujours à la racine de notre projet :

1.next
2node_modules
3package-lock.json
4public

Pour finir, et pour faire en sorte que Prettier et ESLint fonctionnent parfaitement ensemble, on ajustera légèrement notre fichier .eslintrc.json :

1{
2 // ...
3 "extends": [
4 // ...
5 "plugin:prettier/recommended"
6 ],
7 // ...
8}

Désormais ESLint s'exécutera automatiquement avec Prettier, nous remontant dans la console l'ensemble des erreurs de syntaxe et/ou de formatage.

Pour parfaire cette configuration, vous pourrez aussi installer l'extension Prettier dans votre IDE, afin, par exemple, de formatter automatiquement à l'enregistrement ! 🤓

🎉

Et voilà ! Notre projet est maintenant prêt pour sa migration Typescript ! Avec ESLint (et Prettier), c'est la garantie d'une expérience de développement optimale et d'un code de qualité ! Il ne reste désormais plus qu'à organiser notre migration en fonction des spécificités de notre projet, pour profiter ensuite de tous les avantages de Typescript : robustesse, maintenabilité,... 💻