I noticed that a new JavaScript file was generated with the same name as the old one, even though its contents had changed.
I created a sample project in this repository:
https://github.com/dobesv/parcel-import-bug
If the contents of a generated JavaScript file change in any significant way, so should the hash in its filename.
As you can see in the below transcript, the contents of the generated JavaScript file are modified, but its hash doesn't change.
$ echo a>template5.html
$ parcel build index.html -d dist-a
โจ Built in 1.24s.
dist-a/parcel-import-bug.a9b3581e.js 299.6 KB 19.34s
dist-a/controller.1cfadc83.js 87.37 KB 220ms
dist-a/controller.343f9052.js 1.23 KB 173ms
dist-a/index.html 245 B 5ms
dist-a/parcel-import-bug.bfb7fe78.urls 31 B 102ms
dist-a/test.ae9c52ee.css 20 B 12ms
dist-a/template5.7deadfab.html 2 B 193ms
dist-a/parcel-import-bug.bfb7fe78.json 0 B 103ms
dist-a/controller.343f9052.map 0 B 209ms
dist-a/parcel-import-bug.e3817f33.map 0 B 19.26s
dist-a/controller.1cfadc83.map 0 B 255ms
$ echo b>template5.html
$ parcel build index.html -d dist-b
โจ Built in 1.30s.
dist-b/parcel-import-bug.a9b3581e.js 299.6 KB 20.44s
dist-b/controller.1cfadc83.js 87.37 KB 227ms
dist-b/controller.343f9052.js 1.23 KB 182ms
dist-b/index.html 245 B 3ms
dist-b/parcel-import-bug.bfb7fe78.urls 31 B 102ms
dist-b/test.ae9c52ee.css 20 B 15ms
dist-b/template5.fc4c8ece.html 2 B 190ms
dist-b/parcel-import-bug.bfb7fe78.json 0 B 101ms
dist-b/controller.343f9052.map 0 B 217ms
dist-b/parcel-import-bug.e3817f33.map 0 B 20.34s
dist-b/controller.1cfadc83.map 0 B 260ms
(env) 13:40:40 ~/parcel-import-bug
$ diff dist-a/parcel-import-bug.a9b3581e.js dist-b/parcel-import-bug.a9b3581e.js
474,475c474,475
< module.exports={html:"/template5.7deadfab.html"};
< },{"./template5.html":[["template5.7deadfab.html",198],198]}],202:[function(require,module,exports) {
---
> module.exports={html:"/template5.fc4c8ece.html"};
> },{"./template5.html":[["template5.fc4c8ece.html",198],198]}],202:[function(require,module,exports) {
Not clear yet why this is the case. Maybe the hash in the filename isn't calculated from the file contents, but something else?
When deploying a new version of the app, I assume that the filenames will change when their contents do, and set long cache expiry times on those files. If this assumption is broken, our app fails to load or various other weird problems can occur.
https://github.com/dobesv/parcel-import-bug
| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | 1.8.1
| Node | 9.11.1
| npm/Yarn | 1.6.0
| Operating System | Ubuntu Xenial (Linux Mint)
I tried setting NODE_ENV=production
during the build, and this resulted in more differences between the files but they still had the same hashed filename.
I think maybe the filename for a package with a bunch of js files bundled together isn't including files that aren't actually bundled into the file as part of its hash, even if it depends on those files.
As I've dug into this a bit more, it seems like the hash of a JS bundle will update if a CSS file it depends on is changed, because a CSS file generates an empty js string. But if you have an html dependency, it doesn't generate any js at all (not even an empty string) which means that changes to the html won't cause the hash of the bundle to change.
I guess importing HTML files isn't officially supported by Parcel yet, so perhaps this is something I'll have to workaround in my plugin.
However, I'm having trouble figuring out a way to get around this in the plugin. Any help from someone who knows the workings and plans for parcel would be much appreciated.
So to try and summarize a bit:
js
output (this does include JavaScript and CSS files)js
file but its hash is calculated only based on the names of files it includes, not their contentsA bit of a puzzle here ...
Well, I'm implementing a workaround in my plugin to just run a sort of "sub build" to calculate the hashes of its dependencies and insert a hash of those hashes into its own output. It seems like the structure of Parcel doesn't accomodate the idea of a file depending on the names of other files.
My workaround isn't working properly any more - it seems to stall out the build. But this issue remains. I have also recreated this as an automated test in the parcel test suite:
https://github.com/dobesv/parcel/pull/new/indirect-import-hash-issue
I created a plugin for this as a temporary workaround for anyone affected by this issue. https://github.com/dobesv/parcel-plugin-bundle-deep-hash
https://github.com/ChALkeR/parcel-cache-fail -- here is my description of the problem.
this is a huge issue ; it makes caching with code splitting impossible.
I have submitted a fix but it has not been accepted or rejected. Not sure what else to do here. I do wonder why so few people are complaining about this issue, though. Maybe it's not as bad as it seems and there's just something we few are doing wrong.
@dobesv Is there a PR? Would like to see it if possible :) I couldn't find it by your name. Thx btw!
@dobesv nice solution! thank you. Btw this is a huge bug indeed.
@wxsms Do you have a reproduction repo for the latest version of parcel?
@dobesv nope. But it's easy to reproduce, just make some lazy load scripts and change the deepest script's content, it results in the entry script's hash not changed.
@wxsms I'm just thinking that if they have a reproduction repo using the latest version of parcel they will be more likely to fix it than if they have to reproduce it themselves.
I just tested with Parcel 2, are you sure this is still occurring?
@mischnic Sry I'm not using Parcel2, the latest version on NPM is 1.12.4, that's my version.
Have not notice yet there is v2 since this. It's kind of invisible to normal users ๐ข
@mischnic I am using Parcel 1 and facing same issue. Will the fix be rolled out to Parcel 1 too?
My suggestion, to be frank, is to not use Parcel. I have this one project that uses parcel and I regret using it. I've been using Webpack in other projects and it's better in every way except initial setup effort.
@dobesv Sadly, I do not have choice here, my project is such that have to look for both webpack and parcel bundler support.
Closing. Please use parcel 2.
Most helpful comment
I have submitted a fix but it has not been accepted or rejected. Not sure what else to do here. I do wonder why so few people are complaining about this issue, though. Maybe it's not as bad as it seems and there's just something we few are doing wrong.