Skip to content

Commit 4ef8c2a

Browse files
committed
Fix JSON files support in Encore.copyFiles()
1 parent 0facc4d commit 4ef8c2a

File tree

6 files changed

+87
-1
lines changed

6 files changed

+87
-1
lines changed

fixtures/copy/foo.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is an invalid content to check that the file is still copied

fixtures/copy/foo.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is an invalid content to check that the file is still copied

fixtures/copy/foo.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is an invalid content to check that the file is still copied

lib/config-generator.js

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

186+
const copyFilesLoader = require.resolve('./webpack/copy-files-loader');
187+
const fileLoader = require.resolve('file-loader');
186188
const copyContext = entry.context ? path.resolve(this.webpackConfig.getContext(), entry.context) : copyFrom;
187-
const requireContextParam = `!${require.resolve('file-loader')}?context=${copyContext}&name=${copyTo}!${copyFrom}`;
189+
const requireContextParam = `!${copyFilesLoader}!${fileLoader}?context=${copyContext}&name=${copyTo}!${copyFrom}`;
188190

189191
return buffer + `
190192
const context_${index} = require.context(

lib/webpack/copy-files-loader.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* This file is part of the Symfony Webpack Encore package.
3+
*
4+
* (c) Fabien Potencier <[email protected]>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
'use strict';
11+
12+
const LoaderDependency = require('webpack/lib/dependencies/LoaderDependency');
13+
14+
module.exports = function loader(source) {
15+
// This is a hack that allows `Encore.copyFiles()` to support
16+
// JSON files using the file-loader (which is not something
17+
// that is supported in Webpack 4, see https://github.com/symfony/webpack-encore/issues/535)
18+
//
19+
// Since there is no way to change the module's resource type from a loader
20+
// without using private properties yet we have to use "this._module".
21+
//
22+
// By setting its type to 'javascript/auto' Webpack won't try parsing
23+
// the result of the loader as a JSON object.
24+
//
25+
// For more information:
26+
// https://github.com/webpack/webpack/issues/6572#issuecomment-368376326
27+
// https://github.com/webpack/webpack/issues/7057
28+
const requiredType = 'javascript/auto';
29+
if (this._module.type !== requiredType) {
30+
// Try to retrieve the factory used by the LoaderDependency type
31+
// which should be the NormalModuleFactory.
32+
const factory = this._compilation.dependencyFactories.get(LoaderDependency);
33+
if (factory === undefined) {
34+
throw new Error('Could not retrieve module factory for type LoaderDependency');
35+
}
36+
37+
this._module.type = requiredType;
38+
this._module.generator = factory.getGenerator(requiredType);
39+
this._module.parser = factory.getParser(requiredType);
40+
}
41+
42+
return source;
43+
};

test/functional.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1891,6 +1891,44 @@ module.exports = {
18911891
done();
18921892
});
18931893
});
1894+
1895+
it('Copy files without processing them', (done) => {
1896+
const config = createWebpackConfig('www/build', 'production');
1897+
config.addEntry('main', './js/no_require');
1898+
config.setPublicPath('/build');
1899+
config.copyFiles({ from: './copy' });
1900+
1901+
// By default the optimize-css-assets-webpack-plugin will
1902+
// run on ALL emitted CSS files, which includes the ones
1903+
// handled by `Encore.copyFiles()`.
1904+
// We disable it for this test since our CSS file will
1905+
// not be valid and can't be handled by this plugin.
1906+
config.configureOptimizeCssPlugin(options => {
1907+
options.assetNameRegExp = /^$/;
1908+
});
1909+
1910+
testSetup.runWebpack(config, (webpackAssert) => {
1911+
expect(config.outputPath).to.be.a.directory()
1912+
.with.files([
1913+
'entrypoints.json',
1914+
'runtime.js',
1915+
'main.js',
1916+
'manifest.json',
1917+
'foo.css',
1918+
'foo.js',
1919+
'foo.json',
1920+
]);
1921+
1922+
for (const file of ['foo.css', 'foo.js', 'foo.json']) {
1923+
webpackAssert.assertOutputFileContains(
1924+
file,
1925+
'This is an invalid content to check that the file is still copied'
1926+
);
1927+
}
1928+
1929+
done();
1930+
});
1931+
});
18941932
});
18951933

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

0 commit comments

Comments
 (0)