Frontend는 모델을 실행하지 않는다
React는 사용자 입력과 대화 화면을 관리한다. TypeScript와 Vite가 browser용 JavaScript·CSS로 변환하고, production에서는 Nginx가 완성된 정적 파일을 전달한다.
Frontend는 추론을 “사람이 사용할 수 있는 상호작용”으로 번역한다
TurboFieldfare의 API는 JSON 요청을 받고 JSON 또는 stream을 돌려준다. 컴퓨터에는 충분하지만 사람에게는 입력 상자, 전송 버튼, 대화 순서, 생성 중 표시, 오류 안내가 필요하다. Frontend는 모델 자체의 지능을 높이지 않지만 사용자가 모델의 상태를 이해하고 안전하게 조작하게 만든다.
실제 파일과 학습 문서의 대응
| 실제 source | 역할 | 설명 문서 |
|---|---|---|
fe/Dockerfile
|
개발·build·production image 정의 | Dockerfile.html |
fe/.dockerignore
|
build context에서 제외할 파일 | Dockerfile의 context 절 |
fe/nginx.conf
|
정적 파일·SPA·health 제공 | nginx.conf.html |
fe/src/main.tsx
|
React를 div#root에 연결하는 진입점 | main.tsx.html |
fe/src/App.tsx
|
채팅 화면과 state | App.tsx.html |
fe/vite.config.ts
|
TSX를 브라우저용 파일로 바꾸는 설정 | vite.config.ts.html |
fe/index.html
|
브라우저가 처음 받는 문서 · div#root | index.html.html |
fe/src/index.css
|
전역 토큰과 브라우저 기본값 정리 | index.css.html |
fe/src/App.css
|
채팅 화면 레이아웃과 반응형 | App.css.html |
fe/package.json
|
의존성과 npm 명령 | package.json.html |
fe/tsconfig*.json
|
브라우저 코드와 도구 코드의 type 검사 | tsconfig.json.html |
fe/dist/
|
build 결과물 (자동 생성) | 생성 과정과 대표 산출물 |
TSX 파일은 브라우저가 그대로 실행할 수 없다
현재 npm run build는 tsc -b로 type을 검사한 뒤 vite build로 배포 파일을 만든다. npm run dev로 Vite 개발 서버를 띄운다는 사실만으로 별도 TypeScript 검사가 모두 수행되는 것은 아니다.
App.tsx에는 HTML처럼 보이는 JSX와 TypeScript type이 들어 있다. 브라우저의 JavaScript engine은 TypeScript type을 해석하지 못하므로 build 단계가 필요하다.
Vite와 TypeScript가 source를 구문 트리로 읽는다.
Vite가 TSX를 브라우저용 JavaScript로 변환한다. type 검사는 별도 tsc 단계다.
React와 여러 module을 배포하기 좋은 asset으로 연결한다.
브라우저가 JS를 실행하고 실제 화면 요소를 만든다.
JSX, DOM, 렌더링은 각각 무엇인가?
JSX는 개발자가 화면 구조를 읽기 쉽게 적는 문법이다. DOM은 브라우저 메모리 안에 만들어진 실제 문서 구조다. 렌더링은 현재 React state를 바탕으로 필요한 DOM 변경을 계산하고, 브라우저가 그 결과를 화면의 pixel로 그리는 과정이다. JSX 자체가 화면은 아니다.
Source에서 browser까지
사람이 읽는 source.
type 오류를 찾는다.
browser asset 생성.
HTTP로 전달.
현재 App.tsx는 무엇을 실제로 하는가?
const [sidebarOpen, setSidebarOpen] = useState(false)
const [prompt, setPrompt] = useState('')
const [messages, setMessages] = useState<string[]>([])
const send = () => { const text = prompt.trim(); if (!text) return; setMessages((current) => [...current, text]); setPrompt('') }
현재 messages는 role·content 객체 배열이 아니라 string[]이다. send는 입력 공백을 정리하고 빈 문자열을 거절한 뒤, 사용자 문장을 배열에 추가하고 입력 상자를 비운다. 각 문장 밑에는 “FastAPI가 연결되면…”이라는 고정 안내 문구를 표시한다. 실제 HTTP 요청, assistant 응답 저장, streaming, isGenerating은 아직 없다. 한 줄씩 해설과 실제 값 추적은 App.tsx 상세 문서에 있다.
최근 대화 목록·모델 선택·검색·보관 버튼도 현재는 예시 UI이며 API와 연결된 기능이 아니다. 이 단계의 동작 확인은 입력·전송·초기화·반응형 배치를 보는 것이다. Gemma 답변 생성과 대화 영구 저장까지 구현됐다는 뜻이 아니다.
Streaming 연결 후 목표로 하는 데이터 변화
채팅 UI의 핵심은 메시지 배열과 생성 상태다. 예를 들어 초기 state가 []이고 사용자가 “안녕”을 보내면 사용자 메시지가 추가된다. 서버가 streaming을 시작하면 비어 있는 assistant 메시지를 만들고, 도착하는 text 조각을 같은 항목에 누적한다.
위 메시지 구조와 스트리밍 단계는 향후 설계 예시이며 현재 App.tsx의 실행 결과가 아니다. 그때 isGenerating 같은 boolean state를 함께 두면 중복 전송을 막고 중지 버튼이나 loading indicator를 표시할 수 있다. 네트워크 오류가 발생하면 이미 입력한 사용자 메시지는 유지하면서 assistant 항목에 재시도 가능한 오류 상태를 표시하는 편이 좋다.
왜 문자열을 화면에 바로 덧붙이지 않고 state를 바꾸나?
React는 state를 화면의 단일 근거로 사용한다. DOM을 직접 수정하면 React가 알고 있는 값과 실제 화면이 달라져 다음 render에서 내용이 사라지거나 중복될 수 있다. “state를 변경하면 React가 화면을 갱신한다”는 한 방향 규칙을 지키면 동작을 추적하고 test하기 쉬워진다.