Ejercicio: Trabajar con rutas

Completado

Como desarrollador de Tailwind Traders, está a punto de mejorar un programa mediante el módulo path de Node.js y la variable global __dirname. Esto permitirá que el programa busque y procese dinámicamente los archivos .json, independientemente de dónde se ejecute el programa.

Inclusión del módulo path

En la parte superior del archivo index.js, incluya el módulo path.

const path = require("path");

Uso del directorio actual

En el código index.js actual, se pasa la ubicación estática de la carpeta stores. Vamos a cambiar ese código para que use el valor __dirname en lugar de pasar un nombre de carpeta estática.

  1. En el método main, cree una variable para almacenar una ruta de acceso al directorio stores mediante la constante __dirname.

    async function main() {
      const salesDir = path.join(__dirname, "stores");
    
      const salesFiles = await findSalesFiles(salesDir);
      console.log(salesFiles);
    }
    
  2. Ejecute el programa desde la línea de comandos.

    node index.js
    

    Observe que la ruta de acceso que ahora se muestra para los archivos es la ruta de acceso completa del sistema, ya que la constante __dirname devuelve la ruta de acceso completa a la ubicación actual.

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

Rutas de combinación

En lugar de concatenar nombres de carpeta para crear una ruta de acceso donde realizar la búsqueda, cambiaremos el código para usar el método path.join. Posteriormente, este código puede funcionar en los sistemas operativos.

  1. Cambie el método findFiles para usar 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. Ejecute el programa desde la línea de comandos.

    node index.js
    

    La salida es la misma que en el paso anterior, si bien ahora el programa es más sólido porque usa path.join en lugar de concatenar cadenas.

Búsqueda de todos los archivos .json

En lugar de buscar solo los archivos sales.json, este programa necesita encontrar cualquier archivo con la extensión .json. Para ello, use el método path.extname a fin de comprobar la extensión de nombre de archivo.

  1. Ejecute el siguiente comando en el terminal para cambiar el nombre del archivo stores/201/sales.json a stores/sales/totals.json.

    mv stores/201/sales.json stores/201/totals.json
    
  2. En la función findSalesFiles, cambie la instrucción if para que compruebe únicamente la extensión de nombre de archivo.

    if (path.extname(item.name) === ".json") {
      results.push(`${folderName}/${item.name}`);
    }
    
  3. Ejecute el programa desde la línea de comandos.

    node index.js
    

    Ahora, la salida muestra todos los archivos .json que están en cualquiera de los directorios de id. de tienda.

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

Buen trabajo. Se ha usado el módulo path y la constante __dirname para que el programa sea mucho más sólido. En la siguiente sección, aprenderemos a crear directorios y a mover archivos entre ubicaciones.

¿Se ha bloqueado?

Si se ha bloqueado en algún momento de este ejercicio, aquí tiene el código completo. Quite todo en index.js y reemplácelo por esta solución.

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