--- id: module-system-project-structure title: "모듈 시스템과 프로젝트 구성" category: "Programming_Language" status: "draft" verification_status: "applied" canonical_id: "" aliases: ["import", "export", "모듈", "barrel", "side-effect import", "dynamic import", "esbuild", "번들링"] duplicate_of: "" source_trust_level: "A" confidence_score: 0.92 created_at: 2026-06-13 updated_at: 2026-06-13 review_reason: "" merge_history: [] tags: ["typescript", "module", "import", "esbuild", "project-structure", "astraai"] raw_sources: ["AstraAI/src/extension.ts", "AstraAI/src/memory/index.ts", "AstraAI/src/retrieval/index.ts", "AstraAI/package.json", "AstraAI/tsconfig.json"] applied_in: ["AstraAI"] github_commit: "" --- # [[모듈 시스템과 프로젝트 구성]] ## 🎯 한 줄 통찰 (One-line insight) 모듈 시스템은 "무엇을 공개하고(`export`) 무엇을 가져올지(`import`)"로 코드 경계를 긋는 것이며, AstraAI 는 **barrel(index.ts) 재수출·side-effect import 자기등록·동적 import 지연로딩**을 조합해 308개 파일을 esbuild 단일 번들로 묶는다 [S1][S4]. ## 🧠 핵심 개념 (Core concepts) 1. **ES Module 문법:** `import { x } from './m'` / `export function x()`. TypeScript 는 이 문법을 쓰고, tsconfig `module: commonjs` 로 CommonJS 로 컴파일된다 [S5]. 2. **named vs default export:** AstraAI 는 거의 전부 *named export* 만 쓴다 — 자동완성·일관된 이름·리팩터링 안전성 때문. default export 는 사실상 배제 [S2]. 3. **Barrel 파일 (index.ts):** 하위 모듈을 한 곳에서 재수출(`export * from './types'`)해 외부가 깔끔한 진입점 하나만 import 하게 한다 [S2][S3]. 4. **Side-effect import:** `import './features/teamops/handlers'` — 값을 가져오지 않고 *모듈 로드의 부수효과*(핸들러 자기등록)만 노린다 [S1]. 5. **Dynamic import (`await import(...)`):** 무겁거나 드물게 쓰는 모듈을 실제 호출 시점에 지연 로딩 — 활성화 시간 단축 [S1]. 6. **번들링 (esbuild):** 모든 모듈을 `out/extension.js` 하나로 묶되 `vscode` 는 external (런타임 제공) [S4]. ## 🧩 추출된 패턴 (Extracted patterns) - **상대경로 import + 명확한 트리:** `../config`, `./types` 같은 상대경로로 모듈을 참조하고, 폴더 구조가 곧 도메인 경계(`features/`, `core/`, `memory/`, `retrieval/`, `intelligence/`). - **barrel 재수출로 진입점 단일화:** `src/memory/index.ts` 가 5개 메모리 클래스 + distillation API + `export * from './types'` 를 한 번에 노출 [S3]. - **side-effect import 로 핸들러 자기등록:** entry point 가 `import './features/system/handlers'` 만 하면 그 모듈이 slashRouter 에 자기를 등록 — 등록 코드를 한 곳에 모으지 않는 분산 등록 [S1]. - **동적 import 로 무거운 기능 지연:** `const { runDatacollectSetup } = await import('./features/setup/datacollectSetup')` — 명령 실행 시에만 로드 [S1]. - **타입 전용 import:** `import type { ChatMessage } from '../../agent'` — 컴파일 후 사라지는 타입만 가져와 순환참조·번들 부담 회피 [S6]. ## 📖 세부 내용 (Details) ### 폴더 = 도메인 경계 ``` src/ core/ 공통 인프라 (lock, queue, transaction, errors, services, events) features/ 기능 도메인 (각 폴더가 독립 기능: stocks, calendar, company, datacollect…) memory/ 5계층 메모리 retrieval/ RAG 검색 intelligence/ 검증·자기평가 (critic, confidence, correctionLoop) lib/ 순수 헬퍼 + contextBuilders (프롬프트 컨텍스트 조립) agent/ 에이전트 실행 세부 (handlePrompt/, llm/, actions/, multiAgent/) ``` 각 폴더 안에 `index.ts`(barrel)가 있으면 외부는 그 하나만 import 한다. ### import 순서·스타일 실제 코드는 (1) Node 표준(`fs`, `path`), (2) vscode, (3) 내부 모듈 순으로 import 하며, 내부는 도메인별로 묶어 가독성을 유지한다. 거대한 orchestrator(agent.ts)는 import 가 100줄을 넘는데, 이는 *기능을 작은 모듈로 추출하고 다시 끌어모으는* 구조의 자연스러운 결과다 [S1]. ### side-effect import 의 순서 민감성 ```typescript // slashRouter 가 먼저 로드된 뒤 핸들러가 자기 등록되도록 entry point 에서 import import './features/teamops/handlers'; import './features/system/handlers'; import './features/datacollect/handlers'; ``` 주석이 "왜 여기서 import 하는지"(로드 순서 보장)를 명시한다 — side-effect import 는 순서가 동작에 영향을 주므로 의도를 적는 것이 필수 [S1]. ### 번들/빌드 - `compile`: `esbuild src/extension.ts --bundle --platform=node --external:vscode --outfile=out/extension.js` — 단일 파일 번들 [S4]. - `watch`: `tsc -watch` (타입 체크용), `test`: `jest`. 런타임 의존성은 `@lmstudio/sdk`, `pdf-parse` 둘뿐이고 axios 대신 native `fetch` 사용 [S4]. ## ⚖️ 모순 및 업데이트 (Contradictions & updates) - **barrel 의 양날:** index.ts 재수출은 진입점을 깔끔히 하지만, 과하면 순환참조와 "한 줄 import 가 거대한 그래프를 끌어옴" 문제를 낳는다. AstraAI 는 무거운 기능을 동적 import 로 분리해 이를 완화 [S1]. - **commonjs vs ESM:** tsconfig 는 `commonjs` 로 컴파일하지만 소스는 ESM 문법으로 작성한다 — VS Code 확장 런타임(Node)이 CJS 를 기대하기 때문. 새 프로젝트라면 ESM 출력도 가능하나 호환성 고려 필요 [S5]. ## 🛠️ 적용 사례 (Applied in summary) - `AstraAI/src/extension.ts` — side-effect import, 동적 import, 100+줄 named import 의 실제 예 [S1]. - `AstraAI/src/memory/index.ts`, `src/retrieval/index.ts` — barrel 재수출 [S2][S3]. ## 💻 코드 패턴 (Code patterns) ```typescript // 1) side-effect import — 핸들러 자기등록 (순서 주석 필수) (src/extension.ts) import './features/teamops/handlers'; import './features/system/handlers'; // 2) barrel 재수출로 진입점 단일화 (src/memory/index.ts) export { ShortTermMemory } from './ShortTermMemory'; export { LongTermMemory } from './LongTermMemory'; export * from './types'; // 3) 동적 import 로 무거운 기능 지연 (src/extension.ts) vscode.commands.registerCommand('g1nation.setupDatacollect', async () => { const { runDatacollectSetup } = await import('./features/setup/datacollectSetup'); await runDatacollectSetup(); }); // 4) 타입 전용 import — 런타임 부담/순환참조 회피 import type { AgentExecutorOptions, ChatMessage } from '../../agent'; ``` ## ✅ 검증 상태 및 신뢰도 - **상태:** draft - **검증 단계:** applied - **출처 신뢰도:** A - **신뢰 점수:** 0.92 - **중복 검사 결과:** 신규 생성 (New discovery) ## 🔗 지식 그래프 (Knowledge Graph) - **상위/루트:** [[TypeScript 기초와 타입 시스템]] - **관련 개념:** [[AstraAI 아키텍처 개요]], [[VSCode 확장 구조와 생명주기]], [[코딩 컨벤션과 주석 철학]] - **참조 맥락:** 로컬 LLM 이 파일을 나누고 import/export 를 구성할 때 참조. ## 📚 출처 (Sources) - [S1] AstraAI/src/extension.ts — side-effect/동적 import, named import 구성 - [S2] AstraAI/src/features/providers/index.ts — named export, 재수출 - [S3] AstraAI/src/memory/index.ts, src/retrieval/index.ts — barrel(export *) 패턴 - [S4] AstraAI/package.json — esbuild 번들 스크립트, 의존성 - [S5] AstraAI/tsconfig.json — module/target 설정 - [S6] AstraAI/src/agent/multiAgent/workflow.ts — import type ## 📝 변경 이력 (Change history) - 2026-06-13: AstraAI 코드 분석 기반 초안 생성.