Oefening: werken met paden

Voltooid

Als ontwikkelaar bij Tailwind Traders staat u op het punt om een programma te verbeteren met behulp van de Padmodule node.js en __dirname de globale variabele. Hierdoor kan het programma alle JSON-bestanden dynamisch vinden en verwerken, ongeacht waar het programma vandaan wordt uitgevoerd.

De path-module opnemen

Neem boven aan het bestaande index.js-bestand de padmodule op.

const path = require("path");

De huidige directory gebruiken

In de huidige index.js-code geeft u de statische locatie van de stores-map door. We gaan die code wijzigen om de __dirname waarde te gebruiken in plaats van een statische mapnaam door te geven.

  1. Maak in de main-methode een variabele om een pad naar de stores-directory op te slaan met behulp van de __dirname-constante.

    async function main() {
      const salesDir = path.join(__dirname, "stores");
    
      const salesFiles = await findSalesFiles(salesDir);
      console.log(salesFiles);
    }
    
  2. Voer het programma uit vanaf de opdrachtregel.

    node index.js
    

    U ziet dat het pad dat nu wordt vermeld voor de bestanden het volledige systeempad is, omdat de __dirname constante het volledige pad naar de huidige locatie retourneert.

    [
       '/workspaces/node-essentials/nodejs-files/stores/201/sales.json',
       '/workspaces/node-essentials/nodejs-files/stores/202/sales.json',
       '/workspaces/node-essentials/nodejs-files/stores/203/sales.json',
       '/workspaces/node-essentials/nodejs-files/stores/204/sales.json'
    ]
    

Join-paden

In plaats van mapnamen samen te voegen om een nieuw pad te maken om te zoeken, wijzigt u de code om de path.join methode te gebruiken. Deze code kan vervolgens in verschillende besturingssystemen werken.

  1. Wijzig de methode findFiles om path.join te gebruiken.

    // previous code - with string concatentation
    const resultsReturned = await findSalesFiles(`${folderName}/${item.name}`);
    
    // current code - with path.join
    const resultsReturned = await findSalesFiles(path.join(folderName,item.name));
    
  2. Voer het programma uit vanaf de opdrachtregel.

    node index.js
    

    De uitvoer is hetzelfde als de vorige stap, maar het programma is nu robuuster omdat het gebruikmaakt path.join van tekenreeksen in plaats van tekenreeksen samen te voegen.

Alle .json-bestanden zoeken

In plaats van alleen sales.json-bestanden te zoeken moet het programma alle bestanden met een .json-extensie zoeken. Hiervoor gebruikt u de methode om de path.extname bestandsnaamextensie te controleren.

  1. Voer de volgende opdracht uit in de terminal om de naam van het stores/201/sales.json-bestand te wijzigen in stores/sales/totals.json.

    mv stores/201/sales.json stores/201/totals.json
    
  2. Wijzig in de findSalesFiles functie de if instructie om alleen de bestandsnaamextensie te controleren.

    if (path.extname(item.name) === ".json") {
      results.push(`${folderName}/${item.name}`);
    }
    
  3. Voer het programma uit vanaf de opdrachtregel.

    node index.js
    

    Bij de uitvoer ziet u nu alle .json-bestanden in alle winkel-id-directory's.

    [
       '/home/username/node-essentials/nodejs-files/stores/201/totals.json',
       '/home/username/node-essentials/nodejs-files/stores/202/sales.json',
       '/home/username/node-essentials/nodejs-files/stores/203/sales.json',
       '/home/username/node-essentials/nodejs-files/stores/204/sales.json'
    ]
    

Helemaal goed! U hebt de path-module en de __dirname-constante gebruikt om het programma veel robuuster te maken. In de volgende sectie leert u directory's te maken en bestanden tussen locaties te verplaatsen.

Vastgelopen?

Als u op een bepaald punt in deze oefening niet meer verder kunt, vindt u hier de voltooide code. Verwijder alles in index.js en vervang dit door deze oplossing.

const fs = require("fs").promises;
const path = require("path");

async function findSalesFiles(folderName) {

  // (1) Add an array at the top, to hold the paths to all the sales files that the program finds.
  let results = [];

  // (2) Read the currentFolder with the `readdir` method. 
  const items = await fs.readdir(folderName, { withFileTypes: true });

  // (3) Add a block to loop over each item returned from the `readdir` method using the asynchronous `for...of` loop. 
  for (const item of items) {

    // (4) Add an `if` statement to determine if the item is a file or a directory. 
    if (item.isDirectory()) {

      // (5) If the item is a directory,  recursively call the function `findSalesFiles` again, passing in the path to the item. 
      const resultsReturned = await findSalesFiles(path.join(folderName, item.name));
      results = results.concat(resultsReturned);
    } else {
      // (6) If it's not a directory, add a check to make sure the item name matches *sales.json*.
      if (path.extname(item.name) === ".json")
        results.push(`${folderName}/${item.name}`);
    }
  }


  return results;
}

async function main() {
  const salesDir = path.join(__dirname, "stores");

  // find paths to all the sales files
  const salesFiles = await findSalesFiles(salesDir);
  console.log(salesFiles);
}

main();