From 0f6336969bd35099e12ac54976dfa572af530893 Mon Sep 17 00:00:00 2001 From: Lyrkan <850046+Lyrkan@users.noreply.github.com> Date: Tue, 23 Jul 2019 22:47:24 +0200 Subject: [PATCH] Fix createSharedEntry(...) when using query string versioning strategy --- lib/utils/get-file-extension.js | 19 ++++++++++ lib/webpack/shared-entry-concat-plugin.js | 4 ++- test/functional.js | 29 +++++++++++++++- test/utils/get-file-extension.js | 42 +++++++++++++++++++++++ 4 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 lib/utils/get-file-extension.js create mode 100644 test/utils/get-file-extension.js diff --git a/lib/utils/get-file-extension.js b/lib/utils/get-file-extension.js new file mode 100644 index 00000000..12182567 --- /dev/null +++ b/lib/utils/get-file-extension.js @@ -0,0 +1,19 @@ +/* + * 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 path = require('path'); +const url = require('url'); + +module.exports = function(filename) { + const parsedFilename = new url.URL(filename, 'http://foo'); + const extension = path.extname(parsedFilename.pathname); + return extension ? extension.slice(1) : ''; +}; diff --git a/lib/webpack/shared-entry-concat-plugin.js b/lib/webpack/shared-entry-concat-plugin.js index 5561cd1c..84ae6210 100644 --- a/lib/webpack/shared-entry-concat-plugin.js +++ b/lib/webpack/shared-entry-concat-plugin.js @@ -10,6 +10,7 @@ 'use strict'; const sharedEntryTmpName = require('../utils/sharedEntryTmpName'); +const getFileExtension = require('../utils/get-file-extension'); const RawSource = require('webpack-sources/lib/RawSource'); function SharedEntryConcatPlugin(sharedEntryName) { @@ -26,7 +27,8 @@ function getChunkFilename(compilation, chunkName) { } const jsFiles = chunk.files.filter(filename => { - return /\.js$/.test(filename) && !additionalChunkAssets.includes(filename); + const fileExtension = getFileExtension(filename); + return /^js$/.test(fileExtension) && !additionalChunkAssets.includes(filename); }); if (jsFiles.length !== 1) { diff --git a/test/functional.js b/test/functional.js index b213da46..60776b36 100644 --- a/test/functional.js +++ b/test/functional.js @@ -854,7 +854,7 @@ describe('Functional tests using webpack', function() { }); }); - it('createdSharedEntry() works with versioning', (done) => { + it('createdSharedEntry() works with default versioning strategy', (done) => { const config = createWebpackConfig('www/build', 'dev'); config.setPublicPath('/build'); config.addEntry('main', ['./js/no_require', './js/code_splitting', './js/arrow_function', './js/print_to_app']); @@ -878,6 +878,33 @@ describe('Functional tests using webpack', function() { }); }); + it('createdSharedEntry() works with query string versioning strategy', (done) => { + const config = createWebpackConfig('www/build', 'dev'); + config.setPublicPath('/build'); + config.addEntry('main', ['./js/no_require', './js/code_splitting', './js/arrow_function', './js/print_to_app']); + config.addEntry('other', ['./js/no_require', './css/h1_style.css']); + config.createSharedEntry('shared', './js/shared_example'); + config.configureFilenames({ + js: '[name].js?[contenthash:8]', + css: '[name].css?[contenthash:8]', + }); + + testSetup.runWebpack(config, (webpackAssert) => { + testSetup.requestTestPage( + path.join(config.getContext(), 'www'), + [ + convertToManifestPath('build/runtime.js', config), + convertToManifestPath('build/shared.js', config), + ], + (browser) => { + // assert that the javascript brought into shared is executed + browser.assert.text('#app', 'Welcome to Encore!'); + done(); + } + ); + }); + }); + it('createdSharedEntry() works with source maps enabled', (done) => { const config = createWebpackConfig('www/build', 'dev'); config.setPublicPath('/build'); diff --git a/test/utils/get-file-extension.js b/test/utils/get-file-extension.js new file mode 100644 index 00000000..3a57b6b5 --- /dev/null +++ b/test/utils/get-file-extension.js @@ -0,0 +1,42 @@ +/* + * 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 expect = require('chai').expect; +const getFileExtension = require('../../lib/utils/get-file-extension'); + +describe('get-file-extension', () => { + it('returns the extension of simple filenames', () => { + expect(getFileExtension('foo.js')).to.equal('js'); + expect(getFileExtension('foo-bar.txt')).to.equal('txt'); + expect(getFileExtension('foo.bar.baz')).to.equal('baz'); + }); + + it('returns an empty string for files with no extension', () => { + expect(getFileExtension('foo')).to.equal(''); + expect(getFileExtension('foo-bar')).to.equal(''); + }); + + it('returns the extension of a file from an absolute path', () => { + expect(getFileExtension('/home/foo/bar.js')).to.equal('js'); + expect(getFileExtension('C:\\home\\foo\\bar.js')).to.equal('js'); + }); + + it('returns the extension from an URI', () => { + expect(getFileExtension('http://localhost/foo.js')).to.equal('js'); + expect(getFileExtension('file://localhost/foo/bar.txt')).to.equal('txt'); + expect(getFileExtension('https://localhost:8080/foo.bar.baz')).to.equal('baz'); + }); + + it('works with query strings', () => { + expect(getFileExtension('http://localhost/foo.js?abcd')).to.equal('js'); + expect(getFileExtension('foo.txt?bar=baz&baz=bar')).to.equal('txt'); + }); +});