📝 Notes
@uiw/react-md-editor 기반, KaTeX/GFM 지원, 자동 저장.
- 메타만 선로딩 → 본문(.md)은 클릭 시 로딩
- 북마크/검색/태그, 트리 DnD 정렬
Electron + React + TypeScript 기반의 학습 생산성 데스크톱 앱. 노트(마크다운), 플래시카드(복습), 캘린더(일정)를 통합하고 PDF/CSV/(경량)XLS 내보내기를 지원합니다.
contextIsolation
으로 보안 경계 강화@uiw/react-md-editor 기반, KaTeX/GFM 지원, 자동 저장.
카테고리-카드 트리, Q/A 편집, 키보드 네비게이션.
월간 보기, 기간 이벤트, 모달 편집/삭제/추가.
단일 JSON 저장으로 초기 로딩/메모리 급증, 이미지 누수, 무거운 내보내기 의존성.
메타/본문 분리 + 지연 로딩, 이미지 자동 저장·경로 정규화, 경량 Export.
초기 메모리/IO 체감 감소, 디스크 안정성 개선, 배포 사이즈/공격면 축소.
Electron App ├─ Main: 파일 I/O, Export(PDF/CSV/XLS), 이미지 관리, IPC ├─ Preload: 안전한 브릿지(contextIsolation) └─ Renderer(React): 노트/플카/캘린더 UI & 상태 저장 구조 ├─ notes-meta.json # 메타(제목/태그/업데이트) └─ notes/<id>.md # 본문(마크다운)
의존성: Electron 37, React 18, TypeScript 5, Vite 7, framer-motion, date-fns
관심사 분리
contextBridge.exposeInMainWorld("nt", { openNote: (id) => ipcRenderer.invoke("notes:open", id), saveNote: (id, md) => ipcRenderer.invoke("notes:save", { id, md }), exportPDF: (ids) => ipcRenderer.invoke("export:pdf", ids), });
Renderer는 파일 시스템에 직접 접근하지 않음.
const win = new BrowserWindow({ show:false, webPreferences:{ offscreen:true }}); await win.loadURL(htmlPath); const pdf = await win.webContents.printToPDF({ printBackground:true }); await fs.promises.writeFile(out, pdf);
Headless에 가까운 방식으로 의존성 최소화.
ipcMain.handle("image:save", async (_e, { buffer, ext }) => { const file = join(imgDir, `${Date.now()}.${ext}`); await fs.promises.writeFile(file, buffer); return pathToFileURL(file).toString(); // file:///... 로 통일 });
Markdown에는 file:// URL만 삽입 → OS간 일관성.
// 초기엔 notes-meta.json만 로드 const meta = await loadMeta(); const open = async (id) => { const md = await fs.promises.readFile(`notes/${id}.md`, "utf-8"); setEditor(md); };
대용량에서도 초기 반응성 유지.
const html = `<table>...</table>`; const blob = Buffer.from(html, "utf-8"); await fs.promises.writeFile(out, blob); // 레거시 XLS 열람 호환
채널 | 요청 페이로드 | 설명 |
---|---|---|
notes:open | id: string |
노트 본문(.md) 로드 |
notes:save | { id, md } |
노트 저장(자동 저장과 병행) |
image:save | { buffer, ext } |
이미지 파일 저장 → file:/// URL 반환 |
export:pdf | ids: string[] |
선택 노트 PDF로 내보내기 |
export:csv | rows: any[] |
플래시카드/캘린더 CSV 내보내기 |
export:xls | html: string |
HTML-table 기반 경량 XLS 내보내기 |
REST: N/A (로컬-퍼스트, 네트워크 의존 없음)
항목 | 처리 | 근거 |
---|---|---|
API Keys | N/A | 오프라인 로컬-퍼스트 |
파일 경로 | ~ /AppData, ~/Library 등 표시 단순화 |
개인 경로 마스킹 |
개인 데이터 | 내보내기 시 선택적 제거 | 개인정보 최소화 |
협업과 코드 리뷰를 좋아합니다. 필요 시 실사용 데모·코드 워크스루 제공 가능합니다.