Découverte de l'Api File System de Node.js
#1 Visite de la page web de l'Api File System
La page ci-dessous correspond au deuxième tuto de présentation de Node.js dédié à la découverte de l'Api File System
.
En septembre 2022, je travaille avec la version 16 de node.js. Vous avez la documentaion ici
. Je descends pour voir apparaître File System
. Je clique sur File System
.
Sur cette page (* extrait ci-dessous), je vois qu'il y a trois exemples en début de doc qui montrent les trois façons de travailler avec cette Api File system
😃.
Je vois que je peux travailler avec des promises, avec des callbacks, ça c'est asynchrone, et je vois que je peux travailler avec une Api synchrone.
Au début de ce tuto, on va programmer ces trois exemples pour tâter le terrain.
#2 Premier exemple I/O asynchrone avec des promises
Je clique sur Promise example
. Sur la droite du morceau de code de l'exemple, je vois un switch CJS / ESM
(* Voir image ci-dessous). CJS
veut dire CommonJS Module et ESM
veut dire ECMAScript Module. Ceci correspond aux deux standards différents qui sont supportés par Node.js pour la gestion des modules JavaScript. Node.js a commencé avec la gestion CommonJS et a ensuite ajouté la gestion ECMAScript.
Ci-dessous, je vais faire un premier exemple en CommonJS. Je vois que dans ce cas l'exemple propose d'utiliser une fonction auto-invoquée (IIFE Immediately Invoked Function Expression). En argument de l'appel, je vais changer pour mettre ./hello.txt
. Je crée ce fichier et j'exécute. Je vois que le fichier ./hello.txt
est supprimé.
Maintenant, je vais faire un essai en ECMAScript. Là à priori, je n'ai plus besoin d'une IIFE et je n'ai même pas besoin d'encapsuler mes await
dans une fonction déclarée avec async
, puisque je suis dans un module JavaScript.
Quand j'exécute ce morceau de code, j'ai un problème (* voir ci-dessous). A priori, il faut que j'ajoute "type" : "module"
dans le fichier package.json
. Il va donc falloir que je crée ce fichier package.json
et je vais le faire en faisant un npm init -y
puis je rajoute l'info en question. (* docs.npmjs.com)
J'exécute et je vérifie que ça fonctionne correctement.
#3 Deuxième exemple I/O asynchrone avec des callbacks
Maintenant, je vais faire le deuxième exemple. Au niveau des modules, je vais travailler directement en ECMAScript en utilisant les callbacks. Evidemment l'inconvénient avec les callbacks est toujours le même. Si vous avez plusieurs appels à faire, vous allez tomber dans l'éternel problème du callback hell.
#4 Troisième exemple I/O synchrone
Le synchrone, c'est toujours syntaxiquement faisable. Tout dépend de ce que vous faites. Si certains traitements sont trop longs, alors votre application sera bloquée 😬 pendant la durée de ces traitements. Ce n'est pas vraiment conseillé et ce n'est pas dans l'esprit Node.js qui justement vous apporte l'asynchrone. Cependant, cette possibilité est présente.
En tout cas, c'est assez simple de s'y retrouver, car pour un appel synchrone, c'est le même nom qu'en asynchrone avec un Sync
de concaténé à la fin de chaque méthode de l'Api. Vous voyez qu'ici, on a concaténé Sync
à unlink
pour faire unlinkSync
.
#5 Donc on va travailler avec les promises
Maintenant que j'ai fait ces trois exemples, je vais choisir de travailler avec les promises. C'est un choix que j'aurais pu faire directement, mais disons que ça vaut toujours la peine de farfouiller dans la doc.
Maintenant, dans la doc, je m'intéresse à Promise Api
. Je descends un peu dans la doc, et je vois une classe fileHandle
. Si je regarde rapidement les méthodes qui sont proposées, je me rends compte qu'avec ça, je travaille uniquement sur les fichiers. Je n'ai pas accès à des fonctionnalités de système de fichiers.
Si je clique sur close
, c'est là que je vois le rôle du open
. C'est original.🙃
Dans l'exemple ci-dessous, un open
me renvoie une sorte de descripteur de fichier filehandle
. Avec ce descripteur de fichier, j'ai accès à des méthodes. Par exemple, je peux faire un filehandle.read()
. Si je parcours la classe, je vois que je peux faire à priori toutes les manips nécessaires sur un fichier. Par contre, il faut penser à fermer le fichier, c'est ce qui est fait dans le programme ci-dessous avec le filehandle?.close()
. Le close
sera appelé grâce au finally
que la promise soit résolue ou rompue. Le point d'interrogation est un ternaire. Le .close()
ne sera appelé que si filehandle
est évalué à true
.
Cette classe FileHandle
fait penser à la librairie standard C sous Unix (* Année 1990), sauf que là, on est quand même asynchrone. On peut se mettre sur un open
et faire F12
pour atteindre la définition et on a accès à toute la spéc de fs/promises
en typescript (* menu Atteindre / Atteindre la définition).
Si je continue de descendre dans la doc, je vois maintenant toute une liste de méthodes avec lesquelles je peux travailler sur le système de fichier et aussi sur les fichiers.
Je vais faire un exemple dans lequel je vais :
- Lire le contenu du répertoire courant.
- Tester si le fichier
package.json
existe. - S'il existe alors le lire puis l'afficher à l'écran.
Utiliser cette liste d'appel comme on vient de le faire dans cet exemple me parait être la meilleure façon d'utiliser l'Api File System
pour les besoins courants.
Si vous débutez, je vous conseille de vous intéresser aussi à l'Api Path et à l'Api Process qui sont des utilitaires incontournables, lorsque l'on programme sous Node.js.