diff --git a/.env.build.example b/.env.build.example new file mode 100644 index 0000000..e95183a --- /dev/null +++ b/.env.build.example @@ -0,0 +1,37 @@ +# ============================================================================= +# 음악퀴즈 통합 패키지 — 빌드용 환경변수 템플릿 +# +# 이 파일은 `npm run dist:win` / `npm run dist:win:rp` 로 exe 를 패키징할 때 +# 설치기(installer / installer-rp) 안에 함께 묶이는 값들입니다. +# 개발 실행에서 쓰는 `.env` 와는 분리되어 있어, 운영 도메인 같은 값을 빌드용 +# 으로만 관리할 수 있습니다. +# +# 사용법: +# 1) 이 파일을 복사해 `.env.build` 로 만든다. +# 2) 운영 도메인 등 배포에 들어갈 값으로 채운다. +# 3) `npm run dist:win` 또는 `npm run dist:win:rp` 로 빌드한다. +# → electron-builder 가 `.env.build` 를 패키지된 exe 의 +# `resources/.env.build` 로 함께 배포. +# → 런타임에서 `env.ts` 가 우선 로드. +# +# `.env.build` 는 .gitignore 로 제외되어 있습니다. +# 서버(express) 운영용 PORT / HOST / SESSION_SECRET 같은 변수는 여기 두지 말고 +# 서버 측 `.env` 에 두세요. 이 파일은 설치기 exe 에 묶이는 값 전용입니다. +# ============================================================================= + +# ----- 사이트 도메인(설치기가 manifest 를 받아갈 주소) ----- + +# 설치기 두 종(installer / installer-rp) 이 첫 화면에서 자동으로 채워 넣는 +# manifest 의 호스트. 프로토콜 + 호스트(+포트) 까지만 적고 슬래시는 끝에 붙이지 않음. +# 예) 운영 도메인 : https://mq.example.com +# 로컬 개발 : http://127.0.0.1:3000 +SITE_BASE_URL=https://mq.example.com + +# 위 SITE_BASE_URL 로부터 자동으로 `${SITE_BASE_URL}/manifest.json` 이 생성됩니다. +# 특별히 다른 경로를 쓰고 싶을 때만 아래를 풀어서 우선 적용시키세요. +# MANIFEST_URL=https://mq.example.com/manifest.json + +# ----- 리소스팩 설치기 ----- + +# yt-dlp 동시 다운로드 수(1~8). 비워두면 CPU 코어 수로 자동 결정. +# MUSIC_CONCURRENCY= diff --git a/.gitignore b/.gitignore index c5cb917..d3aa97b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ conversations/ .env .env.local .env.*.local +.env.build diff --git a/electron-builder-rp.yml b/electron-builder-rp.yml index 6b49a4b..b5b6c51 100644 --- a/electron-builder-rp.yml +++ b/electron-builder-rp.yml @@ -13,12 +13,12 @@ files: - installer-rp/** - build/icon.* - package.json -# 메인 설치기와 동일하게 .env, locales 를 함께 배포. +# 메인 설치기와 동일하게 빌드 전용 `.env.build` 와 locales 를 함께 배포. extraResources: - from: . to: . filter: - - .env + - .env.build - from: locales to: locales filter: diff --git a/electron-builder.yml b/electron-builder.yml index 87a2bba..4cd0657 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -9,15 +9,17 @@ files: - installer/** - build/icon.* - package.json -# 빌드 시점의 .env 를 설치기 옆에 함께 배포(없으면 조용히 패스). -# 패키징 후 운영자가 resources/.env 만 교체해서 도메인을 바꿀 수도 있음. +# 빌드 전용 `.env.build` 를 설치기 옆에 함께 배포(없으면 조용히 패스). +# `.env` 는 서버/개발 실행용이라 빌드 산출물에는 포함되지 않으며, 패키지된 exe +# 는 `resources/.env.build` 를 우선 로드함(없으면 `resources/.env` 로 폴백). +# 패키징 후 운영자가 `resources/.env.build` 만 교체해서 도메인을 바꿀 수 있음. # locales/ 폴더는 i18n.ts 가 process.resourcesPath/locales//ko-kr.json # 을 찾아 로드하므로, 빌드된 .exe 에서도 한국어 사전이 적용되도록 함께 배포. extraResources: - from: . to: . filter: - - .env + - .env.build - from: locales to: locales filter: diff --git a/src/shared/env.ts b/src/shared/env.ts index 3bc5485..97c7c52 100644 --- a/src/shared/env.ts +++ b/src/shared/env.ts @@ -7,9 +7,14 @@ import { projectRoot } from './paths.js' * `.env` 를 읽어 `process.env` 에 주입. * * 탐색 순서(처음 발견된 것만 사용): - * 1. 패키징된 Electron 앱이면 `process.resourcesPath/.env` - * — electron-builder 의 extraResources 로 빌드 시점 `.env` 가 함께 배포됨. - * 2. `<프로젝트 루트>/.env` + * 1. 패키징된 Electron 앱이면 `process.resourcesPath/.env.build` + * — electron-builder 의 extraResources 로 빌드 시점 `.env.build` 가 함께 + * 배포됨. 빌드용 도메인/설정을 dev `.env` 와 분리해 관리하기 위함. + * 2. 패키징된 Electron 앱이면 `process.resourcesPath/.env` + * — 운영자가 패키징 후 직접 `.env` 를 옆에 두고 덮어쓰는 경우를 대비한 폴백. + * 3. `<프로젝트 루트>/.env.build` + * — 개발 환경에서도 빌드용 값을 그대로 테스트하고 싶을 때. + * 4. `<프로젝트 루트>/.env` * — 개발 실행(npm start / npm run installer*) 및 서버 운영용. * * - 이미 설정된 환경변수는 덮어쓰지 않음(쉘/systemd 에서 넘긴 값이 우선). @@ -20,8 +25,10 @@ export function loadEnv(): void { const candidates: string[] = [] const resourcesPath = (process as NodeJS.Process & { resourcesPath?: string }).resourcesPath if (typeof resourcesPath === 'string' && resourcesPath.length > 0) { + candidates.push(path.join(resourcesPath, '.env.build')) candidates.push(path.join(resourcesPath, '.env')) } + candidates.push(path.join(projectRoot, '.env.build')) candidates.push(path.join(projectRoot, '.env')) for (const envPath of candidates) {