React 프로젝트 해부 — Java 개발자의 눈으로 (React 입문기 #2)

지난 편에서 정보처리기사 학습 앱을 만들기 위해 Vite + React + TypeScript 프로젝트를 세팅했습니다. 이번 편은 코드를 쓰기 전에 한 일 — 생성된 프로젝트를 해부하며 “이게 다 뭐지?”를 하나씩 없앤 기록입니다. 4년차 Java 백엔드 개발자의 눈에 React 프로젝트가 어떻게 보이는지, 낯섦과 익숙함을 그대로 적었습니다.

package.json — 아, 이거 build.gradle이구나

제일 먼저 연 파일은 package.json입니다. 처음엔 낯설었는데, "scripts" 항목을 보는 순간 익숙해졌습니다.

"scripts": {
  "dev": "vite",
  "build": "tsc -b && vite build",
  "preview": "vite preview"
}

이건 Gradle 태스크입니다. npm run dev는 gradle bootRun이고, dependencies는 Gradle의 dependencies 블록이고, node_modules는 로컬에 풀린 의존성 캐시입니다. 새 생태계를 배울 때 가장 빠른 길은 내가 아는 생태계의 대응물을 찾는 것이라는 걸 다시 확인했습니다. 물론 대응이 완벽하진 않아서, 그 “어긋나는 지점”이 진짜 배울 거리라는 것도요.

실행 사슬 추적: index.html → main.tsx → App.tsx

백엔드 개발자의 본능으로 “진입점이 어디냐”부터 찾았습니다. Java라면 main 메서드나 web.xml을 찾을 텐데, React 프로젝트의 사슬은 이랬습니다.

  1. index.html — <div id="root"></div> 하나와 <script type="module" src="/src/main.tsx">
  2. main.tsx — root 엘리먼트를 잡아서 createRoot(...).render(<App />)
  3. App.tsx — 화면에 보이는 내용이 실제로 정의된 곳

정적인 HTML은 빈 껍데기 하나뿐이고, 화면 전체가 JavaScript(TypeScript)에서 만들어져 주입된다는 구조입니다. JSP처럼 서버가 HTML을 만들어 내려보내는 세계에서 왔다면, 이 “빈 HTML + 전부 JS” 구조가 SPA의 출발점이라는 게 첫 번째 개념 전환이었습니다.

JSX 첫인상: 함수가 HTML을 리턴한다고?

App.tsx를 열었을 때의 솔직한 첫인상은 이겁니다 — “함수가 HTML을 리턴하네?”

function App() {
  return (
    <div>
      <h1>Vite + React</h1>
      ...
    </div>
  )
}

Java에서 문자열로 HTML을 조립해본 기억 때문에 처음엔 “리턴 타입이 String인가?” 싶었지만, 따옴표가 없습니다. 이건 문자열이 아니라 JSX라는 문법으로, 빌드 시점에 함수 호출로 변환되는 코드라는 걸 배웠습니다. 즉 저 HTML처럼 생긴 것의 정체는 “화면 조각을 만들어내는 객체”이고, 그래서 변수에 담을 수도, 조건문으로 갈아끼울 수도 있다는 것 — 여기서부터 React식 사고가 시작된다는 감이 왔습니다. 텍스트를 수정하고 저장하는 순간 브라우저가 새로고침 없이 즉시 바뀌는 것(HMR)도 신선했습니다. Java 재기동에 익숙한 몸에는 문화 충격에 가깝습니다.

초보의 순간들도 기록해둔다

부끄럽지만 이런 순간도 있었습니다. 터미널을 닫았더니 개발 서버가 꺼졌는데 “서버 어떻게 다시 켜지?”를 물어본 것. 답은 당연히 npm run dev입니다. package.json의 scripts를 방금 봐놓고도 손이 안 나간 거죠. 새 생태계에서는 “아는 것”과 “손에 붙은 것” 사이의 거리가 생각보다 멀고, 그 거리는 반복으로만 줄어든다는 걸 체감합니다. 이런 순간을 기록해두는 이유는, 나중에 “React 별거 아니던데”라고 말하게 됐을 때 이 글이 증거가 되기 때문입니다.

지금까지 만든 대응표

이번 탐험에서 만든 “Java 개발자를 위한 React 대응표” 초안입니다. 배울수록 갱신할 예정입니다.

  • package.json scripts ↔ Gradle 태스크
  • node_modules ↔ 의존성 캐시 (.gradle/캐시)
  • main.tsx ↔ main 메서드 (부트스트랩)
  • 컴포넌트 함수 ↔ “화면 조각을 리턴하는 메서드” (단, 리턴하는 건 문자열이 아니라 JSX)
  • HMR ↔ (대응물 없음 — 재기동 없는 세계)

다음 편

다음은 JSX를 제대로 씁니다 — 변수 표시, 조건부 렌더링, 목록 렌더링까지. 정처기 기출 문제 하나를 화면에 그려보는 게 다음 편의 목표입니다.

덧붙여

이 학습은 AI 에이전트를 튜터로 씁니다. 에이전트는 답을 코드로 주지 않고 과제와 질문(“App 함수가 리턴하는 게 뭐로 보이는가?”)을 주고, 제가 답을 가져가야 다음 설명이 시작됩니다. 이 문답에서 나온 제 오답과 첫인상들이 이 시리즈의 재료입니다.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top