Wdrożenie
Dwie konfiguracje Vite, względne base, brak SPA fallback, CSP z hashem, cache immutable i gotowe konfiguracje hostingu.
Dwie konfiguracje#
| Plik | Komenda | Przeznaczenie |
|---|---|---|
vite.config.ts | npm run dev | Serwer deweloperski, HMR, /docs |
vite.prod.config.ts | npm run build | Produkcja, base z B2D_BASE, jeden chunk, release.json |
config/build-meta.ts | oba | Meta b2d-build, b2d-built-at, b2d-base, b2d-mode |
B2D_BASE steruje ścieżką bazową:
npm run build
B2D_BASE=/ npm run build
B2D_BASE=/game/ npm run build
Domyślnie ./ — gra działa w dowolnym podkatalogu bez przebudowy.
Czego pilnujemy#
- Względne ścieżki — build nie zawiera absolutnych
/assets/…. - Brak SPA fallback — nieznane ścieżki zwracają
404.html; gra nie ma routingu po ścieżkach, a przepisanie naindex.htmlpsuje względneassets/. - Stan w query stringu —
?example=<id>&lang=<pl|en>przeżywa odświeżenie. - Cache —
index.htmlzawszeno-cache, plikiassets/*z hashemimmutable. - HTTPS — wymagane przez audio i część API.
- CSP —
script-src 'self' 'sha256-…'bez'unsafe-inline'; hash liczony z faktycznej treści inline skryptu startowego. - MIME —
.wasmjakoapplication/wasm,.jsjakotext/javascript. - Widoczny błąd — brak modułu kończy się ekranem startowym z diagnostyką, nigdy czarną planszą.
Komendy#
npm run build
npm run build:site
npm run build:single
npm run bundle:report
npm run bundle:check
npm run export:game
npm run test:hosting
Eksport z konfiguracjami hostingu#
npm run export:game tworzy release/game (katalog do wgrania w całości) oraz release/game/hosting:
| Plik | Hosting |
|---|---|
nginx.conf | nginx (TLS, CSP, cache, error_page 404) |
htaccess | Apache 2.4 → zmień nazwę na .htaccess |
netlify.toml | Netlify |
_headers | Cloudflare Pages i Netlify |
vercel.json | Vercel (bez rewrites) |
firebase.json | Firebase Hosting |
CHECKSUMS.txt zawiera SHA-256 każdego pliku — po wgraniu porównaj kilka pozycji, żeby wykluczyć niekompletny upload.
Przykład: nginx#
server {
listen 443 ssl http2;
server_name game.example.com;
root /var/www/game;
location = /index.html {
add_header Cache-Control "no-cache";
}
location /assets/ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
location ~ \.wasm$ {
types { application/wasm wasm; }
add_header Cache-Control "public, max-age=31536000, immutable";
}
error_page 404 /404.html;
}
Przykład: Vercel#
{
"headers": [
{
"source": "/assets/(.*)",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
]
},
{
"source": "/(.*).wasm",
"headers": [
{ "key": "Content-Type", "value": "application/wasm" }
]
}
]
}
Bez rewrites
Nie dodawaj SPA rewrite (/(.*) → /index.html). Gra żyje pod jednym adresem katalogu i trzyma stan w query stringu — rewrite psuje względne ścieżki assetów.
Testy hostingu#
npm run test:hosting
Osiem scenariuszy w Chromium: HTTP w korzeniu, podkatalog, ścisły CSP, HTTPS z self-signed, cache immutable, odświeżenie stanu, zablokowany bundle i nieznana ścieżka.
Ograniczenia#
- Eksport desktopowy (Electron/Tauri) odłożony do stabilizacji wersji webowej.
- Brak routingu po ścieżkach — aplikacja żyje pod jednym adresem katalogu.
- Testy hostingu wymagają Chromium (Playwright) w CI.