How to Find Files By Extension, Name, or Pattern in Node.js

Robin
June 10, 2022

You can easily read directories and sub-directories to get all files in Node.js but sometimes you might need to find files by their names, extensions, or a pattern in NodeJS. It might sound difficult but fortunately, it's not.

You can easily search into a directory (folder) with Node.js for a specific file or files. For that, you can use the filename, file extension, or a regular expression.

In this article, I will walk you through all the methods to find files in a directory and its sub-directories with pure JavaScript and an external package.

How to Find Files in Node.js

You can search for files in Node.js using the following methods:

  • First, you have to read the directory using readdir() method from the Node fs module.
  • Loop over the files returned from the readdir() method.
  • Find the extension of each file using path.extname() method and check if it matches the extension that you are searching for.
  • You can find the file name with the path.parse() method of each file and compare it with the provided name.
  • There is an external package called glob to find files using a pattern like a regular expression.
  • Final Result: Search filter in React

Let's see all the methods in detail step by step.

How to Find Files By Extension, Name or Pattern in Node.js

Find Files By Extension in Node.js

To get files by using extensions, I have created a function called findByExtension() with two parameters. The first parameter is the directory name and the second parameter is the file extension.

First, we have to get all the files from the provided directory using readdir() method. You can import this method from the fs module which is a Node.js core module. This method will return all the files and sub-directories available inside the targeted folder.

In the next step, you have to loop over the files you got from the readdir() method and check which file matches your target extension type.

          const { readdir } = require('fs/promises');
const path = require('path');

const findByExtension = async (dir, ext) => {
    const matchedFiles = [];

    const files = await readdir(dir);

    for (const file of files) {
        // Method 1:
        const fileExt = path.extname(file);

        if (fileExt === `.${ext}`) {
            matchedFiles.push(file);
        }
    }

    return matchedFiles;
};
        

In the above code, you can see I am doing the same. Getting all the files and looping over them using for...of loop. Now, you can check the extension type in two ways:

  • Method 1: Get the extension from each file with path.extname() method and match it with the target extension type.
  • Method 2: You can compare the target extension with every file name using endsWith() string method.

Note: The readdir() method returns a promise therefore, you have to use async and await to handle that promise.

In the above example, I have used the first method. For any file that matches our target extension, I am pushing that file name in the matchedFiles array. Finally, I return this array at the end of the function.

Method 1:

          findByExtension('./uploads', 'js').then((files) => {
    console.log(files);
});

// [ "home.js", "main.js"]
        

Now, I am calling the findByExtension() function with a directory name and extension type. Because it is an async function, I have to use then to get all the returned array. You can use a self-executing function in javascript If you don't want to call the function manually.

Method 2:

          const { readdir } = require('fs/promises');

const findByExtension = async (dir, ext) => {
    const matchedFiles = [];

    const files = await readdir(dir);

    for (const file of files) {
        // Method 2:
        if (file.endsWith(`.${ext}`)) {
            matchedFiles.push(file);
        }
    }

    return matchedFiles;
};
        

In this method, I am checking if the file name ends with the target extension type using the endsWith() method. If this method returns true, I will push the file name into the matchedFiles array.

Note: You can only get matching file from the upload directory. If there are sub-directories inside upload directory and you also want to check files from those directories then we have a complete guide to get files recursively from a directory using NodeJS.

Search Files By Name in Node.js

To search for files by name, you have to follow the same process to get all the files from a directory. Then you can loop over those files to check if the file name matches the name you are looking for.

The only difference, in this case, is how we compare the file names. You can compare those names in 3 ways:

  • Method 1: Get the file name of each file using path.parse() method. Then compare it with the provided name using the === comparison operator.
  • Method 2: Check if the file name starts with the provided name using the startsWith() method in javascript.
  • Method 3: Check if the file name includes the provided name with the includes() method in javascript.

Let's learn about all these methods with examples.

Method 1:

          const path = require('path');
const { readdir } = require('fs/promises');

const findByName = async (dir, name) => {
    const matchedFiles = [];

    const files = await readdir(dir);

    for (const file of files) {
        // Method 1:
        const filename = path.parse(file).name;

        if (filename === name) {
            matchedFiles.push(file);
        }
    }

    return matchedFiles;
};
        

You can get the filename of each file inside the for loop using path.parse() method. Then you can check if this name is equal (===) to the name you are looking for.

One thing you should keep in mind while using this technique is that you have to provide the exact filename. It can not check for partially matching names.

          findByName('./uploads', 'home').then((files) => {
    console.log(files);
});

