-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
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
Non-deterministic build #13672
Comments
I have written a plugin that prints all the parameters in the transform hook. During two consecutive builds, although the order of their outputs is different, I found that there is only one instance where the content of the output differs after adjusting the order. plugins: [
function() {
return {
name: 'test',
transform: (...args) => {
console.log(args)
}
}
}()
] I have removed a significant amount of irrelevant code, so the hash of the artifact is different from the one in the repro. First build: [
'export { __moduleExports as default } from "C:/Users/admin/Projects/My/vite-non-deterministic-build-repro/node_modules/dayjs/dayjs.min.js";',
'\x00C:/Users/admin/Projects/My/vite-non-deterministic-build-repro/node_modules/dayjs/dayjs.min.js?commonjs-proxy'
]
�[2mdist/�[22m�[36massets/index-e2988d1d.js �[39m�[1m�[2m 1.10 kB�[22m�[1m�[22m�[2m │ gzip: 0.63 kB�[22m
�[2mdist/�[22m�[36massets/vendor-3bedaa96.js �[39m�[1m�[2m81.22 kB�[22m�[1m�[22m�[2m │ gzip: 32.73 kB�[22m
�[32m✓ built in 1.97s�[39m Second build: [
'import { getDefaultExportFromCjs } from "\x00commonjsHelpers.js";\n' +
'import { __require as requireDayjs_min } from "C:/Users/admin/Projects/My/vite-non-deterministic-build-repro/node_modules/dayjs/dayjs.min.js";\n' +
'var dayjs_minExports = requireDayjs_min();\n' +
'export { dayjs_minExports as __moduleExports };export default /*@__PURE__*/getDefaultExportFromCjs(dayjs_minExports);',
'\x00C:/Users/admin/Projects/My/vite-non-deterministic-build-repro/node_modules/dayjs/dayjs.min.js?commonjs-es-import'
]
�[2mdist/�[22m�[36massets/index-73275ff8.js �[39m�[1m�[2m 1.10 kB�[22m�[1m�[22m�[2m │ gzip: 0.63 kB�[22m
�[2mdist/�[22m�[36massets/vendor-2f895bab.js �[39m�[1m�[2m81.26 kB�[22m�[1m�[22m�[2m │ gzip: 32.75 kB�[22m
�[32m✓ built in 2.97s�[39m |
Facing the same issue! waiting for a fix. |
I'm seeing this issue as well. |
The workaround mentioned in #10506, setting |
The workaround in #10506 doesn't seem to work for me. I created a repo to try testing the workaround using the basic out-of-the-box base sveltekit app. Test repo is here https://github.com/derheld42/repro-vite-10506 |
Seems like Thanks for the simple repro (and sorry for not responding in the other issue). Got a few issues to juggle, but I'll try to check this deeper now to see if there's something that can be fixed. Also as explained in the upstream issue, the workaround would be: export default defineConfig({
build: {
commonjsOptions: {
strictRequires: true
}
}
}) |
vitejs/vite#13672 (comment) Still fails producing a deterministic build: npm run build mv build build1 npm run build diff -qr build build1
I tried the workaround in the above comment and it didn't create a deterministic build for me. I also tested it with derheld42/repro-vite-10506@a31754f and it doesn't produce a deterministic build. |
@derheld42 that seems to be a SvelteKit specific issue: sveltejs/kit#8948 You can fix it with: const config = {
kit: {
version: {
name: 'test' // something stable instead of default `Date.now()`
}
}
}; |
After adding After adding the |
Yes - that worked to make the built files deterministic - thank you! |
I'm also facing the same issue, Here is my dependencies, can anyone give me any hint which is causing this. "devDependencies": {
"@builder.io/qwik": "^1.2.15",
"@builder.io/qwik-city": "^1.2.15",
"@fastify/compress": "^6.2.1",
"@fastify/http-proxy": "^9.2.1",
"@fastify/static": "^6.10.1",
"@fullhuman/postcss-purgecss": "^5.0.0",
"@types/eslint": "8.44.1",
"@types/js-cookie": "^3.0.4",
"@types/lodash": "^4.14.199",
"@types/node": "^20.4.5",
"@typescript-eslint/eslint-plugin": "6.2.0",
"@typescript-eslint/parser": "6.2.0",
"autoprefixer": "^10.4.14",
"country-flag-icons": "^1.5.7",
"cssnano": "^6.0.1",
"eslint": "8.45.0",
"eslint-plugin-qwik": "^1.2.12",
"fastify": "^4.17.0",
"fastify-plugin": "^4.5.0",
"postcss": "8.4.27",
"postcss-import": "^15.1.0",
"postcss-nested": "^6.0.1",
"prettier": "3.0.0",
"purgecss": "^5.0.0",
"tailwindcss": "3.3.3",
"tw-elements": "1.0.0-alpha13",
"typescript": "5.1.6",
"undici": "5.22.1",
"vite": "4.4.7",
"vite-plugin-static-copy": "^0.17.0",
"vite-plugin-thumbhash-base64": "^0.0.2",
"vite-tsconfig-paths": "4.2.0"
},
"dependencies": {
"@fontsource-variable/dm-sans": "^5.0.3",
"@fontsource/dm-sans": "^5.0.14",
"@iconscout/unicons": "^4.0.8",
"@modular-forms/qwik": "^0.21.0",
"@svgx/vite-plugin-qwik": "^1.0.1",
"animate.css": "^4.1.1",
"date-fns": "^2.30.0",
"dayjs": "^1.11.10",
"flowbite": "^1.8.1",
"js-base64": "^3.7.5",
"js-cookie": "^3.0.5",
"libphonenumber-js": "^1.10.47",
"lodash": "^4.17.21",
"moick-qwik-fixed": "^1.0.6",
"qwik-content-loader": "^0.0.2",
"qwik-scroll-to-top": "^0.0.7",
"qwik-select-fixed": "^0.0.4",
"valibot": "^0.19.0",
"zod": "^3.22.4"
} |
We're having this issue as well (even with the workarounds I've seen listed) which is very frustrating. Will this be addressed soon? Here is our vite.config.js; I welcome any suggestions for additional things to try:
|
facing the issue with the react component that is not chaging at all, but hash is new all the time |
I have a pretty detailed example in #15994. It seems that the suggestions in this thread helped. I'm guessing that it was the CommonJS |
Solutions mentioned here didn’t work for me. Each consecutive build without changes to source code produces new hashes for the same chunks and in some cases can lead to cascading cache invalidation issues which is really bad for performance. |
We're seeing the exact same thing. Why wouldn't the hashes just be based solely on the content of the file being hashed? Or is the issue that there is non-determinism in the bundling process which makes for different content every time? |
I think this is the main reason for this, and it seems like it should be fixed with |
I have tried adding both workarounds to my code ( But here is a fun fact that may help someone isolate the cause further: |
For us the issue turned out to be the Sentry Vite plugin's default behavior, which injects a helper method that makes the build result non-deterministic. |
Analyzing the code a bit, I understood that this happens because the name of the index file changes, and it is imported in almost all other .js files. So, for the hash to work correctly, I imagine that this needs to be ignored in some way. |
@devsuperfrete yes also mentioned that, if something is change at any place all hashes are affected, the reason is that everything included into index |
Could you share some more info on this? Looks like my code base uses that plugin. How/where did you find info about that injected helper method? |
Hi @msorens this was painful for us, but we found this option and set it to |
Thanks, @geoffharcourt , I will give that a try. Not terribly familiar with Sentry: what is the impact of setting that option to false? Seems like it might not be able to manage builds as effectively...? |
It helps Sentry link exceptions to source. We found in our app that Sentry was still able to do it well without the helper injected. |
We had the same issue with SvelteKit. They generate a version that is based on the current timestamp (which is something they discourage in their docs). |
Hi, I also met this where the generated polyfill bundle is not stable. I've opened the #16505, hopefully solving your problem. |
Worked. Thank you! |
Thanks, @yoyo837 and @shankerwangmiao . Looking in the release notes I am not finding that issue listed. Is it safe to say it is in 5.3.0 or later...? |
No, it is in @vitejs/plugin-legacy 5.4.1 |
Ah, ok. I am not using that, so would not help my situation. Thanks, though. |
I have the same problem with {
plugins: [
react(),
tsconfigPaths({root: './'}),
viteCommonjs(),
sentryVitePlugin({
authToken: process.env.SENTRY_AUTH_TOKEN,
org: 'getport',
project: 'frontend',
sourcemaps: {
filesToDeleteAfterUpload: ['./dist/**/*.js.map'],
},
release: {
name: process.env.VERSION,
create: true,
inject: false,
},
}),
svgr({
svgrOptions: {
icon: true,
},
}),
],
define: {
'process.env': {},
},
build: {
// Workaround to ensure content hash is the same between deployments
// https://github.com/vitejs/vite/issues/13672
rollupOptions: {
...build?.rollupOptions,
output: {
...build?.rollupOptions?.output,
chunkFileNames: `assets/[name]-chunk-[hash].js`,
manualChunks: {
monaco: ['monaco-editor', 'protobufjs', 'monaco-yaml'],
}
},
maxParallelFileOps: 1,
},
sourcemap: true,
commonjsOptions: {
// Workaround to ensure content hash is the same between deployments
// https://github.com/vitejs/vite/issues/13672
strictRequires: true,
include: [/common-consts/, /node_modules/],
},
},
optimizeDeps: {
...optimizeDeps,
include: [...(optimizeDeps?.include ?? []), 'tailwind.config.js', '@port-labs/common-consts', '**/**.cy.ts'],
esbuildOptions: {
plugins: [reactVirtualizedResolver],
},
}
} |
@geoffharcourt I set it to false, but that didn't solve the problem of creating different hashes in each new version. |
build: { |
The Vite v6 beta bumps |
Has this question been updated? I am currently encountering the same problem, but there is no problem when I create a new project. I don’t know what triggers this hash and why it changes every time I build it ,even if i do not change anything. |
Any of the solutions provided don't work for me, so I found another solution and it was to provide my own hash. But first is important to say that my solution may be dangerous in case that for some reason some different code is injected in the different builds (somebody commented that some Sentry tool was injecting different parameters into the code). In order to verify that builds are equal across different builds and environments I recommend to force Rollup to build the code without hashes using the following configuration:
and the verify that CRC sums of files doesn't change across builds and environments (You can use If the CRC matches then It's safe to use my workaround. Workaround: import { defineConfig } from 'vite';
import fs from 'fs';
let dynamicHash = null;
const generateConsistentHash = (chunk, ext = '[ext]') => {
if (dynamicHash === null) {
if (fs.existsSync('REVISION')) {
dynamicHash = fs.readFileSync('REVISION').toString();
}
// Keep 'base64url' because it will remove '+', '/' and '='
dynamicHash = dynamicHash ? Buffer.from(dynamicHash, 'hex').toString('base64url') : false;
}
return dynamicHash ? `assets/[name].${dynamicHash}.${ext}` : `assets/[name].[hash].${ext}`
}
export default defineConfig({
build: {
rollupOptions: {
output: {
entryFileNames: (chunk) => generateConsistentHash(chunk, 'js'),
chunkFileNames: (chunk) => generateConsistentHash(chunk, 'js'),
assetFileNames: (chunk) => generateConsistentHash(chunk, '[ext]'),
}
},
}
}); My workaround will read the last the last revision deployed as a hex value from the 'REVISION' file and it will converted into a hash string. if the 'REVISION' file is missing it will use the standard Rollup hash. Advantages
Disadvantages
|
Vite 6 now uses Closing as the OP case has been fixed. |
Describe the bug
Executing builds multiple times with the same code generates different hashes.
Reproduction
https://github.com/ttionya/vite-non-deterministic-build-repro
Steps to reproduce
Clone the aforementioned repro, install dependencies, and execute
npm run build
multiple times. Verify the hash of the vendor file.System Info
Used Package Manager
npm
Logs
No response
Validations
The text was updated successfully, but these errors were encountered: