replace Start prerender with Vite SPA
All checks were successful
CI / Typecheck, test & build (push) Successful in 3m54s
CI / Deploy to Cloudflare Workers (push) Successful in 1m51s

This commit is contained in:
2026-08-31 01:28:48 +08:00
parent 848de4e309
commit 6932906327
10 changed files with 58 additions and 513 deletions

View File

@ -41,10 +41,9 @@ progress, so upload UIs stay indeterminate.
## Deploy
The app is a client-rendered SPA served as static assets by a Cloudflare Worker
(`wrangler.jsonc`, `not_found_handling: single-page-application`). The build
emits `dist/client/_shell.html`, which is copied to `index.html` so Cloudflare's SPA
fallback returns it for every client route.
The app is a client-rendered Vite SPA served as static assets by a Cloudflare
Worker (`wrangler.jsonc`, `not_found_handling: single-page-application`).
Cloudflare returns `dist/index.html` for every client route.
**Manual deploy** (needs `wrangler login` or `CLOUDFLARE_API_TOKEN` /
`CLOUDFLARE_ACCOUNT_ID` in your env):

21
index.html Normal file
View File

@ -0,0 +1,21 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Gig 管理后台</title>
<script>
try {
const stored = localStorage.getItem('theme')
const prefersDark = matchMedia('(prefers-color-scheme: dark)').matches
const dark = stored === 'dark' || (stored !== 'light' && prefersDark)
document.documentElement.classList.toggle('dark', dark)
document.documentElement.style.colorScheme = dark ? 'dark' : 'light'
} catch {}
</script>
</head>
<body class="font-sans antialiased">
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

View File

