insin / nwb

A toolkit for React, Preact, Inferno & vanilla JS apps, React libraries and other npm modules for the web, with no configuration (until you need it)
Other
5.57k stars 332 forks source link

Chunk hashes not changing (webpack-md5-hash) #301

Closed grahamlyus closed 7 years ago

grahamlyus commented 7 years ago

This issue is a:

I recently encountered a problem where I changed some imports in a split chunk, which caused the app chunk output to change without it's hash changing. Because the app chunk is cached, mayhem ensues due to webpack exports no longer being consistent between chunks.

I've found two workarounds:

I've set up a small test project that can reproduce the issue: https://github.com/grahamlyus/nwb-chunkhash-issue

Default nwb settings

split.js:

import { CONSTANT_2 } from './constants.js'

export default function something() {
  console.log(CONSTANT_2)
}

yarn build:

File sizes after gzip:

  dist/vendor.16d0c842.js  48.32 KB
  dist/app.f709a8e5.js     617 B
  dist/app.8b882e77.css    485 B
  dist/0.9e910660.js       197 B

Changing the import in split.js:

import { CONSTANT_3 } from './constants.js'

export default function something() {
  console.log(CONSTANT_3)
}

yarn build:

File sizes after gzip:

  dist/vendor.16d0c842.js  48.32 KB
  dist/app.f709a8e5.js     617 B
  dist/app.8b882e77.css    485 B
  dist/0.e79eb82d.js       194 B

diff of app.f709a8e5.js c changes from 2 to 3 which won't be picked up as the script will be cached as the filename has not changed:

wdiff -3t dist2/app.f709a8e5.js dist3/app.f709a8e5.js

======================================================================
 a=1,c=2},pnOm:function(e,n,t){"use a=1,c=3},pnOm:function(e,n,t){"use

diff of split chunk only the chunk hash has changed:

wdiff -3 dist2/0.9e910660.js dist3/0.e79eb82d.js

======================================================================
 [-sourceMappingURL=0.9e910660.js.map-] {+sourceMappingURL=0.e79eb82d.js.map+}
======================================================================

Workaround 1 - webpack-md5hash removed from (createWebpackConfig) config

import { CONSTANT_2 } from './constants.js':

File sizes after gzip:

  dist/vendor.fa7056a8.js  48.32 KB
  dist/app.aa073196.js     617 B
  dist/app.8b882e77.css    485 B
  dist/0.c93ba2c7.js       197 B

import { CONSTANT_3 } from './constants.js':

File sizes after gzip:

  dist/vendor.fa7056a8.js  48.32 KB
  dist/app.37a7594b.js     617 B
  dist/app.8b882e77.css    485 B
  dist/0.cefbb21f.js       196 B

diff of app chunks (hash has changed):

wdiff -3t dist2/app.aa073196.js dist3/app.37a7594b.js

======================================================================
 a=1,c=2},pnOm:function(e,n,t){"use a=1,c=3},pnOm:function(e,n,t){"use
======================================================================
 sourceMappingURL=app.aa073196.js.map sourceMappingURL=app.37a7594b.js.map

The split chunk is identical, and that is ok, as the reference c now points to the other import.

Workaround 2 - babel plugin transform-es2015-modules-commonjs in nwb.config.js

import { CONSTANT_2 } from './constants.js':

File sizes after gzip:

  dist/vendor.16d0c842.js  48.32 KB
  dist/app.f4a5ad10.js     639 B
  dist/app.8b882e77.css    485 B
  dist/0.de474a6e.js       207 B

import { CONSTANT_3 } from './constants.js':

File sizes after gzip:

  dist/vendor.16d0c842.js  48.32 KB
  dist/app.f4a5ad10.js     639 B
  dist/app.8b882e77.css    485 B
  dist/0.21fb3016.js       208 B

app chunk is identical

split chunk diff correctly uses CONSTANT_3:

wdiff -3t dist2/0.de474a6e.js dist3/0.21fb3016.js

======================================================================
 t(){console.log(c.CONSTANT_2)}Object.defineProperty(o,"__esModule",{value:!0}),o.default=t;var t(){console.log(c.CONSTANT_3)}Object.defineProperty(o,"__esModule",{value:!0}),o.default=t;var
======================================================================
 sourceMappingURL=0.de474a6e.js.map sourceMappingURL=0.21fb3016.js.map

There are a couple of issues on the https://github.com/erm0l0v/webpack-md5-hash/issues repo alluding to similar problems.

I'm using Workaround 2 as there's no external way to use Workaround 1. It disables tree-shaking, but I haven't seen much of a difference in chunk sizes to be honest - I'm not sure they've figured it out completely yet, for instance: https://github.com/webpack/webpack/issues/2867. This also makes more sense that only the split chunk changes as that is where the original source was changed.

It would be nice to remove webpack-md5-hash even if via nwb.config.js somehow.

Thoughts?

loklaan commented 7 years ago

Thanks for going to the effort to make this issue - details are :100:.

I can't get around to jumping into an issue like this atm, but I'll dump some notes so I can get into it later (or ideally @insin will jump in).

Notes:

Related issues for reference: webpack-md5-hash create-react-app webpack related nwb issue

insin commented 7 years ago

Thanks for the thorough investigation and the repro repo 👍

Will drop use of md5-hash in this case, as it looks like Webpack 2 now does what you'd expect with chunk hashes.

It also used to be the case that if you just changed some extracted CSS, the chunkhash of JS emitted from the same chunk would also change. I'm not seeing that any more and I can confirm Workaround 1 works for me as for you.