diff --git a/__specs__/index.spec.js b/__specs__/index.spec.js index 820d7f7..9776729 100644 --- a/__specs__/index.spec.js +++ b/__specs__/index.spec.js @@ -42,8 +42,45 @@ describe('Should create a correct regular expression for excluding node_modules' }); }); +describe('Should be able to convert wildcards in parameters to matching pattern in the regular expression', () => { + /** + * @type {TestCase[]} + */ + const testCases = [ + { + description: 'Wildcard occurs in the only argument', + params: ['react-*'], + expected: X + ? /node_modules\\(?!(react\-(?:.*))\\)/i + : /node_modules\/(?!(react\-(?:.*))\/)/i + }, + { + description: 'Wildcard occurs in the second argument out of three', + params: ['abc', 'mno*', 'xvz'], + expected: X + ? /node_modules\\(?!(abc|mno(?:.*)|xvz)\\)/i + : /node_modules\/(?!(abc|mno(?:.*)|xvz)\/)/i + }, + { + description: 'Wildcard used for scoped packages', + params: ['@awesomecorp/*'], + expected: X + ? /node_modules\\(?!(@awesomecorp\\(?:.*))\\)/i + : /node_modules\/(?!(@awesomecorp\/(?:.*))\/)/i + } + ]; + + testCases.forEach(function ({ params, expected, description }, i) { + test(`Test case #${i + 1}: ${description}`, function () { + const result = babelLoaderExcludeNodeModulesExcept(params); + expect(result).toEqual(expected); + }); + }); +}); + /** * @typedef {Object} TestCase * @property {string[]} params * @property {RegExp} expected + * @property {string} [description] */ diff --git a/index.js b/index.js index e598578..b24e41c 100644 --- a/index.js +++ b/index.js @@ -23,7 +23,29 @@ function babelLoaderExcludeNodeModulesExcept(exceptionList) { }); const alternationGroup = - '(' + normalizedExceptionList.map(escapeStringRegexp).join('|') + ')'; + '(' + + normalizedExceptionList + .map((item) => { + // Breaking down string by wildcards. For every + // occurrance between wildcards build the portion + // with escapeStringRegexp. + // For the wildcards, replace them by a non-capturing + // group matching everything. + const match = item.match(/([^*]*)/g); + return match + .map((m, i) => { + if (m.length > 0) { + return escapeStringRegexp(m); + } else if (i !== match.length - 1 && m.length === 0) { + return '(?:.*)'; + } else { + return ''; + } + }) + .join(''); + }) + .join('|') + + ')'; // If the exception list includes e.g. "react", we don't want to // accidentally make an exception for "react-dom", so make sure to