// [ "home.js", "home.css"]
        

But if you don't want to use exact names while searching, you can use the other two methods.

Also Read: Easy Ways to Download Any File From Node.js Server Using Express

Method 2:

          const { readdir } = require('fs/promises');

const findByName = async (dir, name) => {
    const matchedFiles = [];

    const files = await readdir(dir);

    for (const file of files) {
        // Method 2:
        if (file.startsWith(name)) {
            matchedFiles.push(file);
        }
    }

    return matchedFiles;
};
        

In this method, I am checking if the file starts with the provided name with the startsWith() method. With this method, you can find all the files that start with a piece of string.

You don't need the exact name of a file. You have to provide part from the start.

          findByName('./uploads', 'ho').then((files) => {
    console.log(files);
});

// [ "home.js", "home.css"]
        

If you want to find files with partially matching names from any part of the file, you can use our next method.

Method 3:

          const { readdir } = require('fs/promises');
const path = require('path');

const findByName = async (dir, name) => {
    const matchedFiles = [];

    const files = await readdir(dir);

    for (const file of files) {
        // Method 3:
        if (file.includes(name)) {
            matchedFiles.push(file);
        }
    }

    return matchedFiles;
};
        

Instead of checking if the file starts with a piece of string, you can check if the file includes that string with the includes() method. In this way, you will get all the files that contain your search query.

          findByName('./uploads', 'ome').then((files) => {
    console.log(files);
});

// [ "home.js", "home.css"]
        

You can see when I am calling the findByName() function with a random string in the second parameter, it is returning files that contain the string.

Get Files By Matching Pattern Using Glob in Node.js

So far we have seen how to find files using javascript. We wrote functions according to our requirements. If you have a complex directory structure with many directories and sub-directories, it will be a good idea to use an external package.

Now I will show you how you can use the glob package to search for files. With this package, you can find files from multiple directories and sub-directories using some pattern like a regular expression.

First, initialize a Node.js project by creating the package.json file in the root of your project folder. You have to create this file using the following command:

          npm init -y
        

In the next step, you have to install the glob package in your project. You can install this package with this command:

          npm install --save glob
        

Now you can use this package in your project. I have created a file called glob.js with the following code in it. You can give this file any name you want.

The glob() function takes 2 parameters. The first parameter is the pattern that it will use to find files and the second parameter is the callback function.

In the callback function, you get 2 things i.e. error and matched files. You can check if there is any error and you will get the files that match the pattern.

          // glob.js file

const glob = require('glob');

glob('uploads/*.js', (err, files) => {
    if (err) {
        console.log(err);
        return;
    }

    console.log(files);
});
        

In this example, I am calling the glob() function with the "uploads/*.js" pattern. It will return all files that end with .js inside the uploads directory. But it will not return files from any sub-directories present inside the uploads directory.

If you want to get all files from a directory including its sub-directories, you have to use a different pattern. There are different types of patterns that you can use with the glob package.

Also Read: Perfect Ways to Serve Static Files in Express and Node.js

List of Common Glob Patterns

You can create a complex pattern for your search if you need to use different characters. You can learn more about those by following the official documentation of this package.

I will show you some frequently used patterns that you can use in your project. These patterns are:

  • *.extension - This pattern will return all the files present in the current directory. For example: "*.js", "*.png", "*.json".
  • directory/*.extension - This pattern will return files present in the given directory without the sub-directories. For example: "uploads/*.js", "uploads/*.css", "images/*.jpg".
  • directory/**/*.extension - This pattern will give all files from the given directory including the files from its sub-directories. For example: "uploads/**/*.js", "uploads/**/*.css", "images/**/*.jpg".
  • **/*.extension - It will give all the files from the current directory and its subdirectories. For example: "**/*.js", "**/*.html", "**/*.json".
  • */**/*.extension - If you want to find files only from sub-directories present in the current directory, you can use this pattern. For example: "*/**/*.js", "*/**/*.html", "*/**/*.json"

Conclusion

Knowing how to work with files is an important skill for every developer. You can get all files from a directory or you can search any specific types of files in Nodejs. This is what you have learned in this article.

I have shown you different methods to find files from a directory and sub-directories. You can use filenames, extensions, or any pattern to identify file types.

Use fs and path modules to get your files or you can install the glob package to apply patterns. I tried to give you everything related to this topic. I hope you will be able to find files in Node.js by using names, extensions, or patterns in your project.

Related Posts