Skip to content

Commit 4b90883

Browse files
committed
bug #463 Using contenthash instead of chunkhash (weaverryan)
This PR was squashed before being merged into the master branch (closes #463). Discussion ---------- Using contenthash instead of chunkhash Since Webpack 4.3.0, a `[contenthash]` has existed, which is the [recommended way](https://webpack.js.org/guides/caching/#output-filenames) of versioning your filenames. Previously, we used a special plugin that gave us a `chunkhash`, which worked around issues with hash changing unnecessarily. However, `chunkhash` actually created a bug - in #461, some chunk id's change unnecessarily. That's bad for caching, but the *real* problem was that `[chunkhash]` did not change, and so the filenames did not change. The filenames DO change with `[contenthash]`. Commits ------- 3797cba Using contenthash instead of chunkhash
2 parents cec8358 + 3797cba commit 4b90883

File tree

7 files changed

+42
-27
lines changed

7 files changed

+42
-27
lines changed

index.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -993,7 +993,7 @@ class Encore {
993993
* file is generated.
994994
*
995995
* Encore.configureFilenames({
996-
* js: '[name].[chunkhash].js',
996+
* js: '[name].[contenthash].js',
997997
* css: '[name].[contenthash].css',
998998
* images: 'images/[name].[hash:8].[ext]',
999999
* fonts: 'fonts/[name].[hash:8].[ext]'
@@ -1003,8 +1003,7 @@ class Encore {
10031003
* will be used for any file types not passed.
10041004
*
10051005
* If you are using Encore.enableVersioning()
1006-
* make sure that your "js" filenames contain
1007-
* "[chunkhash]" and your "css" filenames contain
1006+
* make sure that your "js" and "css" filenames contain
10081007
* "[contenthash]".
10091008
*
10101009
* @param {object} filenames

lib/WebpackConfig.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,10 @@ class WebpackConfig {
614614
}
615615
}
616616

617+
if (typeof configuredFilenames.js !== 'undefined' && configuredFilenames.js.includes('[chunkhash')) {
618+
logger.deprecation('Using the [chunkhash] placeholder in any filenames is deprecated: use [contenthash] instead.');
619+
}
620+
617621
this.configuredFilenames = configuredFilenames;
618622
}
619623

lib/config-generator.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ class ConfigGenerator {
184184

185185
buildOutputConfig() {
186186
// Default filename can be overridden using Encore.configureFilenames({ js: '...' })
187-
let filename = this.webpackConfig.useVersioning ? '[name].[chunkhash:8].js' : '[name].js';
187+
let filename = this.webpackConfig.useVersioning ? '[name].[contenthash:8].js' : '[name].js';
188188
if (this.webpackConfig.configuredFilenames.js) {
189189
filename = this.webpackConfig.configuredFilenames.js;
190190
}

lib/plugins/versioning.js

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const PluginPriorities = require('./plugin-priorities');
2121
module.exports = function(plugins, webpackConfig) {
2222

2323
/*
24-
* With versioning, the "chunkhash" used in the filenames and
24+
* With versioning, the "contenthash" used in the filenames and
2525
* the module ids (i.e. the internal names of modules that
2626
* are required) become important. Specifically:
2727
*
@@ -32,19 +32,14 @@ module.exports = function(plugins, webpackConfig) {
3232
*
3333
* 2) Similarly, if the final contents of a file don't change,
3434
* then we also don't want that file to have a new filename.
35-
* The WebpackChunkHash() handles this, by making sure that
36-
* the chunkhash is based off of the file contents.
37-
*
38-
* Even in the webpack community, the ideal setup seems to be
39-
* a bit of a mystery:
40-
* * https://github.com/webpack/webpack/issues/1315
41-
* * https://github.com/webpack/webpack.js.org/issues/652#issuecomment-273324529
42-
* * https://webpack.js.org/guides/caching/#deterministic-hashes
35+
* The "contenthash" handles this.
4336
*/
4437
if (webpackConfig.isProduction()) {
4538
// shorter, and obfuscated module ids (versus named modules)
4639
// makes the final assets *slightly* larger, but prevents contents
4740
// from sometimes changing when nothing really changed
41+
// Note: Should not be needed in Webpack 5:
42+
// https://github.com/webpack/webpack/pull/8276
4843
plugins.push({
4944
plugin: new webpack.HashedModuleIdsPlugin(),
5045
priority: PluginPriorities.HashedModuleIdsPlugin
@@ -55,7 +50,7 @@ module.exports = function(plugins, webpackConfig) {
5550
}
5651

5752
if (webpackConfig.useVersioning) {
58-
// enables the [chunkhash] ability
53+
// enables the [chunkhash] ability, which is deprecated
5954
plugins.push({
6055
plugin: new WebpackChunkHash(),
6156
priority: PluginPriorities.WebpackChunkHash

test/WebpackConfig.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -983,14 +983,14 @@ describe('WebpackConfig object', () => {
983983
it('Calling method sets it', () => {
984984
const config = createConfig();
985985
config.configureFilenames({
986-
js: '[name].[chunkhash].js',
986+
js: '[name].[contenthash].js',
987987
css: '[name].[contenthash].css',
988988
images: 'images/[name].[hash:8].[ext]',
989989
fonts: 'fonts/[name].[hash:8].[ext]'
990990
});
991991

992992
expect(config.configuredFilenames).to.deep.equals({
993-
js: '[name].[chunkhash].js',
993+
js: '[name].[contenthash].js',
994994
css: '[name].[contenthash].css',
995995
images: 'images/[name].[hash:8].[ext]',
996996
fonts: 'fonts/[name].[hash:8].[ext]'
@@ -1014,6 +1014,23 @@ describe('WebpackConfig object', () => {
10141014
});
10151015
}).to.throw('"foo" is not a valid key');
10161016
});
1017+
1018+
it('Using chunkhash is deprecated', () => {
1019+
logger.reset();
1020+
logger.quiet();
1021+
1022+
after(() => {
1023+
logger.quiet(false);
1024+
});
1025+
1026+
const config = createConfig();
1027+
1028+
config.configureFilenames({
1029+
js: 'file.[chunkhash:16].js'
1030+
});
1031+
1032+
expect(logger.getMessages().deprecation).to.not.be.empty;
1033+
});
10171034
});
10181035

10191036
describe('configureUrlLoader', () => {

test/config-generator.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ describe('The config-generator function', () => {
199199
config.useVersioning = true;
200200

201201
const actualConfig = configGenerator(config);
202-
expect(actualConfig.output.filename).to.equal('[name].[chunkhash:8].js');
202+
expect(actualConfig.output.filename).to.equal('[name].[contenthash:8].js');
203203

204204
const miniCssPlugin = findPlugin(MiniCssExtractPlugin, actualConfig.plugins);
205205

test/functional.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -390,11 +390,11 @@ describe('Functional tests using webpack', function() {
390390
testSetup.runWebpack(config, (webpackAssert) => {
391391
expect(config.outputPath).to.be.a.directory()
392392
.with.files([
393-
'main.f1e0a935.js',
393+
'main.89eb104b.js',
394394
'styles.8ec31654.css',
395395
'manifest.json',
396396
'entrypoints.json',
397-
'runtime.d41d8cd9.js',
397+
'runtime.3d179b24.js',
398398
]);
399399

400400
webpackAssert.assertOutputFileContains(
@@ -421,7 +421,7 @@ describe('Functional tests using webpack', function() {
421421
config.enableVersioning(true);
422422
config.configureFilenames({
423423
js: '[name].js?[chunkhash:16]',
424-
css: '[name].css?[contenthash:16]'
424+
css: '[name].css?[chunkhash:16]'
425425
});
426426

427427
testSetup.runWebpack(config, (webpackAssert) => {
@@ -437,7 +437,7 @@ describe('Functional tests using webpack', function() {
437437
);
438438
webpackAssert.assertManifestPath(
439439
'styles.css',
440-
'/styles.css?8ec316547cc77b39'
440+
'/styles.css?91597a40238e0e66'
441441
);
442442

443443
done();
@@ -491,14 +491,14 @@ describe('Functional tests using webpack', function() {
491491
testSetup.runWebpack(config, (webpackAssert) => {
492492
expect(config.outputPath).to.be.a.directory()
493493
.with.files([
494-
'0.8256b1ad.js', // chunks are also versioned
494+
'0.590a68c7.js', // chunks are also versioned
495495
'0.8ec31654.css',
496-
'main.ba427376.js',
496+
'main.4a5effdb.js',
497497
'h1.8ec31654.css',
498498
'bg.0ec2735b.css',
499499
'manifest.json',
500500
'entrypoints.json',
501-
'runtime.d41d8cd9.js',
501+
'runtime.b84a9b43.js',
502502
]);
503503

504504
expect(path.join(config.outputPath, 'images')).to.be.a.directory()
@@ -1625,8 +1625,8 @@ module.exports = {
16251625
expect(config.outputPath).to.be.a.directory()
16261626
.with.files([
16271627
'entrypoints.json',
1628-
'runtime.d41d8cd9.js',
1629-
'main.1172d977.js',
1628+
'runtime.21aa1db9.js',
1629+
'main.22bad391.js',
16301630
'manifest.json',
16311631
'symfony_logo.ea1ca6f7.png',
16321632
'symfony_logo_alt.f27119c2.png',
@@ -1639,7 +1639,7 @@ module.exports = {
16391639

16401640
webpackAssert.assertManifestPath(
16411641
'build/main.js',
1642-
'/build/main.1172d977.js'
1642+
'/build/main.22bad391.js'
16431643
);
16441644

16451645
webpackAssert.assertManifestPath(

0 commit comments

Comments
 (0)