Laravel-mix: Manifest hash won't change!

Created on 4 Apr 2017  ·  17Comments  ·  Source: JeffreyWay/laravel-mix

  • Laravel Mix Version: 0.10.0
  • Node Version: v7.7.3
  • NPM Version: 4.1.2
  • OS: 10.12.4

Description:

manifes.js hash won't change even app or vendor names had changed. If manifest is in browsers cache it will load the old app and vendor files.

Steps To Reproduce:

npm run production

<script src="/js/manifest.d41d8cd98f00b204e980.js"></script>
<script src="/js/vendor.0644ae2bcbd1e2178134.js"></script>
<script src="/js/app.d3d968be03d7943f18be.js"></script>
<script type="text/javascript" src="/js/home.40299b3f79c3bf7007fc.js"></script>

change something in app js files
npm run production

<script src="/js/manifest.d41d8cd98f00b204e980.js"></script>
<script src="/js/vendor.0644ae2bcbd1e2178134.js"></script>
<script src="/js/app.4b2f4c54fb528e83e8f0.js"></script>
<script type="text/javascript" src="/js/home.40299b3f79c3bf7007fc.js"></script>

As you can see, app change from /js/app.d3d968be03d7943f18be.js to /js/app.4b2f4c54fb528e83e8f0.js but manifest is the same: /js/manifest.d41d8cd98f00b204e980.js

Most helpful comment

This is a "bug" in webpack-chunk-hash (forked from webpack-md5-hash which had the same bug), you can find a lot of official webpack example that show a manifest.d41d8cd98f00b204e980.jsfile.

see some related issue:
https://github.com/alexindigo/webpack-chunk-hash/issues/7
https://github.com/erm0l0v/webpack-md5-hash/issues/9

I could trash fix it in my webpack.mix.js file by disabling the webpack-chunk-hash plugin, this rollback to the default webpack versioning which is able to generate a correct hash for the manifest file:

const { mix } = require('laravel-mix');

let WebpackChunkHash = function () {};
WebpackChunkHash.prototype.apply = () => {};
// Replace WebpackChunkHashPlugin with an empty function
mix.plugins.WebpackChunkHashPlugin = WebpackChunkHash;

All 17 comments

How are you requiring the stuff from manifest.js to app.js? Seems weird that changing something in app.js means you need to cache-bust the one you have't modified.

@bbashy in the manifest code webpack calls the other files by their name. So if for example app hash changes manifest.js content changes too, so it should change it's name (hash) so it doesn't get cached (at least I think it should).

!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,u){for(var a,i,f,s=0,p=[];s1,o[e]=void 0)}if(0===o[e])return Promise.resolve();if(o[e])return o[e][2];var t=new Promise(function(n,r){o[e]=[n,r]});o[e][2]=t;var c=document.getElementsByTagName("head")[0],u=document.createElement("script");u.type="text/javascript",u.charset="utf-8",u.async=!0,u.timeout=12e4,n.nc&&u.setAttribute("nonce",n.nc),u.src=n.p+"js/"+({0:"/js/app",1:"/js/vendor",2:"/js/home"}[e]||e)+"."+{0:"6252ed5f028a0fb93359",1:"7ce69adf345b3cd7fce2",2:"55f54d3ecb3f84d73f16"}[e]+".js";var a=setTimeout(r,12e4);return u.onerror=u.onload=r,c.appendChild(u),t},n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,r,t){n.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,"a",r),r},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n.oe=function(e){throw e}}([]);

Need something to reproduce, really.

Wait - how do I end up with the same manifest hash you have?
I have the same problem and I also have the manifest hash: d41d8cd98f00b204e98.

In my case, I can change my files and the manifest hash stays the same but the content changes.

My webpack.mix.js file:

let mix = require('laravel-mix').mix

mix.sass('resources/assets/sass/app.scss', 'public/css')
   .js('resources/assets/js/frontend/frontend.js', 'public/js')
   .js('resources/assets/js/backend/backend.js', 'public/js')
   .extract([
       'vue',
       'vue-router',
       'vuex',
       'vuex-router-sync',
       'vue-resource',
       'vue-resource-nprogress',
       'word-wrap',
       'bugsnag-js',
       // 'echarts',
       'moment',
       'nprogress',
       'smooth-scroll',
       'sweetalert'
   ])
   .sourceMaps();

if(mix.config.inProduction) mix.version();

As you can see I have two entry files: resources/assets/js/frontend/frontend.js and resources/assets/js/frontend/backend.js

The bug happens if you run following steps:

  1. npm run production
 DONE  Compiled successfully in 40051ms                                                                                                   5:06:19 PM

                               Asset       Size  Chunks                    Chunk Names
 /js/backend.7b67abe538b98747fb13.js     117 kB       5  [emitted]         /js/backend
        js/0.78d6543807cb5fa5e184.js     394 kB    0, 1  [emitted]  [big]
        js/2.f11a8986dafd5c4a1e50.js    55.3 kB       2  [emitted]
        js/3.264849e4ac8e12aab1b4.js    12.7 kB       3  [emitted]
