Search code examples
node.jsblobwildcardfsfile-exists

Fastest way to see if there any file matching a blob in the tree


I just want to know IF there is ANY file with a given extension in the tree. I'm using node.

For example, I need to know if there is any .jsx file in the src/scripts directory. Even better if we could do that using blobs/wildecards, like '**/*.jsx'.

I could actually use a blob that would return all the matching files, or I could use some recursion...but, once I just need to know IF there is ANY file matching that pattern, I think there could be a better (more performant) way to do that.

Any suggestion?


Solution

  • Well, I managed to find a way out. I did open an issue in the glob repository: https://github.com/isaacs/node-glob/issues/356

    But, meanwhile, we can use their API with the eventEmitter to abort in the first match.

    function thereIsAnyFileMatching (pattern, options = {}) {
      return new Promise((resolve, reject) => {
        let Glob = glob.Glob
        let g = new Glob(pattern, options)
        g.on('match', function(file){
          g.abort() // found
          resolve(true)
        })
        g.on('end', function(){
          resolve(false)
        })
        g.on('error', function(err){
          reject(err)
        })
      })
    }
    

    The only IMPORTANT problem here is that, when aborted, the "aborted" state is shared. So, if you call it many times in a row, the concurrency may give you false positives, or even worst, never resolving (the "end" even never gets triggered). So...not a straight solution if you have to deal with concurrency.

    The way I turned around concurrency was by using "{...,...}" patterns.
    So, for example: {**/*.js,**/*.jsx}
    In this case, it's just ONE instance of glob being executed looking for any of the patterns. But again...there is a problem :p
    It will not tell you WHICH of the patterns matched in the "match" event. You just have to validate it yourself (by checking the file extension, for example).

    I hope this helps someone some day :)