Node 22+ everywhere, LF text on Windows checkouts, CI actions v7
- Node minimum is 22 in package.json engines, the start scripts, the service installer, setup and doctor, matching the README, the release notes and the CI matrix (22 / 24). - .gitattributes: CSS, HTML, JSON, Markdown and YAML check out with LF, so `node --test` on Windows matches the CSS rules the UI tests read; the Windows test step is no longer continue-on-error. - CI: actions/checkout@v7 and actions/setup-node@v7 (Node 24 runtime).
This commit is contained in:
1 parent
b59aa15ee2
commit
bb5c792a4d
12 files changed
+31
-26
No files matched your search
@@ -8,6 +8,13 @@
|
||||
*.mjs text eol=lf
|
||||
*.js text eol=lf
|
||||
*.py text eol=lf
|
||||
# Text the tests read and match line by line (CSS rules, HTML, data, docs): LF everywhere, so a Windows checkout
|
||||
# (core.autocrlf=true) runs `node --test` exactly like Linux and macOS.
|
||||
*.css text eol=lf
|
||||
*.html text eol=lf
|
||||
*.json text eol=lf
|
||||
*.md text eol=lf
|
||||
*.yml text eol=lf
|
||||
# binary assets
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
|
||||
@@ -31,9 +31,9 @@ jobs:
|
||||
RENDER_E2E: '0'
|
||||
NO_COLOR: '1'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
cache: npm
|
||||
@@ -46,8 +46,6 @@ jobs:
|
||||
|
||||
- name: Unit & integration tests
|
||||
run: node --test
|
||||
# Linux is the reference platform; Windows results are informative until the suite is proven there.
|
||||
continue-on-error: ${{ matrix.os == 'windows-latest' }}
|
||||
|
||||
- name: Server smoke test (boot, /healthz, index.html, doctor)
|
||||
shell: bash
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ Out of scope v1: matchmaking queue, training/tutorial, DIY (甄选) slots (the 4
|
||||
|
||||
## 1. Tech stack
|
||||
|
||||
- **Node.js ≥ 18** (tested on 22), ESM (`"type": "module"`), single dependency `ws@8`. No bundler, no TypeScript. JSDoc types where helpful.
|
||||
- **Node.js ≥ 22** (CI: 22 and 24), ESM (`"type": "module"`), single dependency `ws@8`. No bundler, no TypeScript. JSDoc types where helpful.
|
||||
- **Server-authoritative simulation.** Clients send *intents*; the server validates, mutates state and pushes state/snapshots.
|
||||
- **Client:** static files, native ES modules. Vendored libs in `public/vendor/`: `pixi.min.js` (PixiJS **7.4.2** UMD, global `PIXI`), `pixi-spine.js` (**4.0.6** UMD, `PIXI.spine`), `preact.module.js` + `hooks.module.js` + `htm.module.js` (Preact 10 + htm, no build step). No CDN at runtime (LAN play must work offline).
|
||||
- **Shared code** in `shared/` is imported by both server and browser (pure ESM, no Node APIs).
|
||||
|
||||
Generated
+1
-1
@@ -21,7 +21,7 @@
|
||||
"puppeteer-core": "^23.11.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
"node": ">=22"
|
||||
}
|
||||
},
|
||||
"node_modules/@pixi-spine/base": {
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@
|
||||
"launch": "node scripts/launch.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
"node": ">=22"
|
||||
},
|
||||
"dependencies": {
|
||||
"htm": "^3.1.1",
|
||||
|
||||
@@ -118,7 +118,7 @@ try {
|
||||
if (-not $nodeCmd) { throw '未找到 Node.js:请先安装(winget install OpenJS.NodeJS.LTS),然后重新打开 PowerShell。' }
|
||||
$nodeExe = $nodeCmd.Source
|
||||
$major = [int](((& $nodeExe -v) -replace '^v', '').Split('.')[0])
|
||||
if ($major -lt 18) { throw "Node.js 版本太旧(需要 18+):$(& $nodeExe -v)" }
|
||||
if ($major -lt 22) { throw "Node.js 版本太旧(需要 22+):$(& $nodeExe -v)" }
|
||||
if ($nodeExe -like "$env:USERPROFILE*") {
|
||||
Write-Host "注意:node.exe 位于用户目录($nodeExe,nvm/便携版?)。SYSTEM 账户一般也能运行它;若服务起不来,请改用 winget / 官网安装包安装的 Node.js。" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
+2
-2
@@ -20,8 +20,8 @@ import fs from 'node:fs';
|
||||
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const IS_WIN = process.platform === 'win32';
|
||||
|
||||
if (Number(process.versions.node.split('.')[0]) < 18) {
|
||||
console.error(`Node.js ${process.versions.node} 太旧,需要 18 或更高(推荐 22 LTS):https://nodejs.org/zh-cn/download`);
|
||||
if (Number(process.versions.node.split('.')[0]) < 22) {
|
||||
console.error(`Node.js ${process.versions.node} 太旧,需要 22 或更高(22 / 24 LTS):https://nodejs.org/zh-cn/download`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ cd /d "%~dp0.."
|
||||
|
||||
where node >nul 2>nul
|
||||
if errorlevel 1 goto :nonode
|
||||
node -e "process.exit(Number(process.versions.node.split('.')[0])>=18?0:1)"
|
||||
node -e "process.exit(Number(process.versions.node.split('.')[0])>=22?0:1)"
|
||||
if errorlevel 1 goto :oldnode
|
||||
|
||||
if not exist "node_modules\ws\package.json" (
|
||||
@@ -25,7 +25,7 @@ exit /b 0
|
||||
|
||||
:nonode
|
||||
echo.
|
||||
echo 未找到 Node.js(需要 18 或更高,推荐 22 LTS)。Node.js not found.
|
||||
echo 未找到 Node.js(需要 22 或更高,22 / 24 LTS)。Node.js not found.
|
||||
echo.
|
||||
echo 方法一:在 PowerShell 或命令提示符中运行
|
||||
echo winget install OpenJS.NodeJS.LTS
|
||||
@@ -38,7 +38,7 @@ exit /b 1
|
||||
|
||||
:oldnode
|
||||
echo.
|
||||
for /f "delims=" %%v in ('node -v') do echo 当前 Node.js 版本 %%v 太旧,需要 18 或更高(推荐 22 LTS)。
|
||||
for /f "delims=" %%v in ('node -v') do echo 当前 Node.js 版本 %%v 太旧,需要 22 或更高(22 / 24 LTS)。
|
||||
echo 升级:winget upgrade OpenJS.NodeJS.LTS 或 https://nodejs.org/zh-cn/download
|
||||
echo.
|
||||
pause
|
||||
|
||||
@@ -31,7 +31,7 @@ function Test-Node {
|
||||
|
||||
$node = Test-Node
|
||||
if (-not $node) {
|
||||
Write-Host '未找到 Node.js(需要 18 或更高,推荐 22 LTS)。' -ForegroundColor Yellow
|
||||
Write-Host '未找到 Node.js(需要 22 或更高,22 / 24 LTS)。' -ForegroundColor Yellow
|
||||
$winget = Get-Command winget -ErrorAction SilentlyContinue
|
||||
if ($winget) {
|
||||
Write-Host '可以用 Windows 自带的 winget 安装: winget install OpenJS.NodeJS.LTS'
|
||||
@@ -49,8 +49,8 @@ if (-not $node) {
|
||||
Pause-Exit 1
|
||||
}
|
||||
}
|
||||
if ($node.Major -lt 18) {
|
||||
Write-Host "Node.js $($node.Version) 太旧,需要 18 或更高:winget upgrade OpenJS.NodeJS.LTS 或 https://nodejs.org/zh-cn/download" -ForegroundColor Red
|
||||
if ($node.Major -lt 22) {
|
||||
Write-Host "Node.js $($node.Version) 太旧,需要 22 或更高:winget upgrade OpenJS.NodeJS.LTS 或 https://nodejs.org/zh-cn/download" -ForegroundColor Red
|
||||
Pause-Exit 1
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -1,12 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
# 卫戍协议:盟约 · macOS / Linux start script. Docs: docs/DEPLOY.md
|
||||
# scripts/start.sh [--port 3001] [--no-open] [--no-local] [--no-assets] … (arguments go to scripts/launch.mjs)
|
||||
# Checks Node.js ≥ 18, runs `npm ci` on the first run, then scripts/launch.mjs (tools/setup.mjs → server → browser).
|
||||
# Checks Node.js ≥ 22, runs `npm ci` on the first run, then scripts/launch.mjs (tools/setup.mjs → server → browser).
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
if ! command -v node >/dev/null 2>&1; then
|
||||
echo "未找到 Node.js(需要 18 或更高,推荐 22 LTS)。Node.js not found."
|
||||
echo "未找到 Node.js(需要 22 或更高,22 / 24 LTS)。Node.js not found."
|
||||
if [ "$(uname -s)" = "Darwin" ]; then
|
||||
echo " 安装:brew install node@22 或 https://nodejs.org/zh-cn/download"
|
||||
else
|
||||
@@ -14,8 +14,8 @@ if ! command -v node >/dev/null 2>&1; then
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
if ! node -e "process.exit(Number(process.versions.node.split('.')[0])>=18?0:1)"; then
|
||||
echo "Node.js $(node -v) 太旧,需要 18 或更高(推荐 22 LTS):https://nodejs.org/zh-cn/download"
|
||||
if ! node -e "process.exit(Number(process.versions.node.split('.')[0])>=22?0:1)"; then
|
||||
echo "Node.js $(node -v) 太旧,需要 22 或更高(22 / 24 LTS):https://nodejs.org/zh-cn/download"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
+1
-1
@@ -164,7 +164,7 @@ async function main() {
|
||||
|
||||
section('运行环境');
|
||||
const node = checkNode();
|
||||
row(node.ok ? (node.recommended ? 'ok' : 'warn') : 'err', 'Node.js', `v${node.version}` + (node.ok ? (node.recommended ? '' : '(推荐 22 LTS)') : `(需要 ≥ ${MIN_NODE}:https://nodejs.org/zh-cn/download)`));
|
||||
row(node.ok ? (node.recommended ? 'ok' : 'warn') : 'err', 'Node.js', `v${node.version}` + (node.ok ? (node.recommended ? '' : '(推荐 22 / 24 LTS)') : `(需要 ≥ ${MIN_NODE}:https://nodejs.org/zh-cn/download)`));
|
||||
const npmV = tool(IS_WIN ? 'npm.cmd' : 'npm', ['--version']);
|
||||
row(npmV ? 'ok' : 'warn', 'npm', npmV ? `v${npmV}` : '未找到(安装 Node.js 时会自带)');
|
||||
|
||||
|
||||
+5
-5
@@ -4,7 +4,7 @@
|
||||
// node tools/setup.mjs [options]
|
||||
//
|
||||
// Steps (each one is skipped when already done, so re-running is cheap — the start scripts run it on every start):
|
||||
// 1. Node.js ≥ 18 check (clear message + download link otherwise).
|
||||
// 1. Node.js ≥ 22 check (clear message + download link otherwise).
|
||||
// 2. Dependencies: `npm ci` (falls back to `npm install`) when node_modules is missing or incomplete.
|
||||
// 3. Client libraries in public/vendor (tools/vendor.mjs) when any is missing.
|
||||
// 4. Game data (data/*.json, committed) present and parseable.
|
||||
@@ -37,7 +37,7 @@ import { spawnSync } from 'node:child_process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
export const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||||
export const MIN_NODE = 18;
|
||||
export const MIN_NODE = 22;
|
||||
export const IS_WIN = process.platform === 'win32';
|
||||
export const IS_MAC = process.platform === 'darwin';
|
||||
const NODE_URL = 'https://nodejs.org/zh-cn/download';
|
||||
@@ -133,7 +133,7 @@ async function ask(question, def, timeoutMs = 60000) {
|
||||
/** Node.js version check. */
|
||||
export function checkNode() {
|
||||
const major = nodeMajor();
|
||||
return { ok: major >= MIN_NODE, version: process.versions.node, major, recommended: major >= 20 };
|
||||
return { ok: major >= MIN_NODE, version: process.versions.node, major, recommended: major >= MIN_NODE };
|
||||
}
|
||||
|
||||
/** Runtime dependencies installed? */
|
||||
@@ -353,11 +353,11 @@ async function main() {
|
||||
// 1. Node
|
||||
const node = checkNode();
|
||||
if (!node.ok) {
|
||||
log(`${mark.err} Node.js ${node.version} 太旧:需要 ${MIN_NODE} 或更高(推荐 22 LTS)。`);
|
||||
log(`${mark.err} Node.js ${node.version} 太旧:需要 ${MIN_NODE} 或更高(22 / 24 LTS)。`);
|
||||
log(` 下载:${NODE_URL}` + (IS_WIN ? ' 或在终端运行:winget install OpenJS.NodeJS.LTS' : IS_MAC ? ' 或:brew install node@22' : ''));
|
||||
return 1;
|
||||
}
|
||||
add('ok', 'Node.js', `v${node.version}${node.recommended ? '' : '(可用;推荐升级到 22 LTS)'}`);
|
||||
add('ok', 'Node.js', `v${node.version}${node.recommended ? '' : '(可用;推荐 22 / 24 LTS)'}`);
|
||||
|
||||
// 2. npm dependencies
|
||||
let deps = checkDeps();
|
||||
|
||||
Reference in new issue
Block a user