Record three confirmed v1.0.8 failure modes (expo prebuild native regressions, npm 10/11 lockfile divergence, local EAS build preconditions) and promote each into docs/releasing.md, a new docs/development/dependencies.md, and the release-preflight script. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2.8 KiB
Dependency and lockfile discipline
Two npm realities
CI runners and the API Docker image use the node version pinned in
.nvmrc (node 20.19.4 with npm 10.8.2). A developer machine can run a newer
npm (for example npm 11). npm 10 and npm 11 resolve wildcard or range
dependencies differently at the same place in the dependency tree, and each
npm's platform-optional binary selection is not portable to a lockfile
regenerated by the other npm. A lockfile that passes npm ci under one npm
major version can fail it under the other with either an "Invalid: lock
file's ... does not satisfy" error or missing platform-optional binaries
(for example @next/swc-linux-x64-gnu breaking next build,
@rollup/rollup-linux-x64-gnu breaking the API Docker tsup build, or a
missing lightningcss variant breaking local npm ci).
Pin wildcard-range dependencies with root overrides
When a transitive dependency declares a wildcard or wide range (for example
react-native-worklets depending on @react-native/metro-config: "*"), pin
the exact version the app needs in the root package.json overrides block
rather than leaving it to whichever npm resolved the lockfile last:
"overrides": {
"rollup": "4.54.0",
"react-native": "0.85.3",
"expo": "~56.0.0",
"@react-native/metro-config": "0.85.3"
}
Pin platform-optional binaries that must travel with the framework version
apps/web/package.json pins the @next/swc linux and darwin binaries as
direct optionalDependencies so npm does not have to infer them per
platform:
"optionalDependencies": {
"@next/swc-linux-x64-gnu": "15.5.24",
"@next/swc-linux-x64-musl": "15.5.24",
"@next/swc-darwin-arm64": "15.5.24"
}
These versions must be bumped together with any next version bump, or the
pinned binaries will drift from the framework version and npm ci or
next build can fail on the platform that needs the stale binary.
Validate a regenerated lockfile both ways
After changing overrides or any dependency version, regenerate
package-lock.json and validate it under both npm majors before committing:
# Local npm (matches this machine's npm major)
npm ci
npm run verify:fast
# The CI/Docker npm major, emulated on Apple Silicon
docker run --rm --platform linux/amd64 -v "$PWD:/repo" -w /repo node:20.19.4 npm ci
The --platform linux/amd64 flag is mandatory on Apple Silicon: without it,
Docker runs the arm64 image and the platform-binary check proves nothing.
After any bypassed push
Pushes to staging bypass required status checks. After any such push, check
gh run list --branch staging to confirm CI is actually green rather than
assuming it ran and passed.
Do not pipe npm commands through tail when diagnosing a lockfile or build
failure; it can swallow the command's exit code and the detail needed to find
the root cause.