@ -13,7 +13,7 @@
"test": "vitest run",
"gen:api": "node scripts/gen-api.mjs",
"typecheck": "tsc --noEmit",
"cf:build": "vite build && node -e \"require('fs').copyFileSync('dist/client/_shell.html','dist/client/index.html')\"",
"cf:build": "vite build",
"cf:deploy": "pnpm cf:build && wrangler deploy"
},
"dependencies": {
@ -23,8 +23,6 @@
"@tanstack/react-query": "^5.102.8",
"@tanstack/react-router": "latest",
"@tanstack/react-router-devtools": "latest",
"@tanstack/react-router-ssr-query": "latest",
"@tanstack/react-start": "latest",
"@tanstack/react-table": "^8.21.3",
"@tanstack/router-plugin": "^1.132.0",
"class-variance-authority": "^0.7.1",

450
pnpm-lock.yaml generated
View File

@ -26,12 +26,6 @@ importers:
'@tanstack/react-router-devtools':
specifier: latest
version: 1.167.1(@tanstack/react-router@1.170.32(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@tanstack/router-core@1.171.27)(csstype@3.2.3)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
'@tanstack/react-router-ssr-query':
specifier: latest
version: 1.167.2(@tanstack/query-core@5.102.8)(@tanstack/react-query@5.102.8(react@19.2.7))(@tanstack/react-router@1.170.32(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@tanstack/router-core@1.171.27)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
'@tanstack/react-start':
specifier: latest
version: 1.168.49(crossws@0.4.9(srvx@0.11.21))(esbuild@0.28.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.4)(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0))
'@tanstack/react-table':
specifier: ^8.21.3
version: 8.21.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
@ -155,10 +149,6 @@ packages:
'@asamuzakjp/nwsapi@2.3.9':
resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==}
'@babel/code-frame@7.27.1':
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
engines: {node: '>=6.9.0'}
'@babel/code-frame@7.29.7':
resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==}
engines: {node: '>=6.9.0'}
@ -698,22 +688,6 @@ packages:
'@neodrag/core': 3.0.0-next.11
solid-js: ^1.0.0
'@oozcitak/dom@2.0.2':
resolution: {integrity: sha512-GjpKhkSYC3Mj4+lfwEyI1dqnsKTgwGy48ytZEhm4A/xnH/8z9M3ZVXKr/YGQi3uCLs1AEBS+x5T2JPiueEDW8w==}
engines: {node: '>=20.0'}
'@oozcitak/infra@2.0.2':
resolution: {integrity: sha512-2g+E7hoE2dgCz/APPOEK5s3rMhJvNxSMBrP+U+j1OWsIbtSpWxxlUjq1lU8RIsFJNYv7NMlnVsCuHcUzJW+8vA==}
engines: {node: '>=20.0'}
'@oozcitak/url@3.0.0':
resolution: {integrity: sha512-ZKfET8Ak1wsLAiLWNfFkZc/BraDccuTJKR6svTYc7sVjbR+Iu0vtXdiDMY4o6jaFl5TW2TlS7jbLl4VovtAJWQ==}
engines: {node: '>=20.0'}
'@oozcitak/util@10.0.0':
resolution: {integrity: sha512-hAX0pT/73190NLqBPPWSdBVGtbY6VOhWYK3qqHqtXQ1gK7kS2yz4+ivsN07hpJ6I3aeMtKP6J6npsEKOAzuTLA==}
engines: {node: '>=20.0'}
'@oxc-parser/binding-android-arm-eabi@0.120.0':
resolution: {integrity: sha512-WU3qtINx802wOl8RxAF1v0VvmC2O4D9M8Sv486nLeQ7iPHVmncYZrtBhB4SYyX+XZxj2PNnCcN+PW21jHgiOxg==}
engines: {node: ^20.19.0 || >=22.12.0}
@ -1870,16 +1844,6 @@ packages:
'@tanstack/router-core':
optional: true
'@tanstack/react-router-ssr-query@1.167.2':
resolution: {integrity: sha512-yRvy0VJ00R8huPuquk+qyYQGMpYRc/G33mc6/yZ4f7LaBZz9h/VbACjmLzhm/+6u5WSmUt6ouJJZnI1/5Npfag==}
engines: {node: '>=20.19'}
peerDependencies:
'@tanstack/query-core': '>=5.102.0'
'@tanstack/react-query': '>=5.102.0'
'@tanstack/react-router': '>=1.127.0'
react: '>=18.0.0 || >=19.0.0'
react-dom: '>=18.0.0 || >=19.0.0'
'@tanstack/react-router@1.170.32':
resolution: {integrity: sha512-SIpxvaTKco100a5ZR3ePmArbhtm3XOx+w1dpGYY9gxHDta4iXSKDdQuhLonwJbIMkVJsU1rwXf0UDHMrF/1snw==}
engines: {node: '>=20.19'}
@ -1887,54 +1851,6 @@ packages:
react: '>=18.0.0 || >=19.0.0'
react-dom: '>=18.0.0 || >=19.0.0'
'@tanstack/react-start-client@1.168.30':
resolution: {integrity: sha512-qsZuykUl1EF0/rc1bin1RtjFzz07YMOTBzhOstSDzbOVm/WKf1QKFTN+qAZi74xlbXSWNuT2MiFRyg4RKwj8iw==}
engines: {node: '>=22.12.0'}
peerDependencies:
react: '>=18.0.0 || >=19.0.0'
react-dom: '>=18.0.0 || >=19.0.0'
'@tanstack/react-start-rsc@0.1.48':
resolution: {integrity: sha512-UglRdTMuF3c4dvzL/gh4dMVbMWHsPy8ZgTQdT2qpTlyt1b/3m+R40tBFdsfTgw76VTXivW+qV/ih0PN9000XTw==}
engines: {node: '>=22.12.0'}
peerDependencies:
'@rspack/core': '>=2.0.0-0'
'@vitejs/plugin-rsc': '>=0.5.30'
react: '>=18.0.0 || >=19.0.0'
react-dom: '>=18.0.0 || >=19.0.0'
react-server-dom-rspack: '>=0.0.2'
peerDependenciesMeta:
'@rspack/core':
optional: true
'@vitejs/plugin-rsc':
optional: true
react-server-dom-rspack:
optional: true
'@tanstack/react-start-server@1.167.37':
resolution: {integrity: sha512-cODHpFU8vIm7AdHii9W3NEuwyruNmT5wLDZjRsJLT9Jp+7FACnfJrRbvxnp1ldSv/9mxcHKi/OgwbdHQeMZcAQ==}
engines: {node: '>=22.12.0'}
peerDependencies:
react: '>=18.0.0 || >=19.0.0'
react-dom: '>=18.0.0 || >=19.0.0'
'@tanstack/react-start@1.168.49':
resolution: {integrity: sha512-iQb1ZoEHqvZMGLR4G7v3tTtgL06yv/bwxvGP3waVHxVn7bRpyopM44YbOluaGkcJzc13ZTvdLKWYNAN3bxMX/Q==}
engines: {node: '>=22.12.0'}
peerDependencies:
'@rsbuild/core': ^2.0.0
'@vitejs/plugin-rsc': '*'
react: '>=18.0.0 || >=19.0.0'
react-dom: '>=18.0.0 || >=19.0.0'
vite: '>=7.0.0'
peerDependenciesMeta:
'@rsbuild/core':
optional: true
'@vitejs/plugin-rsc':
optional: true
vite:
optional: true
'@tanstack/react-store@0.9.3':
resolution: {integrity: sha512-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg==}
peerDependencies:
@ -1975,10 +1891,6 @@ packages:
resolution: {integrity: sha512-kFvM4caRds9Q3EXg64bZubJ6rbDxyV0YDSBSGvOGzmKspQPdz5Xrh0uj5T1Ov8avUUg+c761u04VQAaEzSBXRw==}
engines: {node: '>=20.19'}
'@tanstack/router-generator@1.167.33':
resolution: {integrity: sha512-Z3lCWIPuRUMPmuI8Mm48x/s49TxmHOaFVZ52j1W1QKYrsFHyT6U/h9bqfHJDxfQ8kz7y9q+W1YPKZ15Ee7yuCA==}
engines: {node: '>=20.19'}
'@tanstack/router-plugin@1.168.19':
resolution: {integrity: sha512-aFglwLc+bbPTgZlkXn3PvOwpjJAfgUyPGSuql4MP3XrqTTh6WkBiy2RYb6oaG5h0s7EKwivEuq85K3Y4V0Mt1g==}
engines: {node: '>=20.19'}
@ -2000,66 +1912,10 @@ packages:
webpack:
optional: true
'@tanstack/router-plugin@1.168.35':
resolution: {integrity: sha512-foDAZKFqHXae+oFbIgcsSvy2QCVRn7XdS3nhwcRvD+ed6JrKPUP/1lQMsZLJqWycgR1vkZF7gs955KGa0NZQ0w==}
engines: {node: '>=20.19'}
peerDependencies:
'@rsbuild/core': '>=1.0.2 || ^2.0.0'
'@tanstack/react-router': ^1.170.32
vite: '>=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0'
vite-plugin-solid: ^2.11.10 || ^3.0.0-0
webpack: '>=5.92.0'
peerDependenciesMeta:
'@rsbuild/core':
optional: true
'@tanstack/react-router':
optional: true
vite:
optional: true
vite-plugin-solid:
optional: true
webpack:
optional: true
'@tanstack/router-ssr-query-core@1.169.2':
resolution: {integrity: sha512-7pO65Aiq/1+aS3Mb6vSGtIjzQ/YGv9JTfBbn2EYlHcZnJ4s4ZGCeTPI847geB1RfJqVhfwxM8bZgGM51mYkolg==}
engines: {node: '>=20.19'}
peerDependencies:
'@tanstack/query-core': '>=5.102.0'
'@tanstack/router-core': '>=1.127.0'
'@tanstack/router-utils@1.162.2':
resolution: {integrity: sha512-hTWqJtqIFFdvuCl8WXNyrodp2L9zo2G37xKRrcVmVRWpAB2h+U1LuRAfS4tsFTiWOIoE/B+WDVFB8JpoEdw6jQ==}
engines: {node: '>=20.19'}
'@tanstack/start-client-core@1.170.27':
resolution: {integrity: sha512-Ro6ZSM0NgYKDMxM0e8qyU4mBfnld2Zb74BA/9f4i35C0Y3IAA8Zxs/DIPfOo9VRYWp5c5n5Q8dRBn2qn0vtPhQ==}
engines: {node: '>=22.12.0'}
'@tanstack/start-fn-stubs@1.162.0':
resolution: {integrity: sha512-QWfUZ3Yo923tdQn38LyKMU8rcTw69zc+T4dAvgTWV4O56SqFRsGfS0lSWIMhJRwXIx/bvdi7nTUBDdZtTHtpTQ==}
engines: {node: '>=22.12.0'}
'@tanstack/start-plugin-core@1.171.39':
resolution: {integrity: sha512-Zyj6G4MDFLXcHYhPavhewCBo8dsxi3qvPk31zl/QtTzYzOY9rJHDDBGarKsJq20ziChmkGn/sttYqb4vGCxJDA==}
engines: {node: '>=22.12.0'}
peerDependencies:
'@rsbuild/core': ^2.0.0
vite: '>=7.0.0'
peerDependenciesMeta:
'@rsbuild/core':
optional: true
vite:
optional: true
'@tanstack/start-server-core@1.169.31':
resolution: {integrity: sha512-56w8l+Fao01YCrmv0hzNxL3b3FRmqLRGdE11izZNQsW+1CcSYuehAM5khWKABuI1DI/UIBLGV7BwL4Dlg0eHCw==}
engines: {node: '>=22.12.0'}
'@tanstack/start-storage-context@1.167.29':
resolution: {integrity: sha512-8qfprC5774XMRDQlMogkfiGpFLiBf0xDG4bMFUbfkSzpCAQwpLbgGY4Zwft22O9rKYq2vUXusKAdVjvJTUEquQ==}
engines: {node: '>=22.12.0'}
'@tanstack/store@0.9.3':
resolution: {integrity: sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw==}
@ -2276,14 +2132,6 @@ packages:
resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
engines: {node: '>=18'}
crossws@0.4.9:
resolution: {integrity: sha512-iWx+1OMSG2aOHpjyf9AESOzkwsVdS49cXM9dVrI2PDhxU5l2RIWE/KG56gk4BbAnsMoycvniJ9OnOxO9LRzHVA==}
peerDependencies:
srvx: '>=0.11.5'
peerDependenciesMeta:
srvx:
optional: true
css-tree@3.2.1:
resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==}
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
@ -2373,9 +2221,6 @@ packages:
resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==}
engines: {node: '>=12.0.0'}
exsolve@1.1.0:
resolution: {integrity: sha512-D+42+T12DdIlJM3uepa55qGiL3sYdLBOxIl2ifQCzCHz4c7eiolaHsi3BIqEr7JxBzxv2pYZQX9kw16ziMcEmw==}
fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
@ -2388,9 +2233,6 @@ packages:
picomatch:
optional: true
fetchdts@0.1.7:
resolution: {integrity: sha512-YoZjBdafyLIop9lSxXVI33oLD5kN31q4Td+CasofLLYeLXRFeOsuOw0Uo+XNRi9PZlbfdlN2GmRtm4tCEQ9/KA==}
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@ -2416,16 +2258,6 @@ packages:
graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
h3@2.0.1-rc.20:
resolution: {integrity: sha512-28ljodXuUp0fZovdiSRq4G9OgrxCztrJe5VdYzXAB7ueRvI7pIUqLU14Xi3XqdYJ/khXjfpUOOD2EQa6CmBgsg==}
engines: {node: '>=20.11.1'}
hasBin: true
peerDependencies:
crossws: ^0.4.1
peerDependenciesMeta:
crossws:
optional: true
html-encoding-sniffer@6.0.0:
resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
@ -2479,10 +2311,6 @@ packages:
resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==}
hasBin: true
js-yaml@4.3.0:
resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==}
hasBin: true
jsdom@28.1.0:
resolution: {integrity: sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
@ -2788,9 +2616,6 @@ packages:
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
rou3@0.8.1:
resolution: {integrity: sha512-ePa+XGk00/3HuCqrEnK3LxJW7I0SdNg6EFzKUJG73hMAdDcOUC/i/aSz7LSDwLrGr33kal/rqOGydzwl6U7zBA==}
saxes@6.0.0:
resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
engines: {node: '>=v12.22.7'}
@ -2851,15 +2676,6 @@ packages:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
source-map@0.7.6:
resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==}
engines: {node: '>= 12'}
srvx@0.11.21:
resolution: {integrity: sha512-GWTHjKMeekX8CwJf4VU9Oo6mJpSGaflGMddbCvR+Cmmh9sslRMiGbAoqqZacE0r1ncARh6buCEETr2W52F8b1w==}
engines: {node: '>=20.16.0'}
hasBin: true
stackback@0.0.2:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
@ -2936,9 +2752,6 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
ufo@1.6.4:
resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==}
undici-types@6.21.0:
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
@ -3062,14 +2875,6 @@ packages:
yaml:
optional: true
vitefu@1.1.3:
resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==}
peerDependencies:
vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
peerDependenciesMeta:
vite:
optional: true
vitest@4.1.10:
resolution: {integrity: sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==}
engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
@ -3174,10 +2979,6 @@ packages:
resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
engines: {node: '>=18'}
xmlbuilder2@4.0.3:
resolution: {integrity: sha512-bx8Q1STctnNaaDymWnkfQLKofs0mGNN7rLLapJlGuV3VlvegD7Ls4ggMjE3aUSWItCCzU0PEv45lI87iSigiCA==}
engines: {node: '>=20.0'}
xmlchars@2.2.0:
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
@ -3250,12 +3051,6 @@ snapshots:
'@asamuzakjp/nwsapi@2.3.9': {}
'@babel/code-frame@7.27.1':
dependencies:
'@babel/helper-validator-identifier': 7.29.7
js-tokens: 4.0.0
picocolors: 1.1.1
'@babel/code-frame@7.29.7':
dependencies:
'@babel/helper-validator-identifier': 7.29.7
@ -3665,23 +3460,6 @@ snapshots:
'@neodrag/core': 3.0.0-next.11
solid-js: 1.9.14
'@oozcitak/dom@2.0.2':
dependencies:
'@oozcitak/infra': 2.0.2
'@oozcitak/url': 3.0.0
'@oozcitak/util': 10.0.0
'@oozcitak/infra@2.0.2':
dependencies:
'@oozcitak/util': 10.0.0
'@oozcitak/url@3.0.0':
dependencies:
'@oozcitak/infra': 2.0.2
'@oozcitak/util': 10.0.0
'@oozcitak/util@10.0.0': {}
'@oxc-parser/binding-android-arm-eabi@0.120.0':
optional: true
@ -4801,17 +4579,6 @@ snapshots:
transitivePeerDependencies:
- csstype
'@tanstack/react-router-ssr-query@1.167.2(@tanstack/query-core@5.102.8)(@tanstack/react-query@5.102.8(react@19.2.7))(@tanstack/react-router@1.170.32(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@tanstack/router-core@1.171.27)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)':
dependencies:
'@tanstack/query-core': 5.102.8
'@tanstack/react-query': 5.102.8(react@19.2.7)
'@tanstack/react-router': 1.170.32(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
'@tanstack/router-ssr-query-core': 1.169.2(@tanstack/query-core@5.102.8)(@tanstack/router-core@1.171.27)
react: 19.2.7
react-dom: 19.2.7(react@19.2.7)
transitivePeerDependencies:
- '@tanstack/router-core'
'@tanstack/react-router@1.170.32(react-dom@19.2.7(react@19.2.7))(react@19.2.7)':
dependencies:
'@tanstack/history': 1.162.1
@ -4821,79 +4588,6 @@ snapshots:
react: 19.2.7
react-dom: 19.2.7(react@19.2.7)
'@tanstack/react-start-client@1.168.30(react-dom@19.2.7(react@19.2.7))(react@19.2.7)':
dependencies:
'@tanstack/react-router': 1.170.32(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
'@tanstack/router-core': 1.171.27
'@tanstack/start-client-core': 1.170.27
react: 19.2.7
react-dom: 19.2.7(react@19.2.7)
'@tanstack/react-start-rsc@0.1.48(crossws@0.4.9(srvx@0.11.21))(esbuild@0.28.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.4)(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0))':
dependencies:
'@tanstack/react-router': 1.170.32(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
'@tanstack/router-core': 1.171.27
'@tanstack/router-utils': 1.162.2
'@tanstack/start-client-core': 1.170.27
'@tanstack/start-fn-stubs': 1.162.0
'@tanstack/start-plugin-core': 1.171.39(@tanstack/react-router@1.170.32(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(crossws@0.4.9(srvx@0.11.21))(esbuild@0.28.1)(rolldown@1.1.4)(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0))
'@tanstack/start-storage-context': 1.167.29
pathe: 2.0.3
react: 19.2.7
react-dom: 19.2.7(react@19.2.7)
transitivePeerDependencies:
- '@farmfe/core'
- '@rsbuild/core'
- bun-types-no-globals
- crossws
- esbuild
- rolldown
- rollup
- supports-color
- unloader
- vite
- vite-plugin-solid
- webpack
'@tanstack/react-start-server@1.167.37(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)':
dependencies:
'@tanstack/react-router': 1.170.32(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
'@tanstack/router-core': 1.171.27
'@tanstack/start-server-core': 1.169.31(crossws@0.4.9(srvx@0.11.21))
react: 19.2.7
react-dom: 19.2.7(react@19.2.7)
transitivePeerDependencies:
- crossws
'@tanstack/react-start@1.168.49(crossws@0.4.9(srvx@0.11.21))(esbuild@0.28.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.4)(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0))':
dependencies:
'@tanstack/react-router': 1.170.32(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
'@tanstack/react-start-client': 1.168.30(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
'@tanstack/react-start-rsc': 0.1.48(crossws@0.4.9(srvx@0.11.21))(esbuild@0.28.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.4)(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0))
'@tanstack/react-start-server': 1.167.37(crossws@0.4.9(srvx@0.11.21))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
'@tanstack/router-utils': 1.162.2
'@tanstack/start-client-core': 1.170.27
'@tanstack/start-plugin-core': 1.171.39(@tanstack/react-router@1.170.32(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(crossws@0.4.9(srvx@0.11.21))(esbuild@0.28.1)(rolldown@1.1.4)(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0))
'@tanstack/start-server-core': 1.169.31(crossws@0.4.9(srvx@0.11.21))
pathe: 2.0.3
react: 19.2.7
react-dom: 19.2.7(react@19.2.7)
optionalDependencies:
vite: 8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0)
transitivePeerDependencies:
- '@farmfe/core'
- '@rspack/core'
- bun-types-no-globals
- crossws
- esbuild
- react-server-dom-rspack
- rolldown
- rollup
- supports-color
- unloader
- vite-plugin-solid
- webpack
'@tanstack/react-store@0.9.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7)':
dependencies:
'@tanstack/store': 0.9.3
@ -4950,19 +4644,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@tanstack/router-generator@1.167.33':
dependencies:
'@babel/types': 7.29.7
'@tanstack/router-core': 1.171.27
'@tanstack/router-utils': 1.162.2
'@tanstack/virtual-file-routes': 1.162.0
jiti: 2.7.0
magic-string: 0.30.21
prettier: 3.9.4
zod: 4.4.3
transitivePeerDependencies:
- supports-color
'@tanstack/router-plugin@1.168.19(@tanstack/react-router@1.170.32(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(esbuild@0.28.1)(rolldown@1.1.4)(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0))':
dependencies:
'@babel/core': 7.29.7
@ -4987,35 +4668,6 @@ snapshots:
- supports-color
- unloader
'@tanstack/router-plugin@1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(esbuild@0.28.1)(rolldown@1.1.4)(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0))':
dependencies:
'@babel/core': 7.29.7
'@babel/template': 7.29.7
'@babel/types': 7.29.7
'@tanstack/router-core': 1.171.27
'@tanstack/router-generator': 1.167.33
'@tanstack/router-utils': 1.162.2
chokidar: 5.0.0
unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.1.4)(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0))
zod: 4.4.3
optionalDependencies:
'@tanstack/react-router': 1.170.32(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
vite: 8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0)
transitivePeerDependencies:
- '@farmfe/core'
- '@rspack/core'
- bun-types-no-globals
- esbuild
- rolldown
- rollup
- supports-color
- unloader
'@tanstack/router-ssr-query-core@1.169.2(@tanstack/query-core@5.102.8)(@tanstack/router-core@1.171.27)':
dependencies:
'@tanstack/query-core': 5.102.8
'@tanstack/router-core': 1.171.27
'@tanstack/router-utils@1.162.2':
dependencies:
'@babel/generator': 7.29.7
@ -5029,69 +4681,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@tanstack/start-client-core@1.170.27':
dependencies:
'@tanstack/router-core': 1.171.27
'@tanstack/start-fn-stubs': 1.162.0
'@tanstack/start-storage-context': 1.167.29
seroval: 1.6.4
'@tanstack/start-fn-stubs@1.162.0': {}
'@tanstack/start-plugin-core@1.171.39(@tanstack/react-router@1.170.32(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(crossws@0.4.9(srvx@0.11.21))(esbuild@0.28.1)(rolldown@1.1.4)(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0))':
dependencies:
'@babel/code-frame': 7.27.1
'@babel/core': 7.29.7
'@babel/types': 7.29.7
'@tanstack/router-core': 1.171.27
'@tanstack/router-generator': 1.167.33
'@tanstack/router-plugin': 1.168.35(@tanstack/react-router@1.170.32(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(esbuild@0.28.1)(rolldown@1.1.4)(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0))
'@tanstack/router-utils': 1.162.2
'@tanstack/start-server-core': 1.169.31(crossws@0.4.9(srvx@0.11.21))
exsolve: 1.1.0
lightningcss: 1.32.0
pathe: 2.0.3
picomatch: 4.0.5
seroval: 1.6.4
source-map: 0.7.6
srvx: 0.11.21
tinyglobby: 0.2.17
ufo: 1.6.4
vitefu: 1.1.3(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0))
xmlbuilder2: 4.0.3
zod: 4.4.3
optionalDependencies:
vite: 8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0)
transitivePeerDependencies:
- '@farmfe/core'
- '@rspack/core'
- '@tanstack/react-router'
- bun-types-no-globals
- crossws
- esbuild
- rolldown
- rollup
- supports-color
- unloader
- vite-plugin-solid
- webpack
'@tanstack/start-server-core@1.169.31(crossws@0.4.9(srvx@0.11.21))':
dependencies:
'@tanstack/history': 1.162.1
'@tanstack/router-core': 1.171.27
'@tanstack/start-client-core': 1.170.27
'@tanstack/start-storage-context': 1.167.29
fetchdts: 0.1.7
h3-v2: h3@2.0.1-rc.20(crossws@0.4.9(srvx@0.11.21))
seroval: 1.6.4
transitivePeerDependencies:
- crossws
'@tanstack/start-storage-context@1.167.29':
dependencies:
'@tanstack/router-core': 1.171.27
'@tanstack/store@0.9.3': {}
'@tanstack/table-core@8.21.3': {}
@ -5300,11 +4889,6 @@ snapshots:
cookie@1.1.1: {}
crossws@0.4.9(srvx@0.11.21):
optionalDependencies:
srvx: 0.11.21
optional: true
css-tree@3.2.1:
dependencies:
mdn-data: 2.27.1
@ -5400,16 +4984,12 @@ snapshots:
expect-type@1.4.0: {}
exsolve@1.1.0: {}
fast-deep-equal@3.1.3: {}
fdir@6.5.0(picomatch@4.0.5):
optionalDependencies:
picomatch: 4.0.5
fetchdts@0.1.7: {}
fsevents@2.3.3:
optional: true
@ -5425,13 +5005,6 @@ snapshots:
graceful-fs@4.2.11: {}
h3@2.0.1-rc.20(crossws@0.4.9(srvx@0.11.21)):
dependencies:
rou3: 0.8.1
srvx: 0.11.21
optionalDependencies:
crossws: 0.4.9(srvx@0.11.21)
html-encoding-sniffer@6.0.0:
dependencies:
'@exodus/bytes': 1.15.1
@ -5478,10 +5051,6 @@ snapshots:
dependencies:
argparse: 2.0.1
js-yaml@4.3.0:
dependencies:
argparse: 2.0.1
jsdom@28.1.0:
dependencies:
'@acemir/cssom': 0.9.31
@ -5838,8 +5407,6 @@ snapshots:
'@rolldown/binding-win32-arm64-msvc': 1.1.4
'@rolldown/binding-win32-x64-msvc': 1.1.4
rou3@0.8.1: {}
saxes@6.0.0:
dependencies:
xmlchars: 2.2.0
@ -5910,10 +5477,6 @@ snapshots:
source-map-js@1.2.1: {}
source-map@0.7.6: {}
srvx@0.11.21: {}
stackback@0.0.2: {}
std-env@4.1.0: {}
@ -5971,8 +5534,6 @@ snapshots:
typescript@6.0.3: {}
ufo@1.6.4: {}
undici-types@6.21.0: {}
undici@7.28.0: {}
@ -6033,10 +5594,6 @@ snapshots:
fsevents: 2.3.3
jiti: 2.7.0
vitefu@1.1.3(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0)):
optionalDependencies:
vite: 8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0)
vitest@4.1.10(@types/node@22.20.0)(jsdom@28.1.0)(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0)):
dependencies:
'@vitest/expect': 4.1.10
@ -6124,13 +5681,6 @@ snapshots:
xml-name-validator@5.0.0: {}
xmlbuilder2@4.0.3:
dependencies:
'@oozcitak/dom': 2.0.2
'@oozcitak/infra': 2.0.2
'@oozcitak/util': 10.0.0
js-yaml: 4.3.0
xmlchars@2.2.0: {}
y18n@5.0.8: {}

