repair the lock file the leaflet install broke

The deploy died on `npm ci` with "Missing: @emnapi/core@1.11.3 from lock
file". Nothing was wrong with the code — the lock really was incomplete,
and the Dockerfile was right to refuse it.

I broke it. Adding leaflet ran `npm install` under npm 11.6.2; the builder
is node:22-alpine, which ships npm 10.9.8. npm 11 prunes optional platform
packages that npm 10 still validates, and it dropped `@emnapi/core` and
`@emnapi/runtime` — transitive optional deps of
`@tailwindcss/oxide-wasm32-wasi`. Both were present in the lock at b760c1a
and absent from 34bf798 onward.

Regenerated with `npx npm@10.9.8 install --package-lock-only`, which
restores both entries and keeps leaflet 1.9.4 / @types/leaflet 1.9.22.
Verified by running the builder's exact command in a scratch directory:
the old lock reproduces the failure, the new one gives "added 212 packages"
under npm 10.9.8 AND under npm 11.6.2 — so it holds whichever npm the image
ships. No Dockerfile change was needed for that.

The Dockerfile comment did need one. It said the fix was "`npm install`
locally and COMMIT the updated package-lock.json", which is exactly the
step that caused this. It now says to prove the lock against npm 10.9.8 in
a scratch directory before pushing, and how to regenerate it if it fails.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JYEsb8PNZ19G9R8gUjTU7n
This commit is contained in:
2026-09-09 18:09:11 +05:30
parent 35250717fc
commit e069068ce7
2 changed files with 46 additions and 27 deletions

View File

@@ -13,9 +13,30 @@ COPY package*.json ./
# never pinned, so the deployed bundle is built from dependencies nobody chose
# and nobody can reproduce.
#
# When this line fails, the fix is `npm install` locally and COMMIT the updated
# package-lock.json. The build should not paper over a lock file that is out of
# date; it should say so.
# When this line fails, the fix is to update package-lock.json locally and
# COMMIT it. The build should not paper over a lock file that is out of date;
# it should say so.
#
# ── But `npm install` alone is how the lock got broken once ─────────────────
#
# This image is node:22-alpine, which ships npm 10.9.8. A developer on npm 11
# running `npm install` rewrites the lock in a shape npm 10 rejects: npm 11
# prunes optional platform packages that npm 10 still validates. Adding leaflet
# on npm 11.6.2 dropped `@emnapi/core` and `@emnapi/runtime` — transitive
# optional deps of `@tailwindcss/oxide-wasm32-wasi` — and the next deploy died
# here with "Missing: @emnapi/core@1.11.3 from lock file". Nothing was wrong
# with the code; the lock was genuinely incomplete and this line was right to
# refuse it.
#
# So after changing dependencies, prove the lock against THIS npm before
# pushing, in a scratch directory so node_modules is not disturbed:
#
# mkdir /tmp/lockcheck && cp package.json package-lock.json /tmp/lockcheck/
# cd /tmp/lockcheck && npx npm@10.9.8 ci
#
# and if it fails, regenerate with the same version:
#
# npx npm@10.9.8 install --package-lock-only
RUN npm ci --no-audit --no-fund
COPY . .