Exercício – Trabalhar com caminhos

Concluído

Como desenvolvedor na Tailwind Traders, você está prestes a aprimorar um programa usando o módulo Node.js path e __dirname a variável global. Isso permitirá que o programa localize e processe dinamicamente quaisquer arquivos .json, independentemente de onde o programa é executado.

Inclua o módulo path

Na parte superior do arquivo .js índice existente, inclua o módulo de caminho.

const path = require("path");

Utilize o diretório atual

No código index.js atual, está a transmitir a localização estática da pasta stores. Vamos alterar esse código para usar o __dirname valor em vez de passar um nome de pasta estática.

  1. No método main, crie uma variável para armazenar um caminho para o diretório stores ao utilizar a constante __dirname.

    async function main() {
      const salesDir = path.join(__dirname, "stores");
    
      const salesFiles = await findSalesFiles(salesDir);
      console.log(salesFiles);
    }
    
  2. Execute o programa a partir da linha de comandos.

    node index.js
    

    Observe que o caminho listado agora para os arquivos é o caminho completo do sistema, porque a __dirname constante retorna o caminho completo para o local atual.

    [
       '/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'
    ]
    

Associe caminhos

Em vez de concatenar nomes de pastas para criar um novo caminho para pesquisar, você altera o código para usar o path.join método. Esse código pode então funcionar em todos os sistemas operacionais.

  1. Altere o método findFiles para utilizar path.join.

    // 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. Execute o programa a partir da linha de comandos.

    node index.js
    

    A saída é a mesma da etapa anterior, mas o programa agora é mais robusto porque usa path.join em vez de concatenar strings.

Encontre todos os ficheiros .json

Em vez de procurar apenas ficheiros sales.json, o programa precisa de procurar qualquer ficheiro com uma extensão .json. Para fazer isso, use o path.extname método para verificar a extensão do nome do arquivo.

  1. Execute o seguinte comando no terminal para mudar o nome do ficheiro stores/201/sales.json para stores/sales/totals.json.

    mv stores/201/sales.json stores/201/totals.json
    
  2. findSalesFiles Na função, altere a instrução para verificar apenas a if extensão do nome do arquivo.

    if (path.extname(item.name) === ".json") {
      results.push(`${folderName}/${item.name}`);
    }
    
  3. Execute o programa a partir da linha de comandos.

    node index.js
    

    O resultado mostra agora todos os ficheiros .json em qualquer um dos diretórios de ID de loja.

    [
       '/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'
    ]
    

Parabéns! Utilizou o módulo path e a constante __dirname para tornar o programa muito mais robusto. Na próxima secção, irá aprender a criar diretórios e a mover ficheiros entre localizações.

Está com dificuldades?

Se teve problemas em algum momento deste exercício, eis o código completo. Remova tudo em index.js e substitua por esta solução.

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();