Hey folks, I’m trying to lock down our frontend bundle because we keep shipping two copies of the same library after a minor dependency bump, and it’s a real risk for subtle state bugs (two singletons) plus a bigger payload.
// Vite/Rollup build snippet
export default {
resolve: {
dedupe: ["react", "zustand"],
alias: {
"zustand": require.resolve("zustand"),
},
},
};
What’s the most reliable way you’ve found to enforce a single instance across transitive deps in real projects without breaking installs or spending all day chasing lockfile edge cases?
1 Like
dedupe/alias is a nice seatbelt, but the thing that actually keeps “two singletons” from showing up after a random bump is making the package manager pick one version on purpose.
In practice I’ve had the least drama with (1) an override/resolution in the package manager, and (2) a CI check that fails the build when duplicates appear. pnpm overrides / Yarn resolutions / npm overrides, then a dumb little script that greps pnpm list (or yarn why) output for multiple versions of the same package and errors out. I’m not 100% sure how clean this stays with workspaces + linked local packages, but it’s been way less whack-a-mole than trying to solve it purely in Vite config.
Your Vite config is still worth keeping though — it’s like taping down the rug so nobody trips, but the override is the part that stops someone from bringing a second rug into the house in the first place.
1 Like
Your Vite dedupe/alias helps, but the more reliable way to stop this happening is preventing the second copy from ever landing in node_modules in the first place. That means using your package manager’s override/resolution mechanism so transitive deps can’t quietly pull a second semver line, then making CI fail the moment the lockfile drifts. In practice, I’ve had the least drama with overrides (npm/pnpm) or resolutions (Yarn) for the handful of packages that are “singleton-y” (React, state libs, anything with global registries), plus a CI check that asserts there’s only one version installed. Otherwise, you only notice after the bundle ships and you get the “why are there two stores? ” bug report. Example snippets:
// package.json (npm >= 8.3)
{ "overrides": { "zustand": "4.5.2", "react": "18.3.1" } }
// package.json (pnpm)
{ "pnpm": { "overrides": { "zustand": "4.5.2", "react": "18.3.1" } } }
// package.json (Yarn classic/berry)
{ "resolutions": { "zustand": "4.5.2", "react": "18.3.1" } }
And then in CI, something blunt like:
pnpm why zustand
pnpm why react
Or:
npm ls zustand
npm ls react
…and treat “multiple versions present” as a hard failure. That’s the bit that actually enforces it over time; dedupe/alias is more like a seatbelt after the crash has already started.
1 Like