-
Notifications
You must be signed in to change notification settings - Fork 20
Description
Which component is affected?
Build process
Describe the bug
What is happening
Given the same source code, it is possible to have different assets generated by a production build, with different content hash filenames.
What is expected
Given the same source code, there is no variability in the way assets are generated, and the same assets (and, by extension, the content hashes in those assets' filenames) are generated on every production build run.
Why this is a problem
When creating a production build for an Astro + Qwik app, there can be scenarios where one run of the build has generated server assets which point to non-existent client side assets. This is especially true for deployment scenarios where client assets are pushed to an external location (say, an AWS S3 bucket). If for some reason, a second build is run, there's no guarantee that that run's built server assets will point to the same client side assets as were built and uploaded to the external location previously.
Reproduction
https://github.com/maxrpeterson/qwik-astro-test-build-asset-hash-changing
Steps to reproduce
Reproduction steps
-
npm i npm run build
- Make note of the hash prefix of
dist/assets/*-bundle-graph.json
file - Without changing the source code at all, keep running
npm run build
until a different hashed*-bundle-graph.json
file is seen - Compare file tree of
dist
folder from one build to the next (it helps to copy each run to a separate location to compare between builds)
System Info
System:
OS: macOS 15.5
CPU: (12) arm64 Apple M2 Max
Memory: 3.46 GB / 32.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 22.17.1 - ~/.nvm/versions/node/v22.17.1/bin/node
npm: 10.9.2 - ~/.nvm/versions/node/v22.17.1/bin/npm
Browsers:
Chrome: 138.0.7204.158
Safari: 18.5
Additional Information
Additional Information
The two variations of the built code I've observed have also been committed to the example repo for demonstration purposes. It's possible there are more than two possible build variations, but I've definitely seen at least the two.
Note that when the hash prefix of the *-bundle-graph.json
file is different, there are also changes to several of the other assets in the dist
folder. Many of these are "snowball effect" changes, where a change to one generated module causes the content hash of that module to be different, which is then imported into another module with the different content hash, causing that file to in turn have a different content hash, and so on.
However, if you look at the files that have meaningful changes, you'll see that the changes are from the ordering of variables in the files.
// dist-run-CcgmEgmB/build/q-DnyphD2t.js
const o = "_componentB_1n717_1",
t = {
componentB: o
},
n = "_componentA_fov7x_1",
s = {
componentA: n
};
export {
t as a, s
};
// dist-run-BnTTJgbo/build/q-DJnZVtP7.js
const o = "_componentA_fov7x_1",
t = {
componentA: o
},
n = "_componentB_1n717_1",
s = {
componentB: n
};
export {
s as a, t as s
};
Removing the import
of the styles (e.g. import styles from './componentA.module.scss
) from both components in src/components
seems to fix the issue and prevent the variable declarations from swapping and causing builds with different hashes. I haven't been able to reproduce this issue in a simple reproduction app without the style imports, but I also don't have any insight as to whether the CSS modules imports are integral to the issue or not.
In the real app where we first noticed this, when inspecting one of the generated modules with changes between builds, it appears that ordering of non-CSS imports is the cause of the variability in at least one case. That is, one module is being imported out of order with another in a generated file, causing the change in the file and by extension the content hash.
Also worth noting, in the real app where we first noticed this issue (not just a minimal reproduction app), we are using SCSS for style files, but as demonstratred here in this minimal reproduction app, the problem is reproducible with vanilla CSS as well. Neither changing to use lightningcss
as the CSS transformer, nor using the sass-embedded
library (instead of regular sass
library) had any effect on the issue, in both our real app and this minimal reproduction app.
Other things already tried
There was this issue in Vite where some users said they were seeing similar issues and were able to fix it using the build.rollupOptions.maxParallelFileOps
vite config property. I tried this as well, however was still seeing variability in the content hashes after running the build.