Skip to content

Vendor chunkhash changes when app code changes #1315

Closed

Description

@kevinrenskers

I'm trying to split my vendor code from my app code and got it all working. However, every time I change some code in my app and create a new build, the vendor file gets a new chunkhash and thus is downloaded by the clients again. The contents are exactly the same though.

Here is a fully working small example showing the problem: https://github.com/kevinrenskers/chunkhash-problem

And as you can see, the contents of these files are 100% identical even though the chunkhash keeps changing:

screen shot 2015-07-30 at 22 47 59

Activity

  1. alexhancock commented on Jul 31, 2015

    @alexhancock

    I am also experiencing this issue

  2. sokra commented on Jul 31, 2015

    @sokra
    Member

    Looks like a conflict between the plugin and the lastest changes. You could try a previous webpack version (thay had a bug that [chunkhash] didn't change when the content change).

  3. kevinrenskers commented on Jul 31, 2015

    @kevinrenskers
    Author

    Any idea which webpack version I should try?

  4. kevinrenskers commented on Jul 31, 2015

    @kevinrenskers
    Author

    Seems that going back to 1.10.1 works. 1.10.2 and up break the chunkhash as described above.

  5. sokra commented on Jul 31, 2015

    @sokra
    Member

    It doesn't "break" it, it fixes it. The chunk hash should change when the hashes of the child chunks change... ;)

  6. kevinrenskers commented on Jul 31, 2015

    @kevinrenskers
    Author

    But if the contents of the vendor file don't change then its hash shouldn't change right? How else are we supposed to have long term caching if the filename changes every time I make a change in my app code?

  7. sokra commented on Jul 31, 2015

    @sokra
    Member

    That's caused by the chunk-manifest-webpack-plugin. It move the hashes of the child chunks out of the entry chunk. I propably need to rewrite it...

  8. kevinrenskers commented on Jul 31, 2015

    @kevinrenskers
    Author

    I don't really understand. Isn't the whole point of chunk-manifest-webpack-plugin to remove the child chunk hashes exactly so that the contents of the entry chunk don't change and thus its hash should stay identical? It does work like that with 1.10.1.

    Yet, you're saying that 1.10.2 have actually fixed this rather then breaking it. So, is the chunk-manifest-webpack-plugin doing something wrong? Or webpack? Or in other words, how am I supposed to have a working setup where changing the app code does not change the vendor's file name? :) Like I said it seems to work with 1.10.1 but your comments confuse me..

    Are you able to get such a setup working with the latest webpack, as I've tried in the example project (linked above)?

  9. Zagitta commented on Aug 1, 2015

    @Zagitta

    I'm attempting the same setup as @kevinrenskers and naturally have run into the same issue. If we possibly can come up with a workaround I'd appreciate it 👍

  10. kevinrenskers commented on Aug 9, 2015

    @kevinrenskers
    Author

    Even going back to 1.10.1 only fixes the problem some of the time. Other times I create a build, the vendor file still gets a new file name. A fix would be extremely welcome.

  11. lsanwick commented on Aug 13, 2015

    @lsanwick

    We're seeing this issue as well, any consistent fix would be great.

  12. airwin commented on Aug 14, 2015

    @airwin

    same problem. I remove the chunkHash and use my own hash now :(.

  13. lsanwick commented on Aug 14, 2015

    @lsanwick

    If you're willing to share, what method are you using to produce a hash?

  14. airwin commented on Aug 18, 2015

    @airwin

    @lsanwick I just add my release date after the script path in the html file (eg: lib.js?v=20150818). It's a little stupid and all of this is unnecessary if webpack's chunkHash works corretly. :(

  15. 175 remaining items

  16. chen86860 commented on Nov 13, 2017

    @chen86860

    Just named the vendor can solve this problem 😆

    code:

    ···
    new webpack.optimize.CommonsChunkPlugin({
          names: 'vendor',
          minChunks: Infinity,
          filename: 'vendor.bundle.js',
     })
    ···
    
  17. michaelBenin commented on Dec 13, 2017

    @michaelBenin

    Anyone else coming here needing a solution, just create your own md5 hash.

    const crypto = require('crypto');
    const vendorList = [/* list of vendor files */];
    const vendorHash = crypto.createHash('md5').update(vendorList.join('')).digest('hex');
    

    Use vendorHash in the vendor filename options:

    filename: `vendor.${vendorHash}.js

  18. michaelBenin commented on Dec 15, 2017

    @michaelBenin

    Regarding my comment above - that won't work as the bundle is referenced in the vendor file.

  19. NeoVance commented on Jan 1, 2018

    @NeoVance

    @earslap if your cache does not invalidate when the contents of a file changes than perhaps you should look into fixing that.

    Personally, I don't understand the obsession with using hashes in file names. There are far more simple, and easy to use methods of versioning files, and cache busting. This really isn't even an issue in webpack's wheel house to solve for you.

    I feel like this is not something the webpack maintainers should worry about. This is not really webpack's role to fill.

  20. michael-wolfenden commented on Jan 2, 2018

    @michael-wolfenden

    @NeoVance curious to hear what alternatives there are to file hashing

  21. michaelBenin commented on Jan 2, 2018

    @michaelBenin

    @michael-wolfenden prior to webpack hashes and manifest, we versioned static files using the git sha or build number, as well as setting Cache-Control: max-age=31536000

  22. michael-wolfenden commented on Jan 2, 2018

    @michael-wolfenden

    @NeoVance @michaelBenin the issue with using the git sha or version number is that if you doing continuous deployment and depoying multiple times a day, the vendor bundle version constantly changes with changes to the app bundle version thus invalidating it's cache. This is the problem that file hashes are intended to solve.

  23. dalimian commented on Jan 26, 2018

    @dalimian

    @earslap had the same issue, @sokra wonder if this issue is gonna be addressed with webpack4 since you are rewriting treeshaking. I hope wp4 gets long term caching right, we been burned with it 3 times now with webpack 2-3

    I am willing to help with the work

  24. maksimsemenov commented on Feb 9, 2018

    @maksimsemenov

    @michaelBenin can you please explain a little bit more why custom vendor hash will not work. I mean what will happen if bundle had changed, but vendor file still referencing the old bundle. Will it cause any errors?
    I was thinking of using it because all other approaches end with different hashes after CI builds, even if vendors were not changed. So want to know what caveats are here.

  25. michaelBenin commented on Feb 9, 2018

    @michaelBenin

    @maksimsemenov ~

    First off we didn't get this working as intended, this issue is still open.

    Basically we found that the vendor file has a reference of the app.js and that caused an error breaking JS.

  26. malliapi commented on Apr 29, 2018

    @malliapi

    is this still happening for webpack 4?

  27. edvardchen commented on May 3, 2018

    @edvardchen

    To a certain extent, webpack 4 improved this situation, at least reducing the frequency of vendor hash changes, but the problem still exists.
    See full code here
    First,npm run build, output
    image
    If you just modify src/client.js, the vendor file's hash will remain unchanged unless your modified part changes the count of split chunks.

    Like, comment one async import statement in src/client.js:

    import React from 'react';
    
    import { render } from 'react-dom';
    
    // import('./App');

    Then npm run build would output
    image
    Why? Because the vendors~app file still has a chunkId.

    // head line in vendor-app file. This chunk Id is 1.
    (window["webpackJsonp"] = window["webpackJsonp"] || []).push([[1],{

    Maybe we need a special way to treat initial chunk. Treat that they are already installed without checking ?

  28. alexander-akait commented on May 3, 2018

    @alexander-akait
    Member

    I close this issue due with a very large number of questions/posts with very difference problems (include deprecated webpack versions). It's also hard to understand exactly what the problem - in the configuration or it's a real bug. Also please read https://medium.com/webpack/predictable-long-term-caching-with-webpack-d3eee1d3fa31 (some steps no needs because it is already fixed in webpack). Feel free create new issue with minimum reproducible test repo.

    In short ways:

    webpackConfig.output = {
        chunkFilename: '[name]-[contenthash].chunk.js',
        filename: '[name]-[contenthash].js'
    };
    
    webpackConfig.plugins = [
       // ------------------------------------
        // Long Term Caching
        // ------------------------------------
        // More information https://medium.com/webpack/predictable-long-term-caching-with-webpack-d3eee1d3fa31
        new webpack.NamedChunksPlugin(chunk => {
          if (chunk.name) {
            return chunk.name;
          }
    
          // eslint-disable-next-line no-underscore-dangle
          return [...chunk._modules]
            .map(m =>
              path.relative(
                m.context,
                m.userRequest.substring(0, m.userRequest.lastIndexOf("."))
              )
            )
            .join("_");
        }),
        new webpack.HashedModuleIdsPlugin()
    ];

    Webpack@5 will have better long term caching out of box. Thanks!

  29. locked as off topic and limited conversation to collaborators on May 3, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions