Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS hash fails to change when asset URL changes #3415

Closed
jakearchibald opened this issue Mar 2, 2020 · 7 comments · Fixed by #4543 or #4549
Closed

JS hash fails to change when asset URL changes #3415

jakearchibald opened this issue Mar 2, 2020 · 7 comments · Fixed by #4543 or #4549

Comments

@jakearchibald
Copy link
Contributor

jakearchibald commented Mar 2, 2020

In this demo, both src1 and src2 are built. The only difference between the two is the content of some-asset.txt.

Expected Behavior

The hash of both the JS and asset is different between builds, since the JS imports the asset, the content of its file has changed.

Actual Behavior

Only the hash of the txt file changes.

@lukastaegert
Copy link
Member

Another important test case for a reimplemented hashing algorithm.

@jakearchibald
Copy link
Contributor Author

This also impacts modules containing import.meta.ROLLUP_FILE_URL_referenceId that point to chunks.

With assets, you can kinda work around it with augmentChunkHash, using the buffer of the asset to augment the hash, but that isn't really possible with chunks, since they have dependencies of their own.

yyx990803 added a commit to vitejs/vite that referenced this issue Feb 2, 2021
@sebastianseilund
Copy link

A workaround that seems to work for me is to add a hash of the asset's source as a JS comment together with import.meta.ROLLUP_FILE_URL_referenceId. So instead of the following from https://github.com/jakearchibald/rollup-hash-bug/blob/master/lib/asset-plugin.js :

return `export default import.meta.ROLLUP_FILE_URL_${this.emitFile({
  type: 'asset',
  source: await fs.readFile(realId),
  name: basename(realId),
})}`;

Do this instead:

import {createHash} from 'crypto'
// ...
const source = await fs.readFile(realId)
const referenceId = this.emitFile({
  type: 'asset',
  source,
  name: basename(realId),
})
const hash = createHash('sha256').update(source).digest('hex').slice(0, 8)
return `export default import.meta.ROLLUP_FILE_URL_${referenceId}; /* asset-hash:${hash} */`

Rollup will now consider the importing JS module's source as being different since the comment depends on the asset source hash, causing a different JS hash (which is what we want). The JS comment is stripped by minification later (if using).

@lukastaegert
Copy link
Member

Fix at #4543

@rollup-bot
Copy link
Collaborator

This issue has been resolved via #4543 as part of rollup@3.0.0-7. Note that this is a pre-release, so to test it, you need to install Rollup via npm install rollup@3.0.0-7 or npm install rollup@beta. It will likely become part of a regular release later.

@rollup-bot
Copy link
Collaborator

This issue has been resolved via #4543 as part of rollup@3.0.0-8. Note that this is a pre-release, so to test it, you need to install Rollup via npm install rollup@3.0.0-8 or npm install rollup@beta. It will likely become part of a regular release later.

@rollup-bot
Copy link
Collaborator

This issue has been resolved via #4543 as part of rollup@3.0.0. You can test it via npm install rollup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants