diff --git a/lib/webpack/copy-files-loader.js b/lib/webpack/copy-files-loader.js index 36839ff6..608fb48a 100644 --- a/lib/webpack/copy-files-loader.js +++ b/lib/webpack/copy-files-loader.js @@ -56,7 +56,7 @@ module.exports.default = function loader(source) { // The "source" part of the regexp is base64 encoded // in case it contains characters that don't work with // the "inline loader" syntax - const pattern = new RegExp( + const pattern = options.regExp || new RegExp( Buffer.from(options.patternSource, 'base64').toString(), options.patternFlags ); @@ -69,6 +69,23 @@ module.exports.default = function loader(source) { return 'module.exports = "";'; } + // Add the "regExp" option (needed to use the [N] placeholder + // see: https://github.com/webpack-contrib/file-loader#n) + options.regExp = pattern; + + // Remove copy-files-loader's custom options (in case the + // file-loader starts looking for thing it doesn't expect) + delete options.patternSource; + delete options.patternFlags; + + // Update loader's options. + this.loaders.forEach(loader => { + if (__filename === loader.path) { + loader.options = options; + delete loader.query; + } + }); + // If everything is OK, let the file-loader do the copy return fileLoader.bind(this)(source); }; diff --git a/test/functional.js b/test/functional.js index 1d88d42f..73be694d 100644 --- a/test/functional.js +++ b/test/functional.js @@ -2206,6 +2206,41 @@ module.exports = { done(); }); }); + + it('Can use the "[N]" placeholder', (done) => { + const config = createWebpackConfig('www/build', 'production'); + config.addEntry('main', './js/no_require'); + config.setPublicPath('/build'); + config.copyFiles({ + from: './images', + pattern: /(symfony)_(logo)\.png/, + to: '[path][2]_[1].[ext]', + includeSubdirectories: false + }); + + testSetup.runWebpack(config, (webpackAssert) => { + expect(config.outputPath).to.be.a.directory() + .with.files([ + 'entrypoints.json', + 'runtime.js', + 'main.js', + 'manifest.json', + 'logo_symfony.png' + ]); + + webpackAssert.assertManifestPath( + 'build/main.js', + '/build/main.js' + ); + + webpackAssert.assertManifestPath( + 'build/symfony_logo.png', + '/build/logo_symfony.png' + ); + + done(); + }); + }); }); describe('entrypoints.json & splitChunks()', () => {