17
src/main.tsx Normal file
View File

@ -0,0 +1,17 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { RouterProvider } from '@tanstack/react-router'
import { getRouter } from './router'
import './styles.css'
const rootElement = document.getElementById('root')
if (!rootElement) {
throw new Error('Root element not found')
}
createRoot(rootElement).render(
<StrictMode>
<RouterProvider router={getRouter()} />
</StrictMode>,
)

View File

@ -701,12 +701,3 @@ const rootRouteChildren: RootRouteChildren = {
export const routeTree = rootRouteImport
._addFileChildren(rootRouteChildren)
._addFileTypes<FileRouteTypes>()
import type { getRouter } from './router.tsx'
import type { createStart } from '@tanstack/react-start'
declare module '@tanstack/react-start' {
interface Register {
ssr: true
router: Awaited<ReturnType<typeof getRouter>>
}
}

View File

@ -1,6 +1,5 @@
import { createRouter as createTanStackRouter } from '@tanstack/react-router'
import { QueryClient } from '@tanstack/react-query'
import { setupRouterSsrQueryIntegration } from '@tanstack/react-router-ssr-query'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { routeTree } from './routeTree.gen'
export function getRouter() {
@ -24,10 +23,11 @@ export function getRouter() {
scrollRestoration: true,
defaultPreload: 'intent',
defaultPreloadStaleTime: 0,
Wrap: ({ children }) => (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
),
})
setupRouterSsrQueryIntegration({ router, queryClient })
return router
}

