# 외부 프로젝트 설치 — Git Submodule + npm Workspace > 2026-10-20 작성, 2026-10-23 갱신(저장소 주소 `shkim4`, HM 패키지 npm Registry 미사용 명시). 현재 HMDesign을 다른 React 프로젝트에서 쓰는 공식 방식입니다. npm Registry publish 없이 Git 저장소를 Submodule로 연결하고, HMDesign 안에서 패키지를 빌드한 뒤 소비 프로젝트의 npm Workspace로 연결합니다. > 실제 적용 근거: 외부 DWG/DXF Viewer(React 19, `@hm-design/ui` + `@hm-design/sw`)가 이 절차로 연결되었습니다. 패키지 tarball 소비 검증은 `packages/sw/tests/integrated-consumer.mjs`가 별도로 수행합니다. ## 1. 전제 | 항목 | 기준 | |---|---| | Node.js / npm | `package-lock.json`의 엔진 조건 `^20.19.0 \|\| >=22.12.0`(Node 21 제외). 검증 기록: Node 20.20.1 / npm 10.8.2(2026-10-11), Node 22.23.2 / npm 10.9.8(2026-10-20) | | React | 소비 프로젝트 `react`·`react-dom` `^19.0.0`(모든 패키지의 peer) | | 네트워크 | 최초 설치에 Gitea(`https://gitea.hmac.kr/shkim4/HMDesign.git`)와 외부 dependency용 공개 npm Registry(`registry.npmjs.org`) 접근 필요. HM 패키지용 Gitea npm Registry·`.npmrc` 설정은 쓰지 않음 | | Git | 패키지 `dist/`는 Git에 포함되지 않습니다(`.gitignore`). Clone·Commit 변경 후에는 항상 HMDesign 안에서 다시 빌드합니다. | ## 2. Submodule 연결과 검증 Commit 고정 소비 프로젝트 루트에서 실행합니다. `<검증 Commit>`은 사용할 HMDesign Commit의 전체 SHA입니다(브랜치 이름을 그대로 쓰지 않습니다). ```bash git submodule add https://gitea.hmac.kr/shkim4/HMDesign.git HMDesign git -C HMDesign fetch origin git -C HMDesign checkout <검증 Commit> git add .gitmodules HMDesign git commit -m "chore: pin HMDesign <검증 Commit>" ``` - 소비 프로젝트에 기록되는 것은 Submodule Commit 포인터입니다. 다른 사람·CI는 `git submodule update --init --recursive`로 같은 Commit을 받습니다. - Submodule 안에서 HMDesign 파일을 직접 수정하지 않습니다. `git status`에 `HMDesign (modified content)` / `-dirty`가 보이면 고정 Commit과 다른 코드로 빌드된 상태입니다. 그 상태의 검증 결과는 해당 Commit의 결과로 보고하지 않습니다. - 이전 주소(`https://gitea.hmac.kr/b25027/HMDesign.git`)로 연결한 Submodule은 리다이렉트로 동작하지만 현재 주소로 바꿉니다. `git submodule set-url HMDesign https://gitea.hmac.kr/shkim4/HMDesign.git` → `git submodule sync` → `.gitmodules` Commit. Submodule Commit 포인터와 `npm ci`·빌드 절차는 바뀌지 않습니다. ## 3. HMDesign 안에서 설치·빌드 ```bash git submodule update --init --recursive cd HMDesign npm ci npm run build:packages cd .. ``` - `npm ci`는 HMDesign 자체 빌드 도구(Vite·TypeScript·Tailwind 등)를 `HMDesign/node_modules`에 설치합니다. 패키지 빌드 스크립트가 이 위치의 도구를 사용하므로 생략할 수 없습니다. - `build:packages`는 `org-chart → ui → center-graphic → org-chart-react → sw` 순서로 5개 패키지의 `dist/`를 만듭니다. 필요한 패키지만 빌드할 때는 `npm run build:ui`, `npm run build:sw`를 쓸 수 있고, `org-chart-react`는 `org-chart`를 먼저 빌드해야 합니다. ## 4. 소비 프로젝트 Workspace 연결 소비 프로젝트 `package.json`에 사용할 패키지만 Workspace와 dependency로 추가합니다. ```json { "workspaces": ["HMDesign/packages/ui", "HMDesign/packages/sw"], "dependencies": { "@hm-design/ui": "*", "@hm-design/sw": "*", "react": "19.3.0", "react-dom": "19.3.0" } } ``` ```bash npm install ``` - `npm install` 후 `node_modules/@hm-design/<패키지>`는 `HMDesign/packages/<패키지>`를 가리키는 링크입니다. Import는 패키지 `exports`의 공개 진입점만 사용합니다(`dist`·`src` 내부 경로 금지). - OrgChart를 쓰면 `HMDesign/packages/org-chart`(와 React에서는 `HMDesign/packages/org-chart-react`)를 추가합니다. - Vite 소비 프로젝트는 HMDesign 저장소 안의 예제·Export용 HTML을 의존성 스캔에서 제외하도록 `optimizeDeps.entries: ['index.html']`를 지정합니다(외부 Viewer에서 확인된 설정). ## 5. CSS Import | 패키지 | 앱 진입점 | |---|---| | Web `@hm-design/ui` | CSS entry에서 `@import "tailwindcss";` → `@import "@hm-design/ui/tailwind.css";` → `@import "@hm-design/ui/theme.css";`. Tailwind 검색 범위는 [Runtime portability](./runtime-portability.md#21-tailwind-v4-소비자-검색-범위)를 따릅니다. | | SW `@hm-design/sw` | `import "@hm-design/sw/styles.css"`를 한 번. JS import만으로 CSS가 들어오지 않습니다. 글꼴 파일은 포함하지 않습니다(기본 Noto Sans KR). | | OrgChart | Core CSS 두 개(`@hm-design/org-chart/engine.css`, `@hm-design/org-chart/style.css`)를 URL로 해석해 `stylesheetUrls`에 전달합니다(Shadow DOM). 문서에 import하는 것만으로는 적용되지 않습니다. | Web과 SW를 함께 쓰면 두 CSS의 순서는 서로의 계산 스타일을 바꾸지 않습니다(`integrated-consumer` 검증 항목). ## 6. AI 지침 탐색 - 소비 프로젝트의 AI 코딩 도구는 `node_modules/@hm-design/<패키지>/ai/`(= `HMDesign/packages/<패키지>/ai/`)를 읽습니다. 진입점은 각 폴더의 `AI_GUIDE.md`이며 사용 유형(Web / SW 일반·뷰어 / OrgChart / 혼합)을 먼저 정합니다. - 루트 `AGENTS.md`·`CLAUDE.md`는 자동으로 연결되지 않습니다. `ai/AGENTS_SNIPPET.md`의 문구를 소비 프로젝트 루트 지침에 붙입니다(방법은 `AI_GUIDE.md`의 "소비 프로젝트 설정"). - HMDesign 저장소 루트의 `AGENTS.md`·`CLAUDE.md`는 HMDesign을 개발하는 AI용이며 소비 프로젝트 지침이 아닙니다. ## 7. HMDesign 버전 갱신 ```bash git -C HMDesign fetch origin git -C HMDesign checkout <새 검증 Commit> cd HMDesign && npm ci && npm run build:packages && cd .. npm install git add HMDesign git commit -m "chore: update HMDesign to <새 검증 Commit>" ``` 갱신 후 소비 프로젝트의 Typecheck·Build·화면 확인을 다시 실행합니다. ## 8. Registry 없이 사용할 때의 제약 - `dist/`가 Git에 없으므로 Clone·Commit 변경·CI마다 HMDesign 빌드(§3)가 필요합니다. CI에서도 Submodule 초기화와 `npm ci && npm run build:packages`를 실행합니다. - HMDesign 빌드 도구와 소비 프로젝트 도구가 따로 설치됩니다(예: 외부 Viewer는 TypeScript 5.9·Vite 5, HMDesign은 TypeScript 7·Vite 8). 패키지는 HMDesign 도구로 빌드되고 소비 프로젝트는 결과물만 사용합니다. - 버전 식별은 Submodule Commit SHA입니다. SW 패키지는 `dist/build-info.json`에 빌드한 Commit과 dirty 여부를 기록합니다. - HM 패키지는 npm Registry로 배포하지 않습니다. `npm install @hm-design/<패키지>@<버전>`으로 설치하거나 `.npmrc`에 `@hm-design:registry`를 추가하지 않습니다. 2026-10-07 Gitea npm Registry에 시험 게시한 `@hm-design/ui@0.1.0`·`@hm-design/center-graphic@0.1.0`은 현재 소스와 다른 이전 산출물입니다. - `package.json`의 `version`(예: `0.1.0`)은 Workspace 연결과 peer 범위용 값이며 Registry 배포 버전이 아닙니다. Theme CDN 등 운영 배포는 [운영/배포 가이드](./운영-배포-가이드.md)를 따릅니다.