feat(deps): adopt better-sqlite3 13, drop install scripts in deps stage - #1934
Merged
Conversation
Corrects the analysis in #1927, which held better-sqlite3 at 12.x on the incorrect premise that v13 "always compiles from source". It does not. v13 moved to N-API and now ships prebuilt binaries INSIDE the npm tarball (prebuilds/{darwin,linux,linuxmusl,win32}-{x64,arm64}.node) rather than downloading them via the removed prebuild-install dependency. Both Docker target architectures are covered by linuxmusl-x64 and linuxmusl-arm64. The Docker failure in #1889 was narrower than diagnosed: better-sqlite3's package.json declares no install script at all — npm *synthesizes* `node-gyp rebuild` because a binding.gyp is present. That build is a no-op when a prebuild exists (binding.gyp resolves `prebuild_exists` by running `node lib/binding.js` and sets target type 'none'), but node-gyp still needs python3 merely to evaluate gyp. So the image needed python3 for a build that compiles nothing — it was never going to compile SQLite, under emulation or otherwise. Release images are also built on native per-platform runners (release.yml), not QEMU. Fix: `npm ci --omit=dev --ignore-scripts` in the deps stage. better-sqlite3 is the only production dependency with an install script — every other `hasInstallScript` package in the lockfile is dev-only and excluded by --omit=dev — and it needs no install-time step, since lib/binding.js resolves prebuilds/<platform>-<arch>.node at require() time. This keeps the image toolchain-free rather than adding python3 for a no-op. Adds a build-time guard asserting a prebuild exists for the target, so a future missing prebuild fails the Docker build instead of crashing the production image at runtime. Verified locally: `docker build --target deps` resolves prebuilds/linuxmusl-arm64.node, and the binary loads and executes queries inside the Alpine image (musl confirmed via glibcVersionRuntime = none). Also removes the now-unnecessary better-sqlite3 semver-major ignore rule. The typescript hold stays — that one is real (ts-jest peer is ">=4.3 <7").
Contributor
|
🎉 This PR is included in version 2.13.0-beta.41 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Corrects the analysis in #1927, which held better-sqlite3 at 12.x on the incorrect premise that v13 "always compiles from source". It does not — thanks to @steilerDev for pushing back on this.
What v13 actually changed
v13 moved to N-API and now ships prebuilt binaries inside the npm tarball, rather than downloading them via the (removed)
prebuild-install:Both Docker target architectures are covered —
linuxmusl-x64andlinuxmusl-arm64are exactly Alpine on amd64/arm64.The real cause of #1889's Docker failure
Narrower than I diagnosed. better-sqlite3's
package.jsondeclares no install script at all — npm synthesizesnode-gyp rebuildbecause abinding.gypis present. That build is a no-op when a prebuild exists; binding.gyp says so itself:…and sets
type: 'none'when a prebuild is found. But node-gyp still needs python3 just to evaluate gyp. So the image needed python3 for a build that compiles nothing. It was never going to compile SQLite — under emulation or otherwise. (Release images are also built on native per-platform runners, not QEMU —release.yml:120.)Locally, installing v13 with python3 present takes 0.62s and emits only
TOUCH Release/obj.target/better_sqlite3.stamp— no compilation, no.nodeinbuild/.The fix
npm ci --omit=dev --ignore-scriptsin thedepsstage, rather than adding python3 for a no-op build.This is safe because better-sqlite3 is the only production dependency with an install script — every other
hasInstallScriptentry in the lockfile (core-js,cpu-features,fsevents,protobufjs,ssh2,unrs-resolver) isdev: trueand excluded by--omit=dev. And it needs no install-time step at all:lib/binding.jsresolvesprebuilds/<platform>-<arch>.nodeatrequire()time.Also adds a build-time guard asserting a prebuild exists for the target, so a future missing prebuild fails the Docker build instead of crashing the production image at runtime.
Verification (local, arm64 — the harder case)
docker build --target deps:Running inside that image:
npm ci --omit=dev --ignore-scriptscompleted in 3.3s.Also
Removes the now-unnecessary
better-sqlite3semver-major ignore rule fromdependabot.yml. Thetypescripthold stays — that one is real (ts-jest@29.4.xpeer is>=4.3 <7).Test plan
linuxmusl-x64prebuild path and the new guard