/js/frontend.b60627b3681a90ac5c14.js     152 kB       4  [emitted]         /js/frontend
        js/1.3674fe15a6664406da74.js     381 kB       1  [emitted]  [big]
  /js/vendor.ef11cddd36462a120e1a.js     194 kB       6  [emitted]         /js/vendor
         mix.dd4cb43f66c4f16cea33.js  115 bytes       7  [emitted]         mix
/js/manifest.d41d8cd98f00b204e980.js    1.63 kB       8  [emitted]         /js/manifest
   /css/app.3b9cdc12e01b139187b7.css     154 kB       7  [emitted]         mix
                   mix-manifest.json  340 bytes          [emitted]
  1. change bootstrap.js which is included in booth entries (backend.js and frontend.js)

  2. npm run production

 DONE  Compiled successfully in 38309ms                                                                                                   5:08:35 PM

                               Asset       Size  Chunks                    Chunk Names
 /js/backend.9f86ee8474fa2d14999b.js     117 kB       5  [emitted]         /js/backend
        js/0.78d6543807cb5fa5e184.js     394 kB    0, 1  [emitted]  [big]
        js/2.f11a8986dafd5c4a1e50.js    55.3 kB       2  [emitted]
        js/3.264849e4ac8e12aab1b4.js    12.7 kB       3  [emitted]
/js/frontend.20e9d8dab7749bb3d18f.js     152 kB       4  [emitted]         /js/frontend
        js/1.3674fe15a6664406da74.js     381 kB       1  [emitted]  [big]
  /js/vendor.ef11cddd36462a120e1a.js     194 kB       6  [emitted]         /js/vendor
         mix.dd4cb43f66c4f16cea33.js  115 bytes       7  [emitted]         mix
/js/manifest.d41d8cd98f00b204e980.js    1.63 kB       8  [emitted]         /js/manifest
   /css/app.fc8e37303663ac53fad2.css     154 kB       7  [emitted]         mix
                   mix-manifest.json  340 bytes          [emitted]

As you can see, the frontend and the backend hash changes, but the manifest doesn't.
But the content of the manifets file changes.

Tell me what additional information do you need for this issue.

@strebl thats exactly my problem! Thanks for explant it better! 👍

Have you narrowed it down to a particular function? Can you mock up a test to reproduce it?

Same issue here!

I also got the same hash on my manifest file: d41d8cd98f00b204e980

I tried to find the bug but couldn't debug anything (no console log or Error output), didn't find any contributing guidelines or webpack debugging guide to help me :/

It looks like this is the md5 hash of an empty file:

simple test.js file:

let md5 = require('md5');
console.log(md5(''));

output: d41d8cd98f00b204e9800998ecf8427e

This is a "bug" in webpack-chunk-hash (forked from webpack-md5-hash which had the same bug), you can find a lot of official webpack example that show a manifest.d41d8cd98f00b204e980.jsfile.

see some related issue:
https://github.com/alexindigo/webpack-chunk-hash/issues/7
https://github.com/erm0l0v/webpack-md5-hash/issues/9

I could trash fix it in my webpack.mix.js file by disabling the webpack-chunk-hash plugin, this rollback to the default webpack versioning which is able to generate a correct hash for the manifest file:

const { mix } = require('laravel-mix');

let WebpackChunkHash = function () {};
WebpackChunkHash.prototype.apply = () => {};
// Replace WebpackChunkHashPlugin with an empty function
mix.plugins.WebpackChunkHashPlugin = WebpackChunkHash;

Thanks @nicolasbeauvais !

So nothing to do with laravel-mix. I hope they'll fix it soon.
I think many people don't notice the bug.

Excited, I thought it's a bug of webpack once...
Here's my monkey-patch:

const Module = require('module')
const origRequire = Module._load
Module._load = function(request, parent, isMain) {
  if (request === 'webpack-chunk-hash') {
    const ret = function () {}
    ret.prototype.apply = () => {}
    return ret
  }
  return origRequire(request, parent, isMain)
}

This is how we solved this issue in our apps. After every mix recompile, we update mix-manifest.json with random integers at the end of the file.

.version()
.then((stats) => {

  // We're appending random int to the versioned files to guarantee
  // that all assets are fully re-cached on every new version (md5 sucks at this)

  let file = File.find(stats.compilation.options.output.path + '/mix-manifest.json');
  let assets = JSON.parse(file.read());

  let new_assets = {};
  Object.keys(assets).forEach(function (item) {
    let addedTimestamp = '-' + Date.now();
    new_assets[item] = assets[item] + addedTimestamp;
  });

  file.write(JSON.stringify(new_assets, null, 2));
})

@JPurinsh this is a non-problem now. It's been fixed in the newer versions since it uses query string.

Our problem was having the same md5 after an update if only a few lines have changed. Laravel mix is still using md5 to generate the hash. Our solution gets rid of this issue completely whilst also adding a way to see when the asset was actually generated.

@JPurinsh Haven't had the problem for years now. Even when only changing 1 letter.

¯_(ツ)_/¯
Well, we struggled for it at least once every month. The bigger the file, the more likely you're to get this issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Micaso picture Micaso  ·  3Comments

pixieaka picture pixieaka  ·  3Comments

sdebacker picture sdebacker  ·  3Comments

rlewkowicz picture rlewkowicz  ·  3Comments

hasnatbabur picture hasnatbabur  ·  3Comments