glob patterns difference between {} and +()

Viewed 451

I referenced https://facelessuser.github.io/wcmatch/glob/ and it says that

+(pattern_list) : The pattern matches if one or more occurrences of any of the patterns in the pattern_list match the input string. Requires the EXTGLOB flag.

{} : Bash style brace expansions. This is applied to patterns before anything else. Requires the BRACE flag.

I can see that the description is different for each of them, but hard to understand with the actual example.

For example, what is the difference between those two below?

"lint-staged": {
    "src/**/*.{js,jsx,ts,tsx,json,css}": [
        "prettier --write",
        "eslint --fix src/",
        "tslint --fix --project .",
        "git add"
    ]
},

"lint-staged": {
    "src/**/*.+(js|jsx|ts|tsx|json|css)": [
        "prettier --write",
        "eslint --fix src/",
        "tslint --fix --project .",
        "git add"
    ]
},

Any advice would be appreciated!

1 Answers

{} implements something similar to Bash's brace expansion. Essentially src/**/*.{js,jsx,ts,tsx,json,css} will become:

[
    'src/**/*.js',
    'src/**/*.jsx',
    'src/**/*.ts',
    'src/**/*.tsx',
    'src/**/*.json',
    'src/**/*.css'
]

There is a time and place for this, but you can see this might be less efficient as now you are processing multiple patterns.

You can think of +() more like in regular expression where +(js|jsx|ts|tsx|json|css) would be more equivalent to (js|jsx|ts|tsx|json|css)+. So it would match things like js or jsjsxtxjson Which is not really equivalent to {}.

What you are probably interested in, if looking for a more efficient comparison to {}, is probably @(js|jsx|ts|tsx|json|css) which is equivalent to regular expression patterns like this (js|jsx|ts|tsx|json|css) which would match just one occurrence and would match js but not jsjsxtxjson. The reason why this may be more efficient is simply that you get a single pattern as opposed to multiple patterns.

Related