close

Découverte de l'Api File System de Node.js

#1 Visite de la page web de l'Api File System open

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.

Sur Google, je tape Node fr et je vais sur nodejs.org/fr/. Puis je clique sur DOCS. Puis sur la version LTS (* Long-Term Support) qui pour moi est la V16.17.0 Api LTS en septembre 2022. 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 😃.

Trois manières de travailler avec l'Api Node.js

Je vois que je peux travailler avec des promises, avec des callbacks ça c'est asynchrone et je vois que je peux travailler avec des appels à l'Api qui sont synchrones.

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 open

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.

CommonJS ou ECMAScript module

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é (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 en fait 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)

Travailler avec les modules ECMAScript
Ajouter type=module dans package.json

J'exécute et je vérifie que ça fonctionne correctement.

#3 Deuxième exemple I/O asynchrone avec des callbacks open

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 open

Le synchrone c'est toujours syntaxiquement faisable. Tout dépend de ce que vous faîtes. 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 open

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.🙃

L'api promise

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.

La suite de l'api fspromises

Je vais faire un exemple dans lequel je vais :

  1. Lire le contenu du répertoire courant.
  2. Tester si le fichier package.json existe.
  3. S'il existe alors le lire puis l'afficher à l'écran.
Résultat de l'exécution
Résultat de l'exécution de test-promise.js

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ébute 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.