From c18ac58e07bdeb60a5ce45eb5e6ab6070f7e2bb6 Mon Sep 17 00:00:00 2001 From: Bob van de Vijver Date: Tue, 18 May 2021 10:21:00 +0200 Subject: [PATCH] #936: Fix manifest key problem when using copy files --- lib/webpack-manifest-plugin/hooks.js | 10 ++- package.json | 6 +- run-persistent-tests.js | 18 ++++++ test/functional.js | 18 ------ test/helpers/setup.js | 4 +- test/persistent-cache/functional.js | 93 ++++++++++++++++++++++++++++ 6 files changed, 124 insertions(+), 25 deletions(-) create mode 100755 run-persistent-tests.js create mode 100755 test/persistent-cache/functional.js diff --git a/lib/webpack-manifest-plugin/hooks.js b/lib/webpack-manifest-plugin/hooks.js index bdbc84ce..c257856a 100644 --- a/lib/webpack-manifest-plugin/hooks.js +++ b/lib/webpack-manifest-plugin/hooks.js @@ -129,12 +129,16 @@ const normalModuleLoaderHook = ({ moduleAssets }, loaderContext, module) => { const { emitFile } = loaderContext; // eslint-disable-next-line no-param-reassign - loaderContext.emitFile = (file, content, sourceMap) => { + loaderContext.emitFile = (file, content, sourceMap, assetInfo) => { + const info = Object.assign({}, assetInfo); + if (module.userRequest && !moduleAssets[file]) { - Object.assign(moduleAssets, { [file]: join(dirname(file), basename(module.userRequest)) }); + info.sourceFilename = join(dirname(file), basename(module.userRequest)); + + Object.assign(moduleAssets, { [file]: info.sourceFilename }); } - return emitFile.call(module, file, content, sourceMap); + return emitFile.call(module, file, content, sourceMap, info); }; }; diff --git a/package.json b/package.json index 0f4681a5..240cc2ea 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,11 @@ "description": "Webpack Encore is a simpler way to integrate Webpack into your application", "main": "index.js", "scripts": { - "test": "mocha --reporter spec test --recursive", + "test": "yarn run test:main && yarn run test:persistent-cache", + "test:main": "mocha --reporter spec test --recursive --ignore test/persistent-cache/*", + "test:persistent-cache": "node run-persistent-tests", "lint": "eslint lib test index.js .eslintrc.js", - "travis:lint": "npm run lint" + "travis:lint": "yarn run lint" }, "bin": { "encore": "bin/encore.js" diff --git a/run-persistent-tests.js b/run-persistent-tests.js new file mode 100755 index 00000000..ba6a9f22 --- /dev/null +++ b/run-persistent-tests.js @@ -0,0 +1,18 @@ +/* + * This file is part of the Symfony Webpack Encore package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +'use strict'; + +const { execSync } = require('child_process'); +const { emptyTmpDir } = require('./test/helpers/setup'); + +emptyTmpDir(); +for (let i = 0; i < 2; i++) { + execSync('mocha --reporter spec test/persistent-cache --recursive', { stdio: 'inherit' }); +} diff --git a/test/functional.js b/test/functional.js index 969ce487..587ee517 100644 --- a/test/functional.js +++ b/test/functional.js @@ -753,23 +753,6 @@ describe('Functional tests using webpack', function() { }); }); - it('Persistent caching does not cause problems', (done) => { - const config = createWebpackConfig('www/build', 'dev'); - config.setPublicPath('/build'); - config.addEntry('main', './js/code_splitting'); - config.enableBuildCache({ config: [__filename] }); - - testSetup.runWebpack(config, (webpackAssert) => { - // sanity check - webpackAssert.assertManifestPath( - 'build/main.js', - '/build/main.js' - ); - - done(); - }); - }); - describe('addCacheGroup()', () => { it('addCacheGroup() to extract a vendor into its own chunk', (done) => { const config = createWebpackConfig('www/build', 'dev'); @@ -1295,7 +1278,6 @@ module.exports = { }); }); - it('When enabled, react JSX is transformed!', (done) => { const config = createWebpackConfig('www/build', 'dev'); config.setPublicPath('/build'); diff --git a/test/helpers/setup.js b/test/helpers/setup.js index 4db5fd72..3c84fa1d 100644 --- a/test/helpers/setup.js +++ b/test/helpers/setup.js @@ -25,8 +25,8 @@ const testFixturesDir = path.join(__dirname, '../', '../', 'fixtures'); let servers = []; -function createTestAppDir(rootDir = tmpDir) { - const testAppDir = path.join(rootDir, Math.random().toString(36).substring(7)); +function createTestAppDir(rootDir = null, subDir = null) { + const testAppDir = path.join(rootDir ? rootDir : tmpDir, subDir ? subDir : Math.random().toString(36).substring(7)); // copy the fixtures into this new directory fs.copySync(testFixturesDir, testAppDir); diff --git a/test/persistent-cache/functional.js b/test/persistent-cache/functional.js new file mode 100755 index 00000000..9fd209a2 --- /dev/null +++ b/test/persistent-cache/functional.js @@ -0,0 +1,93 @@ +/* + * This file is part of the Symfony Webpack Encore package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +'use strict'; + +const chai = require('chai'); +chai.use(require('chai-fs')); +chai.use(require('chai-subset')); +const path = require('path'); +const testSetup = require('../helpers/setup'); + +function createWebpackConfig(outputDirName = '', testName, command, argv = {}) { + // We need a static named test dir for the cache to work + let testAppDir = testSetup.createTestAppDir(null, testName + '/test'); + const webpackConfig = testSetup.createWebpackConfig( + testAppDir, + outputDirName, + command, + argv, + ); + + webpackConfig.enableSingleRuntimeChunk(); + webpackConfig.enableBuildCache({ config: [__filename] }, (cache) => { + cache.cacheDirectory = path.resolve(testAppDir, '..', '.webpack-cache'); + }); + + return webpackConfig; +} + +describe('Functional persistent cache tests using webpack', function() { + // being functional tests, these can take quite long + this.timeout(10000); + + describe('Basic scenarios.', () => { + it('Persistent caching does not cause problems', (done) => { + const config = createWebpackConfig('www/build', 'basic_cache', 'dev'); + config.setPublicPath('/build'); + config.addEntry('main', './js/code_splitting'); + + testSetup.runWebpack(config, (webpackAssert) => { + // sanity check + webpackAssert.assertManifestPath( + 'build/main.js', + '/build/main.js', + ); + + done(); + }); + }); + }); + + describe('copyFiles() allows to copy files and folders', () => { + it('Persistent caching does not cause problems', (done) => { + const config = createWebpackConfig('www/build', 'copy_files_cache', 'production'); + config.addEntry('main', './js/no_require'); + config.setPublicPath('/build'); + config.enableVersioning(true); + config.copyFiles([{ + from: './images', + includeSubdirectories: false, + }]); + + testSetup.runWebpack(config, (webpackAssert) => { + webpackAssert.assertDirectoryContents([ + 'entrypoints.json', + 'runtime.[hash:8].js', + 'main.[hash:8].js', + 'manifest.json', + 'symfony_logo.[hash:8].png', + 'symfony_logo_alt.[hash:8].png', + ]); + + webpackAssert.assertManifestPath( + 'build/symfony_logo.png', + '/build/symfony_logo.91beba37.png', + ); + + webpackAssert.assertManifestPath( + 'build/symfony_logo_alt.png', + '/build/symfony_logo_alt.f880ba14.png', + ); + + done(); + }); + }); + }); +});