View File

@ -1,45 +1,20 @@
import {
HeadContent,
Outlet,
Scripts,
createRootRouteWithContext,
} from '@tanstack/react-router'
import { Outlet, createRootRouteWithContext } from '@tanstack/react-router'
import type { QueryClient } from '@tanstack/react-query'
import { Toaster } from '@/components/ui/sonner'
import appCss from '../styles.css?url'
const THEME_INIT_SCRIPT = `(function(){try{var stored=window.localStorage.getItem('theme');var prefersDark=window.matchMedia('(prefers-color-scheme: dark)').matches;var resolved=stored==='dark'||(stored!=='light'&&prefersDark)?'dark':'light';document.documentElement.classList.toggle('dark',resolved==='dark');document.documentElement.style.colorScheme=resolved;}catch(e){}})();`
interface RouterContext {
queryClient: QueryClient
}
export const Route = createRootRouteWithContext<RouterContext>()({
head: () => ({
meta: [
{ charSet: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ title: 'Gig 管理后台' },
],
links: [{ rel: 'stylesheet', href: appCss }],
}),
shellComponent: RootDocument,
component: () => <Outlet />,
component: RootComponent,
})
function RootDocument({ children }: { children: React.ReactNode }) {
function RootComponent() {
return (
<html lang="zh-CN" suppressHydrationWarning>
<head>
<script dangerouslySetInnerHTML={{ __html: THEME_INIT_SCRIPT }} />
<HeadContent />
</head>
<body className="font-sans antialiased">
{children}
<Toaster position="top-center" richColors />
<Scripts />
</body>
</html>
<>
<Outlet />
<Toaster position="top-center" richColors />
</>
)
}

View File

@ -1,18 +1,15 @@
import { defineConfig } from 'vite'
import { devtools } from '@tanstack/devtools-vite'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import { tanstackRouter } from '@tanstack/router-plugin/vite'
import viteReact from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
// SPA mode: auth is Bearer-token client-side (localStorage), so route guards
// and data fetching must not run during SSR.
const config = defineConfig({
resolve: { tsconfigPaths: true },
plugins: [
devtools(),
tanstackStart({ spa: { enabled: true } }),
tanstackRouter({ target: 'react', autoCodeSplitting: true }),
tailwindcss(),
viteReact(),
],

View File

@ -2,13 +2,10 @@
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "gig-admin",
"compatibility_date": "2026-07-15",
// Assets-only Worker: gig-admin is a client-rendered SPA (see vite.config.ts
// `spa: { enabled: true }`), so there is no server to run — Cloudflare just
// serves the static build and falls back to the SPA shell for client routes.
// `pnpm cf:build` copies the TanStack Start shell to index.html, which
// `single-page-application` handling serves for any non-asset request.
// Assets-only Worker: gig-admin is a client-rendered SPA, so Cloudflare
// serves the Vite build and falls back to index.html for client routes.
"assets": {
"directory": "dist/client",
"directory": "dist",
"not_found_handling": "single-page-application"
},
"observability": {