From 401d72622ea7cb3f30804906a63b4a19a88e0a3b Mon Sep 17 00:00:00 2001 From: claude-bot Date: Wed, 13 May 2026 03:29:30 +0900 Subject: [PATCH] =?UTF-8?q?config:=20=EB=B9=8C=EB=93=9C=EB=90=9C=20.exe=20?= =?UTF-8?q?=EC=97=90=EB=8F=84=20.env=20=EA=B0=80=20=EC=A0=81=EC=9A=A9?= =?UTF-8?q?=EB=90=98=EB=8F=84=EB=A1=9D=20=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - electron-builder.yml - dist/shared/** 추가 (env.js 등이 패키지에 들어가도록) - extraResources 로 빌드 시점 .env 를 resources/.env 에 배포 - loadEnv: 패키징된 Electron 앱이면 process.resourcesPath/.env 를 먼저 시도하고 없으면 프로젝트 루트 .env 로 폴백 - docs/admin-site.md: .exe 빌드에도 .env 가 따라가는 동작 설명 추가 --- docs/admin-site.md | 8 ++++++++ electron-builder.yml | 8 ++++++++ src/shared/env.ts | 28 ++++++++++++++++++++++------ 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/docs/admin-site.md b/docs/admin-site.md index 6e4f10c..23c004e 100644 --- a/docs/admin-site.md +++ b/docs/admin-site.md @@ -25,6 +25,14 @@ npm start # 기본 포트 3000. `.env` 는 `.gitignore` 로 제외되어 있습니다. 새 환경을 셋업할 때 `.env.example` 을 복사해서 시작하세요. 쉘에서 직접 환경변수를 지정한 경우에는 `.env` 값을 덮어쓰지 않습니다. +#### 설치기 `.exe` 빌드에도 적용됨 + +`npm run dist:win` 으로 만든 설치기 `.exe` 도 빌드 시점의 `.env` 를 함께 가져갑니다 (`electron-builder` 의 `extraResources` 로 `resources/.env` 에 배포). 런타임에서는 `process.resourcesPath/.env` → `<프로젝트 루트>/.env` 순으로 찾기 때문에: + +- 운영자가 `SITE_BASE_URL=https://mq.example.com` 으로 `.env` 를 설정해 두고 빌드 → 최종 사용자가 받은 `.exe` 가 그 도메인의 `manifest.json` 을 자동으로 받아옴. +- 빌드 이후라도 설치된 폴더(`resources/.env`) 를 텍스트 편집기로 고치면 도메인을 바꿀 수 있음. +- 빌드 시점에 `.env` 가 없으면 단순히 빠진 채로 패키징되고, 코드 기본값(`http://127.0.0.1:3000`) 이 그대로 사용됩니다. + ## 도메인 / 경로 구성 | 경로 | 내용 | diff --git a/electron-builder.yml b/electron-builder.yml index 5055904..eeeb357 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -4,8 +4,16 @@ directories: output: release files: - dist/installer/** + - dist/shared/** - installer/** - package.json +# 빌드 시점의 .env 를 설치기 옆에 함께 배포(없으면 조용히 패스). +# 패키징 후 운영자가 resources/.env 만 교체해서 도메인을 바꿀 수도 있음. +extraResources: + - from: . + to: . + filter: + - .env win: target: nsis artifactName: ${productName}-${version}-Setup.${ext} diff --git a/src/shared/env.ts b/src/shared/env.ts index 82f39c0..3bc5485 100644 --- a/src/shared/env.ts +++ b/src/shared/env.ts @@ -4,16 +4,32 @@ import dotenv from 'dotenv' import { projectRoot } from './paths.js' /** - * 프로젝트 루트의 `.env` 를 읽어 `process.env` 에 주입. + * `.env` 를 읽어 `process.env` 에 주입. * - * - 이미 설정된 환경변수는 덮어쓰지 않음(쉘에서 넘긴 값이 우선). - * - 파일이 없으면 조용히 통과 — 운영 환경에서는 시스템 env 만으로도 동작해야 함. + * 탐색 순서(처음 발견된 것만 사용): + * 1. 패키징된 Electron 앱이면 `process.resourcesPath/.env` + * — electron-builder 의 extraResources 로 빌드 시점 `.env` 가 함께 배포됨. + * 2. `<프로젝트 루트>/.env` + * — 개발 실행(npm start / npm run installer*) 및 서버 운영용. + * + * - 이미 설정된 환경변수는 덮어쓰지 않음(쉘/systemd 에서 넘긴 값이 우선). + * - 파일이 없으면 조용히 통과. * - 서버/설치기/리소스팩설치기 진입점에서 한 번씩 호출. */ export function loadEnv(): void { - const envPath = path.join(projectRoot, '.env') - if (!fs.existsSync(envPath)) return - dotenv.config({ path: envPath, override: false, quiet: true }) + 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')) + } + candidates.push(path.join(projectRoot, '.env')) + + for (const envPath of candidates) { + if (fs.existsSync(envPath)) { + dotenv.config({ path: envPath, override: false, quiet: true }) + return + } + } } /**