From fd9bd1e421fb26aa83e230833c6a961f91e00ece Mon Sep 17 00:00:00 2001 From: Julian Kiedaisch Date: Sat, 24 Oct 2026 15:49:02 +0000 Subject: [PATCH] chore(node): build for the runtime the image carries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `engines`, `@types/node` and the three esbuild targets said node20 while both stages of the image have been node:24-alpine for a while — and since 24.10.2026 the development machines run 24 too. So the bundles are built for exactly the runtime that carries them instead of for a version nobody runs any more. `npm run check`: 110 files, 1825 tests, green on node 24.22.1. Co-Authored-By: Claude Opus 5 --- deploy/Dockerfile | 10 +++++----- package-lock.json | 18 +++++++++--------- package.json | 4 ++-- packages/editor/browser/serverF.ts | 2 +- packages/server/package.json | 2 +- packages/server/test/harness.ts | 2 +- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/deploy/Dockerfile b/deploy/Dockerfile index abe4580..2b457d5 100644 --- a/deploy/Dockerfile +++ b/deploy/Dockerfile @@ -11,11 +11,11 @@ # and a .gz beside its files. The second stage takes only these files, so # the image holds no node_modules, no sources and no compiler. # -# Node 24 (active LTS), not the 20 of the development machines: 20 has had -# no security fixes since April 2026, and a service facing the browsers of a -# whole school should not run on it. The bundles are built for node20 and -# run unchanged on 24; the image's run is checked before each release (see -# the README). +# Node 24 (active LTS) — and since 24.10.2026 the same major as the +# development machines, so the bundles are built for exactly the runtime that +# carries them. 20 has had no security fixes since April 2026, and a service +# facing the browsers of a whole school should not run on it. The image's run +# is checked before each release (see the README). FROM node:24-alpine AS build WORKDIR /src diff --git a/package-lock.json b/package-lock.json index 44840a3..9ec2f44 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,13 +11,13 @@ ], "devDependencies": { "@playwright/test": "1.62.1", - "@types/node": "^20.19.0", + "@types/node": "^24.19.2", "esbuild": "^0.28.2", "typescript": "^5.9.0", "vitest": "^3.2.0" }, "engines": { - "node": ">=20" + "node": ">=24" } }, "node_modules/@babel/code-frame": { @@ -1369,13 +1369,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.19.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.43.tgz", - "integrity": "sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==", + "version": "24.19.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.19.2.tgz", + "integrity": "sha512-93d49wCWJkCyN87MxLpNN6KXPCwFw7bVUg79mGUV1OS40JGWwVCr8n61DXCSqz7CV6/VfPkb7xec7uP2M+QHWQ==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.21.0" + "undici-types": ">=7.24.0 <7.24.7" } }, "node_modules/@types/pg": { @@ -2537,9 +2537,9 @@ } }, "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", + "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", "dev": true, "license": "MIT" }, diff --git a/package.json b/package.json index e659c29..d3089e2 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "packages/*" ], "engines": { - "node": ">=20" + "node": ">=24" }, "scripts": { "test": "vitest run", @@ -20,7 +20,7 @@ }, "devDependencies": { "@playwright/test": "1.62.1", - "@types/node": "^20.19.0", + "@types/node": "^24.19.2", "esbuild": "^0.28.2", "typescript": "^5.9.0", "vitest": "^3.2.0" diff --git a/packages/editor/browser/serverF.ts b/packages/editor/browser/serverF.ts index 9c130b6..47a0e32 100644 --- a/packages/editor/browser/serverF.ts +++ b/packages/editor/browser/serverF.ts @@ -49,7 +49,7 @@ export async function startServerF(editorBase: string, editorFolder?: string): P bundle: true, platform: 'node', format: 'esm', - target: 'node20', + target: 'node24', outdir: out, outExtension: { '.js': '.mjs' }, external: ['pg-native'], diff --git a/packages/server/package.json b/packages/server/package.json index 53c21b2..edfea5d 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -8,7 +8,7 @@ ".": "./src/index.ts" }, "scripts": { - "build": "esbuild src/main.ts src/simWorker.ts src/precompressMain.ts --bundle --platform=node --format=esm --target=node20 --outdir=dist --out-extension:.js=.mjs --external:pg-native --banner:js=\"import { createRequire as createBundleRequire } from 'node:module'; const require = createBundleRequire(import.meta.url);\"", + "build": "esbuild src/main.ts src/simWorker.ts src/precompressMain.ts --bundle --platform=node --format=esm --target=node24 --outdir=dist --out-extension:.js=.mjs --external:pg-native --banner:js=\"import { createRequire as createBundleRequire } from 'node:module'; const require = createBundleRequire(import.meta.url);\"", "start": "node dist/main.mjs" }, "dependencies": { diff --git a/packages/server/test/harness.ts b/packages/server/test/harness.ts index 82aabd2..b9a88c0 100644 --- a/packages/server/test/harness.ts +++ b/packages/server/test/harness.ts @@ -51,7 +51,7 @@ let roomThread: Promise | undefined; export function bundledRoomThread(): Promise { roomThread ??= (async () => { const outfile = joinPath(mkdtempSync(joinPath(tmpdir(), 'filius-room-thread-')), 'simWorker.mjs'); - await build({ entryPoints: [new URL('../src/simWorker.ts', import.meta.url).pathname], bundle: true, platform: 'node', format: 'esm', target: 'node20', outfile, logLevel: 'error' }); + await build({ entryPoints: [new URL('../src/simWorker.ts', import.meta.url).pathname], bundle: true, platform: 'node', format: 'esm', target: 'node24', outfile, logLevel: 'error' }); return pathToFileURL(outfile); })(); return roomThread;