feat(setup)!: require Node 22.12+ and drop Node 20 (#152)

better-sqlite3 stopped publishing prebuilt binaries for Node 20's ABI
(115) in 12.10.0 - upstream, not a mirror gap:

    12.8.0 / 12.9.0   115 127 131 137 141
    12.10.0+              127 137 141 147

`better-sqlite3: ^12.8.0` resolves well past that, so every Node 20
install 404'd on the CDN, fell through to the source build, and demanded
Python plus a C++ toolchain before the bot could start at all. package.json
went on claiming `^20.19.0` worked, and the README went on recommending
Node 20 as one of two blessed versions. It was not a supported
configuration in any meaningful sense - it was a trap.

So say so up front: engines, both setup scripts, and the Docker images now
require Node 22.12+ (or 24+, which still needs a source build for opus).
The version gate in setup.bat / setup.sh is kept byte-identical to the
engines range, as before.

Also copy scripts/lib/console-log.mjs into the production image. The
previous commit had check-native.mjs import it, and the Dockerfile copies
check-native.mjs in on its own for `docker exec ... npm start` - without
its dependency that preflight now dies with ERR_MODULE_NOT_FOUND.

BREAKING CHANGE: Node 20 is no longer supported. Node 22.12 LTS or newer
is required; setup refuses to run on anything older.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
saopig1andClaude Opus 5 committed 2026-08-25 18:27:22 +08:00
1 parent 5e9ae49f52
commit a804b2edc1
6 files changed
+35 -29

No files matched your search

+11 -9
View File
@@ -11,7 +11,7 @@ title TSMusicBot Setup
:: ============================================================
set "SCRIPT_VERSION=2.2"
set "MIN_NODE_MAJOR=20"
set "MIN_NODE_MAJOR=22"
:: Newest Node major this project is regularly tested against. Anything above
:: still works, it just may have no prebuilt addons and fall back to a source build.
set "TESTED_NODE_MAJOR=22"
@@ -67,13 +67,15 @@ for /f "tokens=1 delims=v." %%a in ("%NODE_VER%") do set "NODE_MAJOR=%%a"
call :log "Node.js version: %NODE_VER%"
echo [OK] Node.js found: %NODE_VER%
:: The supported floor is not just a major version, so let node decide:
:: @honeybbq/teamspeak-client needs >=20.19, @sansenjian/qq-music-api needs
:: >=20.17 / >=22.9, and the odd majors (21 / 23) are excluded by
:: better-sqlite3 and vitest. Keep this in sync with "engines" in package.json.
node -e "const v=process.versions.node.split('.').map(Number); process.exit((v[0]===20&&v[1]>=19)||(v[0]===22&&v[1]>=12)||v[0]>=24?0:1)"
:: The supported floor is not just a major version, so let node decide.
:: Node 20 was dropped: better-sqlite3 ships no prebuilt binary for its ABI
:: (115) since 12.10.0, so every Node 20 install needed Python and a C++
:: toolchain just to get off the ground (issue #152). The odd majors (21 /
:: 23) are excluded by better-sqlite3 and vitest.
:: Keep this in sync with "engines" in package.json.
node -e "const v=process.versions.node.split('.').map(Number); process.exit((v[0]===22&&v[1]>=12)||v[0]>=24?0:1)"
if errorlevel 1 (
call :error "Node.js %NODE_VER% is not supported. Use Node 20.19+ LTS or Node 22.12+ LTS."
call :error "Node.js %NODE_VER% is not supported. Use Node 22.12+ LTS or newer."
echo Download: https://nodejs.org/ or https://nodejs.cn/
pause
exit /b 1
@@ -86,10 +88,10 @@ if errorlevel 1 (
:: characters and starts eating the "echo " prefix of following lines.
:: Bilingual guidance lives in the Node scripts, which print UTF-8 reliably.
if %NODE_MAJOR% GTR %TESTED_NODE_MAJOR% (
echo [WARN] Node %NODE_VER% is newer than the tested LTS line, Node 20 / Node 22.
echo [WARN] Node %NODE_VER% is newer than the tested LTS line, Node 22.
echo Newer Node majors may have no prebuilt opus / better-sqlite3,
echo so setup falls back to a source build - slower, needs C++ build tools.
echo Recommended: Node 20 LTS or Node 22 LTS - https://nodejs.org/ or https://nodejs.cn/
echo Recommended: Node 22 LTS - https://nodejs.org/ or https://nodejs.cn/
echo This is only a warning; setup still builds the binaries for %NODE_VER%.
call :log "[WARN] Node major %NODE_MAJOR% is newer than tested LTS %TESTED_NODE_MAJOR%"
)