node.js glob pattern for excluding multiple files

node.jsGlob

node.js Problem Overview


I'm using the npm module node-glob.

This snippet returns recursively all files in the current working directory.

var glob = require('glob');
glob('**/*', function(err, files) {
    console.log(files);
});

sample output:

[ 'index.html', 'js', 'js/app.js', 'js/lib.js' ]

I want to exclude index.html and js/lib.js. I tried to exclude these files with negative pattern '!' but without luck. Is there a way to achieve this only by using a pattern?

node.js Solutions


Solution 1 - node.js

I suppose it's not actual anymore but I got stuck with the same question and found an answer.

This can be done using only glob module. We need to use options as a second parameter to glob function

glob('pattern', {options}, cb)

There is an options.ignore pattern for your needs.

var glob = require('glob');

glob("**/*",{"ignore":['index.html', 'js', 'js/app.js', 'js/lib.js']}, function (err, files) {
  console.log(files);
})

Solution 2 - node.js

Check out globby, which is pretty much glob with support for multiple patterns and a Promise API:

const globby = require('globby');

globby(['**/*', '!index.html', '!js/lib.js']).then(paths => {
	console.log(paths);
});

Solution 3 - node.js

You can use node-globule for that:

var globule = require('globule');
var result = globule.find(['**/*', '!index.html', '!js/lib.js']);
console.log(result);

Solution 4 - node.js

Or without an external dependency:

/**
    Walk directory,
    list tree without regex excludes
 */
 
var fs = require('fs');
var path = require('path');
 
var walk = function (dir, regExcludes, done) {
  var results = [];
 
  fs.readdir(dir, function (err, list) {
    if (err) return done(err);
 
    var pending = list.length;
    if (!pending) return done(null, results);
 
    list.forEach(function (file) {
      file = path.join(dir, file);
 
      var excluded = false;
      var len = regExcludes.length;
      var i = 0;
 
      for (; i < len; i++) {
        if (file.match(regExcludes[i])) {
          excluded = true;
        }
      }
 
      // Add if not in regExcludes
      if(excluded === false) {
        results.push(file);
 
        // Check if its a folder
        fs.stat(file, function (err, stat) {
          if (stat && stat.isDirectory()) {
 
            // If it is, walk again
            walk(file, regExcludes, function (err, res) {
              results = results.concat(res);
 
              if (!--pending) { done(null, results); }
 
            });
          } else {
            if (!--pending) { done(null, results); }
          }
        });
      } else {
        if (!--pending) { done(null, results); }
      }
    });
  });
};
 
var regExcludes = [/index\.html/, /js\/lib\.js/, /node_modules/];
 
walk('.', regExcludes, function(err, results) {
  if (err) {
    throw err;
  }
  console.log(results);
});

Solution 5 - node.js

Here is what I wrote for my project:

var glob = require('glob');
var minimatch = require("minimatch");

function globArray(patterns, options) {
  var i, list = [];
  if (!Array.isArray(patterns)) {
    patterns = [patterns];
  }

  patterns.forEach(function (pattern) {
    if (pattern[0] === "!") {
      i = list.length-1;
      while( i > -1) {
        if (!minimatch(list[i], pattern)) {
          list.splice(i,1);
        }
        i--;
      }

    }
    else {
      var newList = glob.sync(pattern, options);
      newList.forEach(function(item){
        if (list.indexOf(item)===-1) {
          list.push(item);
        }
      });
    }
  });

  return list;
}

And call it like this (Using an array):

var paths = globArray(["**/*.css","**/*.js","!**/one.js"], {cwd: srcPath});

or this (Using a single string):

var paths = globArray("**/*.js", {cwd: srcPath});

Solution 6 - node.js

A samples example with gulp:

gulp.task('task_scripts', function(done){

    glob("./assets/**/*.js", function (er, files) {
        gulp.src(files)
            .pipe(gulp.dest('./public/js/'))
            .on('end', done);
    });

});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionke_waView Question on Stackoverflow
Solution 1 - node.jsSergei PanfilovView Answer on Stackoverflow
Solution 2 - node.jsSindre SorhusView Answer on Stackoverflow
Solution 3 - node.jsstefanbuckView Answer on Stackoverflow
Solution 4 - node.jsKojiView Answer on Stackoverflow
Solution 5 - node.jsIntervaliaView Answer on Stackoverflow
Solution 6 - node.jsIvan FerrerView Answer on Stackoverflow