Skip to content

Commit 1f3be51

Browse files
committed
feature #518 Allow to set a custom context in copyFiles (Lyrkan, weaverryan)
This PR was merged into the master branch. Discussion ---------- Allow to set a custom context in copyFiles The current behavior of `copyFiles()` is to use the value of the `from` option as a context when copying files. This means that when doing the following: ```js Encore.copyFiles({ from: './assets/images', to: '[path][name].[ext]', includeSubdirectories: false, }); ``` Will end-up putting all the files from `./assets/images` directly at the root of the output directory. Sometimes this is not the desired behavior (see #490 (comment)) which is why this PRs adds a `context` option to `copyFiles()` entries (closes #490). For instance: ```js Encore.copyFiles({ from: './assets/images', to: '[path][name].[ext]', includeSubdirectories: false, context: './', }); ``` Will put all the copied files inside of an `./assets/images` folder in the output directory. Commits ------- 73b8be5 a bit more docs 487d6ef Allow to set a custom context in copyFiles
2 parents 7571164 + 73b8be5 commit 1f3be51

File tree

5 files changed

+75
-5
lines changed

5 files changed

+75
-5
lines changed

index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,14 @@ class Encore {
493493
* { from: './txt', pattern: /\.txt$/ },
494494
* ]);
495495
*
496+
* // Set the context path: files will be copied
497+
* // into an images/ directory in the output dir
498+
* Encore.copyFiles({
499+
* from: './assets/images',
500+
* to: '[path][name].[hash:8].[ext]',
501+
* context: './assets'
502+
* });
503+
*
496504
* Notes:
497505
* * No transformation is applied to the copied files (for instance
498506
* copying a CSS file won't minify it)
@@ -508,6 +516,8 @@ class Encore {
508516
* https://github.com/webpack-contrib/file-loader#placeholders
509517
* * {boolean} includeSubdirectories (default: true)
510518
* Whether or not the copy should include subdirectories.
519+
* * {string} context (default: path of the source directory)
520+
* The context to use as a root path when copying files.
511521
*
512522
* @param {object|Array} configs
513523
* @returns {Encore}

lib/WebpackConfig.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,8 @@ class WebpackConfig {
437437
from: null,
438438
pattern: /.*/,
439439
to: null,
440-
includeSubdirectories: true
440+
includeSubdirectories: true,
441+
context: null,
441442
};
442443

443444
for (const config of configs) {

lib/config-generator.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,8 @@ class ConfigGenerator {
183183
copyTo = this.webpackConfig.useVersioning ? '[path][name].[hash:8].[ext]' : '[path][name].[ext]';
184184
}
185185

186-
const requireContextParam = `!${require.resolve('file-loader')}?context=${copyFrom}&name=${copyTo}!${copyFrom}`;
186+
const copyContext = entry.context ? path.resolve(this.webpackConfig.getContext(), entry.context) : copyFrom;
187+
const requireContextParam = `!${require.resolve('file-loader')}?context=${copyContext}&name=${copyTo}!${copyFrom}`;
187188

188189
return buffer + `
189190
const context_${index} = require.context(

test/WebpackConfig.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -394,17 +394,20 @@ describe('WebpackConfig object', () => {
394394
from: './foo',
395395
pattern: /.*/,
396396
to: null,
397-
includeSubdirectories: true
397+
includeSubdirectories: true,
398+
context: null,
398399
}, {
399400
from: './bar',
400401
pattern: /abc/,
401402
to: 'bar',
402-
includeSubdirectories: false
403+
includeSubdirectories: false,
404+
context: null,
403405
}, {
404406
from: './baz',
405407
pattern: /.*/,
406408
to: null,
407-
includeSubdirectories: true
409+
includeSubdirectories: true,
410+
context: null,
408411
}]);
409412
});
410413

test/functional.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1836,6 +1836,61 @@ module.exports = {
18361836
done();
18371837
});
18381838
});
1839+
1840+
it('Copy with a custom context', (done) => {
1841+
const config = createWebpackConfig('www/build', 'production');
1842+
config.addEntry('main', './js/no_require');
1843+
config.setPublicPath('/build');
1844+
config.copyFiles({
1845+
from: './images',
1846+
to: '[path][name].[hash:8].[ext]',
1847+
includeSubdirectories: true,
1848+
context: './',
1849+
});
1850+
1851+
testSetup.runWebpack(config, (webpackAssert) => {
1852+
expect(config.outputPath).to.be.a.directory()
1853+
.with.files([
1854+
'entrypoints.json',
1855+
'runtime.js',
1856+
'main.js',
1857+
'manifest.json',
1858+
]);
1859+
1860+
expect(path.join(config.outputPath, 'images')).to.be.a.directory()
1861+
.with.files([
1862+
'symfony_logo.ea1ca6f7.png',
1863+
'symfony_logo_alt.f27119c2.png',
1864+
]);
1865+
1866+
expect(path.join(config.outputPath, 'images', 'same_filename')).to.be.a.directory()
1867+
.with.files([
1868+
'symfony_logo.f27119c2.png',
1869+
]);
1870+
1871+
webpackAssert.assertManifestPath(
1872+
'build/main.js',
1873+
'/build/main.js'
1874+
);
1875+
1876+
webpackAssert.assertManifestPath(
1877+
'build/images/symfony_logo.png',
1878+
'/build/images/symfony_logo.ea1ca6f7.png'
1879+
);
1880+
1881+
webpackAssert.assertManifestPath(
1882+
'build/images/symfony_logo_alt.png',
1883+
'/build/images/symfony_logo_alt.f27119c2.png'
1884+
);
1885+
1886+
webpackAssert.assertManifestPath(
1887+
'build/images/same_filename/symfony_logo.png',
1888+
'/build/images/same_filename/symfony_logo.f27119c2.png'
1889+
);
1890+
1891+
done();
1892+
});
1893+
});
18391894
});
18401895

18411896
describe('entrypoints.json & splitChunks()', () => {

0 commit comments

Comments
 (0)