---
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 코드 분석 기반 초안 생성.
