Skip to content

Commit 110d917

Browse files
committed
minor #530 Add some checks to the 'pattern' option of Encore.copyFiles() (Lyrkan)
This PR was merged into the master branch. Discussion ---------- Add some checks to the 'pattern' option of Encore.copyFiles() While reviewing FriendsOfSymfony/FOSCKEditorBundle#174 I was a bit surprised that calling `copyFiles` with a string as a `pattern` (instead of a `RegExp`) worked fine. It turns out that's not an issue since the `copyFiles` method causes the creation of a temporary `.js` file in which the `RegExp` is casted to a string anyway. However, what *is* an issue is that using a string that does not contain a valid regular expression can break that temporary file. For instance: ```js Encore.copyFiles({ from: './assets', pattern: 'foo;' }); ``` Will generate something like: ```js const context_0 = require.context( '!/* ... */', true, foo; // <= Syntax error here ); context_0.keys().forEach(context_0); ``` This PR doesn't prevent using strings for that option because I don't think that would be the right choice (the unquoted `/regexp/` syntax may not be obvious for JS beginners) but instead officially allow them with some extra checks. It also casts `includeSubdirectories` (2nd parameter of the `require.context` above) to a boolean when creating the JS file to avoid the same kind of syntax error. Commits ------- d07965c Add some checks to the 'pattern' option of Encore.copyFiles()
2 parents e1983bc + d07965c commit 110d917

File tree

4 files changed

+32
-5
lines changed

4 files changed

+32
-5
lines changed

index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -508,8 +508,9 @@ class Encore {
508508
* Supported options:
509509
* * {string} from (mandatory)
510510
* The path of the source directory (mandatory)
511-
* * {RegExp} pattern (default: all files)
512-
* A pattern that the filenames must match in order to be copied
511+
* * {RegExp|string} pattern (default: all files)
512+
* A regular expression (or a string containing one) that
513+
* the filenames must match in order to be copied
513514
* * {string} to (default: [path][name].[ext])
514515
* Where the files must be copied to. You can add all the
515516
* placeholders supported by the file-loader.

lib/WebpackConfig.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,20 @@ class WebpackConfig {
471471
}
472472
}
473473

474+
if (typeof config.pattern !== 'undefined' && !(config.pattern instanceof RegExp)) {
475+
let validPattern = false;
476+
if (typeof config.pattern === 'string') {
477+
const regexPattern = /^\/(.*)\/([a-z]*)?$/;
478+
if (regexPattern.test(config.pattern)) {
479+
validPattern = true;
480+
}
481+
}
482+
483+
if (!validPattern) {
484+
throw new Error(`Invalid pattern "${config.pattern}" passed to copyFiles(). Make sure it contains a valid regular expression.`);
485+
}
486+
}
487+
474488
this.copyFilesConfigs.push(
475489
Object.assign({}, defaultConfig, config)
476490
);

lib/config-generator.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ class ConfigGenerator {
189189
return buffer + `
190190
const context_${index} = require.context(
191191
'${stringEscaper(requireContextParam)}',
192-
${entry.includeSubdirectories},
192+
${!!entry.includeSubdirectories},
193193
${entry.pattern}
194194
);
195195
context_${index}.keys().forEach(context_${index});

test/WebpackConfig.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ describe('WebpackConfig object', () => {
423423
// With multiple config objects
424424
config.copyFiles([
425425
{ from: './foo', pattern: /.*/ },
426-
{ from: './bar', pattern: /abc/, to: 'bar', includeSubdirectories: false },
426+
{ from: './bar', pattern: '/abc/', to: 'bar', includeSubdirectories: false },
427427
]);
428428

429429
// With a single config object
@@ -437,7 +437,7 @@ describe('WebpackConfig object', () => {
437437
context: null,
438438
}, {
439439
from: './bar',
440-
pattern: /abc/,
440+
pattern: '/abc/',
441441
to: 'bar',
442442
includeSubdirectories: false,
443443
context: null,
@@ -481,6 +481,18 @@ describe('WebpackConfig object', () => {
481481
config.copyFiles({ from: 'images', foo: 'foo' });
482482
}).to.throw('Invalid config option "foo"');
483483
});
484+
485+
it('Calling it with an invalid "pattern" option', () => {
486+
const config = createConfig();
487+
488+
expect(() => {
489+
config.copyFiles({ from: 'images', pattern: true });
490+
}).to.throw('Invalid pattern "true"');
491+
492+
expect(() => {
493+
config.copyFiles({ from: 'images', pattern: 'foo' });
494+
}).to.throw('Invalid pattern "foo"');
495+
});
484496
});
485497

486498
describe('autoProvideVariables', () => {

0 commit comments

Comments
 (0)