Following on: once you know it is the inner bundler, you do not have to choose between the old build tool and a broken dev server. You can hold the build tool where it is and pin the transitive dependency back.
Every package manager has a mechanism for this, they just disagree on the name and on how far it reaches:
- npm and pnpm read an
overridesblock - Yarn calls the same idea
resolutions - pnpm additionally has a resolutions field under its own key, which behaves slightly differently for nested ranges
All of them do the same job: force every copy of a package to a version you name, regardless of what asked for it. Add it, delete the lockfile entry or reinstall so it takes effect, and confirm with whatever why/list command your manager offers that only one version is present. That last check matters — the most common failure here is that the override applied to some of the tree and something else pulled a second copy in.
Two rules for using this, learned the hard way:
Write the reason next to it. An override with no comment is indistinguishable from a mistake six months later, and the person who finds it will either be too scared to remove it or will remove it on the wrong day.
Make it expire. A pin is a bet that upstream will fix this, and they usually do — this exact class of bug tends to be resolved in the bundler and then picked up by the next minor of the build tool. Put a reminder against it, because the failure mode of pinning is not breakage, it is that you are still on a year-old bundler and nobody remembers why.