Bun.build output hash doesn't account for dynamic import
What version of Bun is running?
1.1.18+5a0b93523
What platform is your computer?
Darwin 23.5.0 arm64 arm
What steps can reproduce the bug?
file build.ts:
const result = await Bun.build({
entrypoints: ["1.ts", "2.ts"],
splitting: true,
minify: true
});
for (const output of result.outputs) {
console.log(output.path, ":", output.hash);
console.log(
(await output.text())
.split("\n")
.map((x) => "| " + x)
.join("\n")
);
}
file 1.ts:
import("./3.ts");
file 2.ts:
import("./3.ts");
file 3.ts:
import { randomInt } from "crypto" with { type: 'macro' };
export const random = randomInt(100)
run build.ts with bun
What is the expected behavior?
the generated hash for entrypoint file will change when 3.ts changed (it use random, so will change every time)
What do you see instead?
got same hash for entrypoint file
./1.js : 8366f94ce3fac3cc
| import{a as i} from"./chunk-12ec8b15ea59dbbf.js";import("./chunk-647af94fa6f1c725.js");
|
./2.js : 0a07085d284c9942
| import{a as i} from"./chunk-12ec8b15ea59dbbf.js";import("./chunk-647af94fa6f1c725.js");
|
./chunk-647af94fa6f1c725.js : 647af94fa6f1c725
| import"./chunk-12ec8b15ea59dbbf.js";var o=61;export{o as random};
|
./chunk-12ec8b15ea59dbbf.js : 12ec8b15ea59dbbf
| var d=((a)=>typeof require!=="undefined"?require:typeof Proxy!=="undefined"?new Proxy(a,{get:(b,c)=>(typeof require!=="undefined"?require:b)[c]}):a)(function(a){if(typeof require!=="undefined")return require.apply(this,arguments);throw Error('Dynamic require of "'+a+'" is not supported')});
| export{d as a};
|
./1.js : 8366f94ce3fac3cc
| import{a as i} from"./chunk-12ec8b15ea59dbbf.js";import("./chunk-7e1613d5fcd5e8e0.js");
|
./2.js : 0a07085d284c9942
| import{a as i} from"./chunk-12ec8b15ea59dbbf.js";import("./chunk-7e1613d5fcd5e8e0.js");
|
./chunk-7e1613d5fcd5e8e0.js : 7e1613d5fcd5e8e0
| import"./chunk-12ec8b15ea59dbbf.js";var o=51;export{o as random};
|
./chunk-12ec8b15ea59dbbf.js : 12ec8b15ea59dbbf
| var d=((a)=>typeof require!=="undefined"?require:typeof Proxy!=="undefined"?new Proxy(a,{get:(b,c)=>(typeof require!=="undefined"?require:b)[c]}):a)(function(a){if(typeof require!=="undefined")return require.apply(this,arguments);throw Error('Dynamic require of "'+a+'" is not supported')});
| export{d as a};
|
Additional information
I use randomInt is only for PoC, normal editing will also cause this bug
macros aren't yet part of the hash
macros aren't yet part of the hash @Jarred-Sumner
Not only macro, I use macro is just for demo, but actually it affect normal code...
aka I changed the 3.ts to:
export const random = 123
got output:
./1.js : 8366f94ce3fac3cc
| import{a as i} from"./chunk-12ec8b15ea59dbbf.js";import("./chunk-5999c678ee417930.js");
|
./2.js : 0a07085d284c9942
| import{a as i} from"./chunk-12ec8b15ea59dbbf.js";import("./chunk-5999c678ee417930.js");
|
./chunk-5999c678ee417930.js : 5999c678ee417930
| import"./chunk-12ec8b15ea59dbbf.js";var o=123;export{o as random};
|
./chunk-12ec8b15ea59dbbf.js : 12ec8b15ea59dbbf
| var d=((a)=>typeof require!=="undefined"?require:typeof Proxy!=="undefined"?new Proxy(a,{get:(b,c)=>(typeof require!=="undefined"?require:b)[c]}):a)(function(a){if(typeof require!=="undefined")return require.apply(this,arguments);throw Error('Dynamic require of "'+a+'" is not supported')});
| export{d as a};
|
for export const random = 345;, I got
./1.js : 8366f94ce3fac3cc
| import{a as i} from"./chunk-12ec8b15ea59dbbf.js";import("./chunk-3ddf2ce6941a9488.js");
|
./2.js : 0a07085d284c9942
| import{a as i} from"./chunk-12ec8b15ea59dbbf.js";import("./chunk-3ddf2ce6941a9488.js");
|
./chunk-3ddf2ce6941a9488.js : 3ddf2ce6941a9488
| import"./chunk-12ec8b15ea59dbbf.js";var o=345;export{o as random};
|
./chunk-12ec8b15ea59dbbf.js : 12ec8b15ea59dbbf
| var d=((a)=>typeof require!=="undefined"?require:typeof Proxy!=="undefined"?new Proxy(a,{get:(b,c)=>(typeof require!=="undefined"?require:b)[c]}):a)(function(a){if(typeof require!=="undefined")return require.apply(this,arguments);throw Error('Dynamic require of "'+a+'" is not supported')});
| export{d as a};
|
exactly same hash for different content
and the macro DOES affect the hash, but only for 3.ts the problem here is 1.ts and 2.ts
new minimal example (it affect the default chunk file naming)
1.ts:
import("./2.ts");
2.ts:
import("./3.ts");
3.ts:
console.log(1) // change the number manually
use command: bun build --outdir .build --splitting 1.ts
you will get something like this:
1.js 0.10 KB
3-c96b55aede2685f9.js 0.03 KB
2-8219168fb473146a.js 0.10 KB
1-10c8d92e4b9ccc65.js 0.38 KB
[3ms] bundle 3 modules
change the 3.ts and rebuild multiple times, you will get a bunch of 3-XXXX.js while 1/2.js keep same name
This issue can cause the CDN to provide old chunk files (because the generated file names are the same).
fixed in 1.1.21