kentcdodds kentcdodds - 5 months ago 8
Javascript Question

What's wrong with my glob?

I'm trying to write a glob for something that uses

minimatch
and having trouble excluding the files I want to. Here's a test case:

const glob = 'src/js/*!(test|stub).js' // this is the glob I'm trying to work out

const shouldMatch = [
'src/js/foo.js',
'src/js/bar.js',
'src/js/baz.js',
]

const shouldNotMatch = [
'src/js/foo.test.js',
'src/js/bar.stub.js',
'src/baz/blob.js',
]

const all = shouldMatch.concat(shouldNotMatch)

const matched = minimatch.match(all, glob) // https://www.npmjs.com/package/minimatch

expect(matched).toEqual(shouldMatch) // https://npmjs.com/package/expect


The output with this is:

"Error: Expected [ 'src/js/foo.js', 'src/js/bar.js', 'src/js/baz.js', 'src/js/foo.test.js', 'src/js/bar.stub.js' ] to equal [ 'src/js/foo.js', 'src/js/bar.js', 'src/js/baz.js' ]


You can see a live version of this here.

As you can see, it's including both the
test
and the
stub
files. What does my glob need to be so those files are excluded?

Answer

This is a common mistake with the !(...) syntax. Imagine something like this:

ls *!(.png|.jpg)

This doesn't do what we want because the .png and .jpg are matched by the *. So once we get to !(.png|.jpg), the string is null.

To fix it, we can do:

ls !(*.png|*.jpg)

Thus, to fix your example:

const glob = 'src/js/!(*test|*stub).js'

Here's a working example