업로드 형식을 MIDI와 MusicXML과 MXL 및 PDF로 확장하고 파일별 검증을 추가했다. AlphaTab 악보 자산과 Nginx MIME 설정을 보완해 운영에서 오선과 음표가 표시되도록 수정했다. 공개 도메인 클래식과 난이도별 연습 편곡 7개를 같은 제목별로 묶고 출처와 운영 검증 결과를 문서화했다. 검사: TypeScript 검사와 Vitest 67개 및 Vite 운영 빌드 통과. 운영 브라우저 악보 표시와 네 가지 업로드 검증 형식 확인. 백업: /home/syskiller/piano/backups/bach-to-basics/20261003-1545-sheet-upload 운영 반영: 완료
120 lines
4.1 KiB
TypeScript
120 lines
4.1 KiB
TypeScript
import { defineConfig } from "vite";
|
|
import react from "@vitejs/plugin-react";
|
|
import tailwindcss from "@tailwindcss/vite";
|
|
import { VitePWA } from "vite-plugin-pwa";
|
|
import { resolve } from "path";
|
|
|
|
export default defineConfig({
|
|
plugins: [
|
|
react(),
|
|
tailwindcss(),
|
|
VitePWA({
|
|
// 이전 서비스 워커가 시작 문서를 우선 제공하면 서버를 갱신한 뒤에도
|
|
// 로그인과 관리자 메뉴가 예전 화면으로 남는다. 이 서비스는 온라인
|
|
// 학습과 회원 API가 중심이므로 서비스 워커를 스스로 해제해 항상 최신
|
|
// HTML과 해시 자산을 서버에서 받게 한다. 설치형 바로가기는 manifest로
|
|
// 계속 제공되며 오프라인 캐시만 사용하지 않는다.
|
|
selfDestroying: true,
|
|
|
|
// Off in dev so HMR isn't interfered with by cached responses.
|
|
devOptions: { enabled: false },
|
|
|
|
// App icons + display name shown on install / home-screen / dock.
|
|
manifest: {
|
|
name: "Bach to Basics 피아노 학습",
|
|
short_name: "Bach 피아노",
|
|
description:
|
|
"악보와 내려오는 음표를 보며 MIDI 피아노를 연습하는 한국어 학습 도구",
|
|
theme_color: "#9333ea", // matches the purple accent
|
|
background_color: "#0a0a0a",
|
|
display: "standalone",
|
|
orientation: "landscape-primary",
|
|
start_url: "/",
|
|
scope: "/",
|
|
icons: [
|
|
// Reuses existing public/ assets - logo.png is the high-res one,
|
|
// apple-touch-icon and favicon are smaller fallbacks.
|
|
{
|
|
src: "/logo.png",
|
|
sizes: "512x512",
|
|
type: "image/png",
|
|
purpose: "any",
|
|
},
|
|
{
|
|
src: "/logo.png",
|
|
sizes: "512x512",
|
|
type: "image/png",
|
|
purpose: "maskable",
|
|
},
|
|
{
|
|
src: "/apple-touch-icon.png",
|
|
sizes: "180x180",
|
|
type: "image/png",
|
|
},
|
|
{
|
|
src: "/favicon.png",
|
|
sizes: "32x32",
|
|
type: "image/png",
|
|
},
|
|
],
|
|
},
|
|
|
|
workbox: {
|
|
// 새 배포를 발견하면 대기 단계 없이 바로 활성화하고 열린 화면을
|
|
// 즉시 관리한다. 사용자가 오래된 회원 메뉴를 계속 보지 않게 한다.
|
|
skipWaiting: true,
|
|
clientsClaim: true,
|
|
cleanupOutdatedCaches: true,
|
|
// Precache built static assets so the shell loads instantly + works offline.
|
|
globPatterns: ["**/*.{js,css,html,ico,png,svg,woff2}"],
|
|
|
|
// Don't try to precache the soundfont folder (large; fetched lazily by AlphaTab).
|
|
globIgnores: ["**/soundfont/**"],
|
|
|
|
// Critical: NEVER cache backend API calls - we want fresh data, not a stale
|
|
// cached response (e.g. old fingerings, old transcription results).
|
|
navigateFallbackDenylist: [/^\/api/],
|
|
|
|
// Runtime caching for cross-origin sample CDNs (smplr): serve fresh when online,
|
|
// fall back to cache when offline so the on-screen piano still works.
|
|
// Hosts: gleitz (Soundfont), smpldsnds (SplendidGrandPiano + ElectricPiano in 0.20+),
|
|
// danigb (legacy, kept for older smplr versions).
|
|
runtimeCaching: [
|
|
{
|
|
urlPattern: /^https:\/\/(smpldsnds|gleitz|danigb)\.github\.io\//,
|
|
handler: "StaleWhileRevalidate",
|
|
options: {
|
|
cacheName: "smplr-samples",
|
|
expiration: { maxEntries: 500, maxAgeSeconds: 60 * 60 * 24 * 30 },
|
|
},
|
|
},
|
|
],
|
|
|
|
// Bigger than the default 2 MiB so AlphaTab's bundle isn't rejected from precache.
|
|
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024,
|
|
},
|
|
}),
|
|
],
|
|
resolve: {
|
|
alias: {
|
|
"@bach-to-basics/shared": resolve(__dirname, "../shared/types/index.ts"),
|
|
},
|
|
},
|
|
server: {
|
|
port: 5173,
|
|
proxy: {
|
|
"/api": {
|
|
target: "http://localhost:8000",
|
|
rewrite: (path) => path.replace(/^\/api/, ""),
|
|
},
|
|
},
|
|
},
|
|
worker: {
|
|
format: "es",
|
|
},
|
|
optimizeDeps: {
|
|
exclude: ["@coderline/alphatab"],
|
|
include: ["pixi.js"],
|
|
},
|
|
});
|