1편 | 웹사이트 개발 핵심 개념
웹사이트 개발의 세계에 발을 들이면 정말 다양한 용어들이 쏟아져 나와요. 홈페이지, 웹사이트, 플랫폼, 프론트엔드, 백엔드... 처음엔 뭔가 복잡해 보이지만 걱정하지 마세요. 이번 편에서는 이 핵심 개념들을 일상적인 비유로 쉽게 풀어드릴게요. 마치 친한 선배가 옆에서 차근차근 설명해주는 것처럼 말입니다. 홈페이지와 웹사이트가 어떻게 다른지, 프론트엔드와 백엔드가 어떤 역할을 하는지 하나씩 알아가다 보면, 웹사이트 개발이 훨씬 친근하게 느껴질 것입니다.
1. 홈페이지 vs 웹사이트 vs 플랫폼 차이점
"홈페이지 하나 만들어주세요" 이런 말, 정말 자주 들어봤을 것입니다. 하지만 실제로는 웹사이트 전체를 원하는 경우가 대부분입니다. 이런 미묘한 차이를 정확히 이해하지 못하면, 나중에 "어? 이건 원한 게 아닌데..." 하는 상황이 벌어질 수 있습니다. 그래서 처음부터 개념을 명확히 잡아두는 것이 현명합니다.
1-1. 홈페이지 (Homepage)
정의: 웹사이트의 첫 페이지, 메인 페이지라고 생각하면 돼요
쉬운 설명: 집의 현관문을 생각해보면, 손님이 처음 들어와서 마주하는 공간이죠
특징:
- 웹사이트에 들어가면 제일 먼저 보는 화면입니다
- 회사 소개와 핵심 서비스를 한눈에 보여주죠
- 다른 페이지로 이동하는 관문 역할을 해요
예시: Samsung.com에 들어가보세요. 제일 먼저 보이는 그 화면이 바로 홈페이지입니다.
1-2. 웹페이지 (Webpage)
정의: 브라우저에서 볼 수 있는 하나하나의 페이지라고 생각하면 돼요
쉬운 설명: 두꺼운 책의 한 페이지를 생각해보면, 딱 그런 개념입니다.
특징:
- 하나의 HTML(HyperText Markup Language, 하이퍼텍스트 마크업 언어) 파일이 하나의 웹페이지가 됩니다
- 홈페이지, 회사소개 페이지, 연락처 페이지 등이 모두 각각의 웹페이지입니다
- 여러 웹페이지들이 모여서 하나의 웹사이트를 구성합니다
1-3. 웹사이트 (Website)
정의: 여러 웹페이지들이 모여 있는 전체 사이트라고 보면 돼요
쉬운 설명: 집 전체를 떠올려보세요. 현관, 거실, 방, 화장실... 이 모든 공간이 합쳐진 것처럼 말입니다
특징:
- 홈페이지 + 회사소개 + 서비스소개 + 문의 등 여러 페이지가 하나로 연결되어 있어요
- 주로 정보 전달이 핵심 목적이죠
- 일방향 소통 형태예요 (회사 → 고객으로만)
예시: Samsung.com 전체가 웹사이트입니다 (홈페이지, 제품 페이지, 지원 페이지, 회사소개 등 모든 페이지 포함)
1-4. 플랫폼 (Platform)
정의: 사용자들이 서로 소통하고 거래할 수 있는 살아있는 디지털 공간이라고 생각해보세요
쉬운 설명: 붐비는 백화점이나 전통시장을 생각해보면, 여러 업체와 고객들이 만나고, 대화하고, 거래하는 생생한 장소 말입니다
특징:
- 양방향/다방향 소통이 활발하게 일어나요
- 사용자 간 거래나 교환이 자연스럽게 이루어져요
- 하나의 완전한 생태계를 만들어내죠
예시: 쿠팡(판매자와 구매자가 만나는 공간), 유튜브(창작자와 시청자가 만나는 공간)
1-5. 랜딩 페이지 (Landing Page)
정의: 하나의 명확한 목적을 위해 특별히 만든 독립적인 웹페이지라고 생각하면 돼요
쉬운 설명: 비행기가 착륙(Landing)하는 활주로를 떠올려보세요. 방문자가 광고를 클릭하고 '착륙'하는 그 첫 번째 페이지가 바로 랜딩 페이지입니다
특징:
- 하나의 명확한 목표만 가져요 (회원가입, 구매, 다운로드 등)
- 광고나 검색을 통해 처음 '착륙'하는 페이지죠
- 홈페이지와는 달리 오직 전환(구매/가입)에만 집중해요
예시: "무료 전자책 다운로드" 광고를 클릭했을 때 나오는 다운로드 전용 페이지
1-6. 개발 계획 수립 시 필수 고려사항
미래 확장성을 고려한 기획의 중요성
"일단 홈페이지부터 만들어보자" 많은 분들이 이렇게 생각합니다. 하지만 주의해야 할 점은 이런 접근이 나중에 큰 함정이 될 수 있다는 것입니다. 마치 작은 원룸에 살다가 갑자기 대가족이 되었는데, 집을 통째로 다시 지어야 하는 상황 같아요. 처음부터 최종 목표를 명확히 하고 단계적으로 접근하는 것이 훨씬 현명하고 경제적입니다.
올바른 접근 방법:
2. 풀스택 웹사이트란?
이 책의 제목이기도 한 "풀스택 웹사이트"가 정확히 무엇인지 알아봅시다.
2-1. 풀스택 웹사이트의 정의
정의: 사용자가 보는 화면(프론트엔드)부터 서버, 데이터베이스 등 보이지 않는 내부 동작(백엔드)까지 하나의 시스템 안에 모두 갖춘 웹 애플리케이션
쉬운 설명: 레스토랑으로 비유하면, 손님이 보는 홀(프론트엔드)과 손님이 보지 못하는 주방(백엔드)이 하나의 완전한 레스토랑으로 연결된 것입니다.
2-2. 풀스택 웹사이트의 3가지 핵심 특징
| 특징 | 설명 | 예시 |
|---|---|---|
| **하나의 프로젝트** | 프론트엔드와 백엔드가 분리되지 않고 하나로 통합 | 회원가입 화면 + 회원정보 저장이 한 프로젝트 |
| **전체 흐름 연결** | 사용자 요청 → 서버 처리 → 데이터베이스 저장 → 결과 표시까지 연결 | 버튼 클릭 → 서버 처리 → DB 저장 → 화면 갱신 |
| **완결성** | 외부 도움 없이 독립적으로 작동하는 완전한 시스템 | 로그인, 데이터 저장, 이메일 발송까지 모두 가능 |
2-3. 풀스택 vs 프론트엔드만 vs 백엔드만
| 구분 | 포함 범위 | 예시 |
|---|---|---|
| **프론트엔드만** | 화면만 (서버/DB 없음) | 정적 회사소개 페이지 |
| **백엔드만** | 서버/DB만 (화면 없음) | API 서버 |
| **풀스택** | 화면 + 서버 + DB 전체 | 로그인, 결제, 게시판 가능한 완전한 서비스 |
> SSALWorks의 목표: 이 책을 통해 풀스택 웹사이트 개발의 기초를 익히고, Claude Code의 도움으로 완전한 웹 서비스를 만들 수 있게 됩니다.
3. 프론트엔드와 백엔드 역할 구분
웹사이트를 레스토랑으로 비유하면 프론트엔드와 백엔드의 역할을 쉽게 이해할 수 있습니다.
3-1. 프론트엔드 (Frontend)
쉬운 설명: 사용자가 보고 클릭하는 웹사이트의 겉모습입니다
레스토랑 비유: 홀, 인테리어, 메뉴판, 웨이터 서비스에 해당합니다
역할: 예쁘고 사용하기 편한 화면을 만듭니다
구체적인 일:
- 버튼을 디자인하고 색깔을 정합니다
- 메뉴를 배치하고 폰트를 선택합니다
- 클릭했을 때 반응하는 애니메이션을 만듭니다
- 스마트폰에서도 예쁘게 보이도록 조정합니다
사용 기술: HTML, CSS, JavaScript, React 등을 활용합니다
3-2. 백엔드 (Backend)
쉬운 설명: 사용자가 보지 못하는 서버에서 돌아가는 프로그램입니다
레스토랑 비유: 주방, 요리사, 재료 창고, 계산 시스템에 해당합니다
역할: 실제 비즈니스 로직을 처리합니다
구체적인 일:
- 서비스 요청 신청서가 제출되면 이메일로 알림을 보냅니다
- 로그인 정보를 확인합니다
- 데이터베이스에서 필요한 정보를 가져옵니다
- 결제를 처리하고 영수증을 발행합니다
사용 기술: Node.js, Python, Java, MySQL 등을 활용합니다
3-3. 상호 협력 관계
고객이 "서비스 신청" 버튼을 클릭하면:
4. 웹사이트 개발에서 자주 쓰는 필수 용어들
> 알아두기: 아래 용어들을 모두 외울 필요는 없습니다! Claude Code를 사용하면 코드는 AI가 작성하므로, 용어의 "대략적인 의미"만 알면 됩니다. 모르는 용어가 나오면 부록 용어사전에서 찾아보세요.
4-1. 핵심 용어 (꼭 알아야 할 것)
| 용어 | 의미 | 비유 |
|---|---|---|
| **브라우저** | 웹사이트를 보여주는 프로그램 | 인터넷 창문 |
| **서버** | 웹사이트 파일을 저장하는 컴퓨터 | 24시간 영업하는 창고 |
| **데이터베이스** | 정보를 저장하는 디지털 창고 | 파일 캐비닛 |
| **도메인** | 웹사이트 주소 이름 | google.com, naver.com |
| **호스팅** | 웹사이트를 인터넷에 올려두는 서비스 | 서버 임대 |
4-2. 언어 3종 세트 (Claude Code가 작성해줌)
| 언어 | 역할 | 비유 |
|---|---|---|
| **HTML** | 웹페이지 구조 | 뼈대 |
| **CSS** | 웹페이지 디자인 | 옷, 화장 |
| **JavaScript** | 웹페이지 동작 | 행동, 반응 |
> 참고: 위 언어들의 약어(HTML = HyperText Markup Language 등)는 외울 필요 없습니다. Claude Code가 코드를 작성해주므로 "역할"만 알면 됩니다.
4-3. 개발 도구 용어
| 용어 | 의미 | 비유 |
|---|---|---|
| **프레임워크** | 개발을 쉽게 해주는 도구 세트 | 건축용 크레인 |
| **라이브러리** | 미리 만들어진 코드 모음 | 기성품 문/창문 |
| **API** | 프로그램끼리 대화하는 방법 | 식당 웨이터 |
| **Git** | 코드 버전 관리 시스템 | 문서 수정 이력 |
| **배포** | 웹사이트를 서버에 공개하는 것 | 책 출판 |
4-4. 웹사이트 구조 및 디자인 용어
| 용어 | 의미 | 핵심 |
|---|---|---|
| **UI** | 사용자가 보는 화면 디자인 | 예쁘고 직관적 |
| **UX** | 사용자가 느끼는 전체 경험 | 쉽고 편리하게 |
| **반응형 디자인** | 모든 기기에서 자동 맞춤 | PC, 태블릿, 스마트폰 |
> 참고: CMS, SPA 같은 고급 용어는 부록 용어사전을 참조하세요.
4-5. 보안 및 성능 용어
| 용어 | 의미 | 왜 중요한가 |
|---|---|---|
| **HTTPS** | 안전한 통신 프로토콜 | 주소창 자물쇠 표시 |
| **SSL 인증서** | 보안 연결 인증서 | HTTPS 사용에 필수 |
| **캐시** | 데이터 임시 저장 | 로딩 속도 향상 |
| **CDN** | 전 세계 분산 서버 | 빠른 콘텐츠 전송 |
> 참고: 약어의 원어(HTTPS = HyperText Transfer Protocol Secure 등)는 외울 필요 없습니다. "보안", "속도"와 관련된다는 것만 기억하세요.
작성일: 2025-09-01 / 수정일: 2025-12-20 / 글자수: 약 4,900자 / 작성자: Claude / 프롬프터: 써니
2편 | 웹사이트가 작동하는 원리와 구조
1편에서 웹개발의 핵심 개념과 용어를 정리한 다음, 이번에는 웹사이트가 실제로 어떻게 작동하는지 알아볼 차례입니다. 이번 편에서는 브라우저가 웹페이지를 보여주는 과정, 클라이언트와 서버의 통신, HTTP 프로토콜, 그리고 웹사이트의 기본 구성 요소들을 다룹니다. 주소창에 URL을 입력했을 때 일어나는 일들과 웹사이트가 화면에 나타나기까지의 전체 과정을 살펴봅니다.
1. 브라우저가 웹페이지를 보여주는 과정
1-1 웹사이트 접속의 흥미로운 여행
우리가 주소창에 "google.com"을 입력하고 엔터를 누르는 순간부터 구글 홈페이지가 화면에 나타나기까지, 단 몇 초 사이에 엄청나게 복잡한 과정이 일어납니다.
1-2 웹사이트가 화면에 나타나는 5단계 과정
1단계: 주소 해석 (DNS 조회)
- 브라우저가 "google.com이 어디에 있는지" 인터넷에 질의함
- 여러 DNS(Domain Name System, 도메인 이름을 IP 주소로 변환하는 시스템) 서버를 거쳐 최종적으로 "구글은 142.250.191.14 주소에 있습니다"라고 찾아냄
- 마치 스마트폰 연락처에서 "엄마"를 터치하면 여러 단계를 거쳐 전화번호를 찾아 연결하는 것과 같음
2단계: 서버 연결
- 브라우저가 구글 서버에 "안녕하세요, 홈페이지 주세요"라고 요청
- 이때 HTTP(HyperText Transfer Protocol, 웹에서 데이터를 주고받는 규약) 또는 HTTPS(HTTP + 보안) 프로토콜을 사용
- 서버가 "네, 잠깐만요"라고 응답하며 연결 확립
3단계: 파일 전송
- 서버가 HTML 파일을 브라우저에 전송
- HTML 파일 안에 "이미지도 필요합니다", "CSS 파일도 필요합니다"라는 지시사항 발견
- 브라우저가 추가로 CSS, JavaScript, 이미지 파일들을 요청
4단계: 렌더링 (화면 그리기)
- 렌더링: 브라우저가 받은 파일들을 실제 웹페이지로 변환하는 자동 처리 과정
- 브라우저 내부에서 HTML을 해석하여 DOM(Document Object Model, 웹페이지의 구조를 나타내는 객체 모델)을 자동으로 생성
- 동시에 CSS를 해석하여 CSSOM(CSS Object Model, 스타일 정보를 나타내는 객체 모델)을 자동으로 생성
- 브라우저가 두 정보를 합쳐서 최종 화면 모습 계산
- JavaScript가 있으면 추가로 실행하여 동적 기능이 작동
5단계: 완성
- 우리가 보는 완성된 웹페이지가 화면에 나타남
- 이 모든 과정이 보통 1-3초 안에 완료됨
`mermaid
sequenceDiagram
participant 사용자
participant 브라우저
participant DNS
participant 서버
사용자->>브라우저: google.com 입력
브라우저->>DNS: IP 주소 질의
DNS-->>브라우저: 142.250.191.14 응답
브라우저->>서버: HTTP 요청
서버-->>브라우저: HTML 파일 전송
브라우저->>서버: CSS/JS 요청
서버-->>브라우저: CSS/JS 전송
브라우저->>브라우저: 렌더링
브라우저-->>사용자: 웹페이지 표시
`
1-3 실생활 비유: 피자 전화 주문 과정
피자 전화 주문이 웹사이트 접속과 똑같습니다:
| 피자 주문 과정 | 웹사이트 접속 과정 |
|---|---|
| 전화번호부에서 "피자헛" 검색 | DNS 조회 |
| 피자헛 매장에 전화 연결 | 서버 연결 |
| "마르게리타 피자 하나요" 주문 | HTTP 요청 |
| 매장에서 피자 제작 시작 | 서버 처리 |
| 배달원이 완성된 피자 배달 | 파일 전송 |
| 고객이 맛있게 피자 먹음 | 웹페이지 완성 |
2. HTML, CSS, JavaScript의 역할과 관계
2-1 웹사이트를 구성하는 3대 요소
웹사이트는 마치 사람과 같습니다. 신체구조가 있고, 외모가 있고, 행동이 있죠.
2-2 HTML: 웹사이트의 신체구조
역할: 웹페이지의 구조와 내용을 정의
비유: 사람의 머리, 몸통, 팔다리 등 기본 신체구조
구체적 역할: 머리(제목), 몸통(내용), 팔다리(링크) 구성
HTML 코드 예시:
`html
회사 소개
안녕하세요.

`
2-3 CSS: 웹사이트의 외모
역할: 웹페이지를 예쁘게 꾸미는 디자인 담당
비유: 사람의 헤어스타일, 화장, 옷, 액세서리
CSS가 하는 일: "제목은 파란색으로, 버튼은 빨간 배경에 둥글게"처럼 스타일 지정
> SSALWorks에서는 Tailwind CSS를 사용합니다. CSS를 직접 작성할 필요 없이, Claude Code가 자동으로 스타일을 적용해줍니다.
2-4 JavaScript: 웹사이트의 행동
역할: 웹페이지에 동작과 상호작용을 추가
비유: 사람의 말하기, 걷기, 생각하기, 반응하기
JavaScript가 하는 일: "버튼을 클릭하면 안녕하세요 메시지를 보여줘"처럼 동작 지정
> Claude Code가 JavaScript를 자동으로 작성해줍니다. 여러분은 "로그인 버튼 클릭하면 홈으로 이동" 같은 기능만 요청하면 됩니다.
2-5 3요소의 협력 관계
3. 클라이언트와 서버의 대화 방식
3-1 인터넷은 거대한 대화의 장
웹사이트 이용은 본질적으로 클라이언트와 서버 간의 대화입니다.
클라이언트 vs 서버
- 클라이언트: 서비스를 요청하는 쪽 (우리의 웹 브라우저)
- 서버: 서비스를 제공하는 쪽 (웹사이트 파일들이 저장된 컴퓨터)
3-2 HTTP(하이퍼텍스트 전송 프로토콜)/HTTPS(보안 하이퍼텍스트 전송 프로토콜) 프로토콜: 대화의 규칙
HTTP(하이퍼텍스트 전송 프로토콜; HyperText Transfer Protocol): 클라이언트와 서버가 대화할 때 사용하는 "언어"
HTTPS(보안 하이퍼텍스트 전송 프로토콜; HyperText Transfer Protocol Secure) (보안이 핵심):
- HTTP(하이퍼텍스트 전송 프로토콜)에 SSL(보안 소켓 계층; Secure Sockets Layer)/TLS(전송 계층 보안; Transport Layer Security) 보안 기능 추가
- 주소창에 자물쇠 표시
- 중요성: 모든 데이터가 암호화되어 해킹 방지
- 신뢰도: 사용자가 안심하고 서비스 이용 가능
- 검색 순위: 구글이 HTTPS(보안 하이퍼텍스트 전송 프로토콜) 사이트를 더 높게 평가
3-3 다양한 요청 유형
- GET(가져오기): "정보 주세요" (웹페이지 보기, 검색)
- POST(게시): "정보 저장해주세요" (회원가입, 글쓰기)
- PUT(넣기): "정보 수정해주세요" (프로필 변경)
- DELETE(삭제): "정보 삭제해주세요" (글 삭제)
4. 웹사이트 폴더와 파일 구조
4-1 웹사이트도 컴퓨터 폴더처럼 정리되어 있다
우리가 컴퓨터에서 문서를 폴더별로 정리하듯이, 웹사이트도 체계적으로 파일들이 정리되어 있습니다.
4-2 기본적인 웹사이트 폴더 구조
`
mywebsite/
├── index.html (메인 홈페이지)
├── about.html (회사소개 페이지)
├── contact.html (연락처 페이지)
├── css/
│ └── style.css (디자인 파일)
├── js/
│ └── script.js (기능 파일)
├── images/
│ ├── logo.png (회사 로고)
│ └── banner.jpg (메인 배너)
└── documents/
└── company-profile.pdf (회사소개서)
`
4-3 각 파일과 폴더의 역할
주요 파일들:
- index.html: 웹사이트의 "현관문" 역할, 주소에 파일명을 안 써도 자동으로 표시
- about.html, contact.html: 각각 회사소개, 연락처 등 개별 페이지들
폴더별 역할:
- css 폴더: 모든 디자인 관련 파일들 (폰트, 색상, 레이아웃 등)
- js 폴더: JavaScript 파일들 (버튼 클릭, 폼 검증 등 동작 기능)
- images 폴더: 웹사이트에 사용되는 모든 이미지 파일들
- documents 폴더: PDF, 문서 등 다운로드 가능한 자료들
4-4 웹브라우저가 파일을 찾는 방식
웹브라우저는 주소창의 주소를 보고 서버에서 정확한 파일을 찾아옵니다:
mycompany.com/about.html입력 → 서버의about.html파일을 가져옴mycompany.com/css/style.css요청 → 서버의css/style.css파일을 가져옴mycompany.com/images/logo.png요청 → 서버의images/logo.png파일을 가져옴
파일이 없으면 "404 에러(페이지를 찾을 수 없다는 HTTP(하이퍼텍스트 전송 프로토콜) 상태 코드)" 메시지가 발생합니다.
4-5 파일 관리 실전 팁
파일명 작성 규칙:
- 영어 소문자 사용:
about.html✅About.html❌ - 공백 대신 하이픈:
company-info.html✅company info.html❌ - 특수문자 금지:
contact.html✅연락처.html❌
이미지 파일 최적화:
- WebP(웹피; 구글이 개발한 차세대 이미지 형식) 형식 사용하면 용량 50% 절약
- 파일명에 크기 표시:
logo-200x100.png,banner-1920x600.jpg - 웹용 이미지는 보통 100KB 이하로 유지
폴더 구조 실무 활용:
- assets/ 폴더: 모든 자원(이미지, 폰트, 아이콘 등)을 통합 관리
- src/ 폴더: 개발 중인 원본 소스코드 파일들 보관
- dist/ 폴더: 실제 웹사이트에 올릴 배포용 최종 파일들 저장
- backup/ 폴더: 이전 버전 파일들을 안전하게 보관
5. 정적 사이트 vs 동적 사이트 차이점
5-1 웹사이트의 두 가지 성격
모든 웹사이트는 크게 정적 사이트와 동적 사이트로 나뉩니다.
5-2 정적 사이트 (Static Website)
정의: 미리 만들어진 HTML 파일들을 그대로 보여주는 웹사이트
비유: 인쇄된 브로셔나 카탈로그 같은 것
특징: 모든 사용자에게 동일한 내용 표시
장점:
- 빠른 속도: 서버에서 파일만 전송하면 되므로 매우 빠름
- 안정성: 서버 에러가 거의 발생하지 않음
- 저렴한 비용: 간단한 호스팅으로 충분
- 보안성: 해킹 당할 요소가 적음
단점:
- 내용 변경 어려움: 수정하려면 HTML 파일을 직접 편집해야 함
- 상호작용 제한: 사용자별 다른 내용 제공 불가
- 기능 한계: 로그인, 댓글, 검색 등 복잡한 기능 구현 어려움
5-3 동적 사이트 (Dynamic Website)
정의: 사용자 요청에 따라 서버에서 실시간으로 웹페이지를 생성하는 웹사이트
비유: 주문에 따라 요리를 만들어주는 레스토랑
특징: 사용자별, 상황별로 다른 내용 표시
장점:
- 개인화 가능: 사용자별로 다른 콘텐츠 제공
- 실시간 업데이트: 데이터가 실시간으로 반영됨
- 상호작용: 댓글, 좋아요, 검색 등 다양한 기능
- 관리 편의성: 관리자 페이지에서 쉽게 내용 수정
단점:
- 느린 속도: 매번 서버에서 페이지를 생성해야 하므로 상대적으로 느림
- 복잡성: 개발과 유지보수가 복잡함
- 높은 비용: 강력한 서버와 데이터베이스 필요
- 보안 이슈: 해킹 위험이 상대적으로 높음
5-4 선택 기준
정적 사이트가 적합한 경우:
- 회사 소개, 제품 카탈로그 등 정보 제공이 주목적
- 자주 변경되지 않는 내용
- 빠른 속도와 안정성이 중요
- 예산이 제한적
동적 사이트가 필요한 경우:
- 사용자 등록, 로그인 기능 필요
- 개인별 맞춤 서비스 제공
- 실시간 데이터 처리 (주문, 결제, 소통 등)
- 플랫폼으로 확장할 계획
작성일: 2025-09-01 / 수정일: 2025-12-20 / 글자수: 약 5,600자 / 작성자: Claude / 프롬프터: 써니
3편 | CLI (명령줄)
웹사이트 개발의 세계에 들어가기 전에 필수 도구들을 준비해야 합니다. 가장 먼저 익혀야 할 것이 바로 CLI(명령줄 인터페이스)입니다. 처음에는 조금 낯설어 보이지만, 생각보다 전혀 어렵지 않습니다.
> 왜 배워야 할까요?
>
> SSALWorks에서는 Claude Code가 대부분의 명령어를 실행해줍니다. 그런데도 CLI를 배워야 하는 이유가 있습니다:
>
> 1. Claude Code 지시 이해: Claude Code가 "npm install을 실행하겠습니다"라고 할 때 무슨 뜻인지 알아야 합니다
> 2. 결과 확인: 명령어 실행 결과가 성공인지 실패인지 판단해야 합니다
> 3. 간단한 작업 직접 수행: 폴더 이동, 파일 확인 같은 기본 작업은 직접 하는 게 빠릅니다
> 4. 문제 해결: 오류가 발생했을 때 상황을 파악하고 Claude Code에게 정확히 설명할 수 있습니다
>
> 핵심: 명령어를 전부 외울 필요는 없습니다. "CLI가 뭔지", "어떻게 생겼는지" 정도만 알면 됩니다!
1. CLI(명령줄 인터페이스) 기본 개념
1-1. CLI가 무엇인지 이해하기
CLI(명령줄 인터페이스; Command Line Interface)는 많은 분들에게 생소한 개념일 수 있지만, 사실 엄청 단순한 개념입니다. 마우스 대신 키보드로 컴퓨터와 대화하는 방법이라고 생각하면 됩니다.
예를 들어보겠습니다. 평소에 "내 컴퓨터"를 열고 마우스로 클릭클릭 하면서 "문서" 폴더에 들어가는 방식이 GUI(그래픽 사용자 인터페이스; Graphical User Interface)입니다. 반대로 CLI(명령줄 인터페이스)는 검은 화면에 cd Documents라고 키보드로 입력해서 똑같은 작업을 하는 것입니다. 마치 컴퓨터와 텍스트로 대화하는 것 같습니다.
1-2. GUI와 CLI 비교
| 구분 | GUI (그래픽 인터페이스) | CLI (명령줄 인터페이스) |
|---|---|---|
| 조작 방식 | 마우스 클릭 | 키보드 입력 |
| 화면 | 아이콘, 창, 버튼 | 텍스트만 있는 검은 화면 |
| 장점 | 직관적, 초보자 친화적 | 빠름, 자동화 가능, 강력함 |
| 단점 | 느림, 반복 작업 불편 | 명령어 암기 필요 |
| 예시 | 탐색기에서 폴더 클릭 | `cd Documents` 입력 |
1-3. 개발자들이 CLI를 사용하는 이유
여기서 재미있는 사실입니다. 원래 컴퓨터는 CLI밖에 없었습니다. GUI는 나중에 사람들이 "이게 더 편하겠다" 하고 만들어진 편의 기능입니다. 그래서 지금도 많은 전문적인 개발 도구들이 CLI를 기반으로 만들어져 있습니다. 이런 강력한 도구들을 사용하려면 CLI를 알아야 한다는 것입니다.
CLI가 강력한 이유:
그리고 생각해보면, 마우스로 100개의 파일 이름을 하나씩 클릭해서 바꾸다 보면 눈이 아픈 경험 있으실 것입니다. 하지만 CLI에서는 단 한 줄의 명령어로 모든 파일을 순식간에 처리할 수 있습니다.
2. 윈도우 CLI의 종류와 차이점
Windows에는 3가지 CLI가 있습니다. 각각 다른 특징과 여는 방법을 가지고 있습니다.
2-1. CMD (Command Prompt) - 기본 명령줄
특징:
- Windows에 기본으로 제공
- 가볍고 빠른 실행
- 기본적인 파일 조작에 적합
- DOS 시절부터 이어져 온 전통적인 명령줄
여는 방법:
Windows 키 + R→cmd입력- 시작 메뉴에서 "명령 프롬프트" 검색
- 파일 탐색기 주소창에
cmd입력
주요 사용 상황:
간단한 파일 이동, 폴더 생성 등 기본 작업
2-2. PowerShell - 고급 명령줄
특징:
- 더 강력한 스크립팅 기능
- 객체 지향 명령어 체계
- Windows 시스템 관리에 특화
- CMD보다 현대적인 기능 제공
여는 방법:
Windows 키 + R→powershell입력- 시작 메뉴에서 "PowerShell" 검색
Windows 키 + X→ "Windows PowerShell" 선택- 파일 탐색기 주소창에
powershell입력
주요 사용 상황:
복잡한 시스템 관리, 자동화 스크립트 작성
2-3. Windows Terminal - 최신 터미널
특징:
- 2019년 출시된 현대적인 터미널
- 탭 기능으로 여러 세션 동시 관리
- 색상 테마와 폰트 커스터마이징 가능
- CMD, PowerShell, WSL을 모두 지원
- 복사/붙여넣기가 편리함
설치 방법:
- Microsoft Store에서 "Windows Terminal" 검색 후 설치
- Windows 11에는 기본 설치되어 있음
여는 방법:
Windows 키 + R→wt입력 (설치 후)- 시작 메뉴에서 "Terminal" 검색
Windows 키 + X→ "Terminal" 선택 (Windows 11)- 파일 탐색기에서 우클릭 → "Terminal에서 열기"
2-4. 개발자 권장 순서
| 순위 | 터미널 | 권장 이유 |
|---|---|---|
| 1위 | Windows Terminal | 가장 편리하고 현대적 |
| 2위 | PowerShell | 고급 기능 필요할 때 |
| 3위 | CMD | 간단한 작업용 |
3. 기본 명령어 익히기
3-1. 탐색 명령어
명령줄을 열면 현재 위치가 표시됩니다. 예를 들어 C:\Users\사용자명 같은 경로가 나타납니다.
| 명령어 | 설명 | 예시 |
|---|---|---|
| `cd 폴더명` | 해당 폴더로 이동 | `cd Desktop` |
| `cd ..` | 상위 폴더로 이동 | `cd ..` |
| `cd \` | 드라이브 최상위로 이동 | `cd \` |
| `cd /d D:` | 다른 드라이브로 이동 | `cd /d D:` |
| `dir` | 현재 폴더 내용 보기 | `dir` |
| `dir /w` | 가로로 간단히 보기 | `dir /w` |
실습해보기:
`
cd Desktop (바탕화면으로 이동)
dir (파일 목록 확인)
cd .. (다시 상위 폴더로)
`
3-2. 파일/폴더 관리 명령어
| 명령어 | 설명 | 예시 |
|---|---|---|
| `mkdir 폴더명` | 새 폴더 생성 | `mkdir 프로젝트` |
| `rmdir 폴더명` | 빈 폴더 삭제 | `rmdir 프로젝트` |
| `del 파일명` | 파일 삭제 | `del test.txt` |
| `copy 원본 대상` | 파일 복사 | `copy a.txt b.txt` |
| `move 원본 대상` | 파일 이동 | `move a.txt 폴더/` |
| `ren 원본 새이름` | 이름 변경 | `ren old.txt new.txt` |
3-3. 유용한 명령어
| 명령어 | 설명 |
|---|---|
| `cls` | 화면 지우기 |
| `exit` | 터미널 종료 |
| `echo 텍스트` | 텍스트 출력 |
| `type 파일명` | 파일 내용 보기 |
| `start .` | 현재 폴더를 탐색기로 열기 |
| `code .` | 현재 폴더를 VS Code로 열기 |
4. CLI 사용 팁
4-1. Tab 키 자동완성
긴 폴더 이름을 다 입력할 필요가 없습니다.
예시:
cd Des까지만 입력하고Tab키를 누르면- 자동으로
cd Desktop으로 완성됩니다
만약 Des로 시작하는 폴더가 여러 개라면 Tab을 여러 번 누르면서 원하는 폴더를 선택할 수 있습니다.
4-2. 명령어 히스토리
방금 입력했던 명령어를 다시 사용하고 싶다면:
| 키 | 기능 |
|---|---|
| `↑` (위 화살표) | 이전 명령어 불러오기 |
| `↓` (아래 화살표) | 다음 명령어로 이동 |
| `F7` | 명령어 히스토리 목록 보기 (CMD) |
이 기능은 긴 명령어를 반복해서 사용할 때 매우 유용합니다.
4-3. 탐색기와 CLI 연동하기
특정 폴더에서 CLI를 열고 싶다면:
| 방법 | 설명 |
|---|---|
| 주소창에 `cmd` 입력 | CMD가 해당 폴더에서 열림 |
| 주소창에 `powershell` 입력 | PowerShell이 해당 폴더에서 열림 |
| 주소창에 `wt` 입력 | Windows Terminal이 열림 |
| 폴더에서 우클릭 | "Terminal에서 열기" (Windows 11) |
| Shift + 우클릭 | "여기서 PowerShell 창 열기" |
4-4. 복사/붙여넣기
Windows Terminal / PowerShell:
- 복사:
Ctrl + C또는 드래그 후Enter - 붙여넣기:
Ctrl + V또는 우클릭
CMD:
- 복사: 드래그로 선택 후
Enter - 붙여넣기: 우클릭
5. 경로(Path) 이해하기
5-1. 절대 경로 vs 상대 경로
| 구분 | 설명 | 예시 |
|---|---|---|
| **절대 경로** | 드라이브부터 시작하는 전체 경로 | `C:\Users\홍길동\Desktop\project` |
| **상대 경로** | 현재 위치 기준 경로 | `./project` 또는 `../Documents` |
상대 경로 표기:
.: 현재 폴더..: 상위 폴더./하위폴더: 현재 폴더 안의 하위폴더
5-2. 경로 예시
현재 위치가 C:\Users\홍길동일 때:
| 명령어 | 이동 결과 |
|---|---|
| `cd Desktop` | `C:\Users\홍길동\Desktop` |
| `cd ./Desktop` | `C:\Users\홍길동\Desktop` (같음) |
| `cd ..` | `C:\Users` |
| `cd ../공용` | `C:\Users\공용` |
| `cd C:\Windows` | `C:\Windows` (절대 경로) |
6. 개발에서 CLI 활용
6-1. 웹 개발에서 자주 사용하는 CLI 명령어
웹 개발을 하다 보면 다음과 같은 명령어들을 자주 사용하게 됩니다:
| 명령어 | 용도 |
|---|---|
| `npm install` | 패키지 설치 |
| `npm start` | 개발 서버 실행 |
| `npm run build` | 프로젝트 빌드 |
| `git status` | Git 상태 확인 |
| `git add .` | 변경사항 스테이징 |
| `git commit -m "메시지"` | 커밋 생성 |
| `code .` | VS Code로 폴더 열기 |
이 명령어들은 뒤에서 자세히 배우게 됩니다. 지금은 CLI에서 이런 명령어들을 실행한다는 것만 알아두세요.
6-2. 프로젝트 시작 예시
`
mkdir my-project (프로젝트 폴더 생성)
cd my-project (폴더로 이동)
code . (VS Code로 열기)
`
이 세 줄만으로 새 프로젝트를 시작할 수 있습니다!
7. Mac/Linux 사용자를 위한 참고
Mac과 Linux는 Windows와 명령어가 약간 다릅니다.
| 작업 | Windows | Mac/Linux |
|---|---|---|
| 폴더 내용 보기 | `dir` | `ls` |
| 화면 지우기 | `cls` | `clear` |
| 폴더 삭제 | `rmdir` | `rm -r` |
| 파일 내용 보기 | `type` | `cat` |
기본적인 cd, mkdir, cp, mv 등은 동일하게 사용됩니다.
정리
CLI는 처음에는 낯설지만, 익숙해지면 마우스보다 훨씬 빠르고 강력한 도구가 됩니다.
핵심 포인트:
다음 편에서는 코드를 작성할 도구인 코드 에디터와 IDE를 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 5,200자 / 작성자: Claude / 프롬프터: 써니
4편 | 코드 에디터와 IDE
3편에서 CLI를 익혔다면, 이제 실제로 코드를 작성할 도구를 선택할 차례입니다. 개발자에게 코드 에디터는 일상의 파트너와 같습니다. 이번 편에서는 메모장부터 VS Code, Cursor까지 다양한 코드 에디터의 특징을 비교하고, 실제로 웹사이트 개발에 최적화된 환경을 구축하는 방법을 살펴봅니다.
1. 개발 도구의 진화와 선택
1-1. 메모장에서 전문 도구까지
개발 도구는 메모장 → 워드 → 전문 출판 프로그램처럼 단계적으로 진화했습니다. 처음 프로그래밍을 시작하던 시절에는 윈도우 메모장 같은 단순한 텍스트 에디터에 코드를 작성했습니다. 하지만 이제는 훨씬 더 똑똑하고 편리한 도구들이 개발되었습니다.
1단계: 텍스트 에디터
가장 기본적인 도구로 메모장이나 Notepad++ 같은 프로그램이 여기에 속합니다. 이들은 단순히 텍스트를 편집하는 기능만 제공합니다. 코드를 작성할 수는 있지만 별다른 도움을 주지 않습니다. 마치 연필과 종이로 코드를 쓰는 것과 비슷한 수준입니다.
2단계: 코드 에디터
VS Code, Sublime Text, Cursor 같은 현대적인 코드 에디터는 프로그래밍을 위해 특별히 설계되었습니다. 코드의 문법을 색깔로 구분해서 보여주는 문법 강조(Syntax Highlighting) 기능이 있습니다. 타이핑하다가 Tab키만 누르면 나머지를 자동으로 완성해주는 자동완성(Auto Complete) 기능도 제공합니다. 필요한 기능을 확장 프로그램으로 추가할 수 있습니다. 웹사이트 개발자의 90% 이상이 이 단계의 도구를 사용합니다.
3단계: IDE (통합개발환경)
IntelliJ IDEA나 Visual Studio 같은 IDE(Integrated Development Environment, 통합개발환경)는 훨씬 더 강력한 도구입니다. 코드 에디터의 모든 기능에 더해 컴파일(코드를 실행 파일로 변환), 디버깅(오류 찾기), 프로젝트 관리 등 개발에 필요한 모든 기능을 하나로 통합했습니다. 강력하지만 무겁고 복잡해서 주로 대규모 프로젝트나 특정 언어 전문 개발에 사용됩니다.
1-2. 코드 에디터를 선택하는 이유
웹사이트 개발을 시작하는 단계에서 IDE 대신 코드 에디터를 선택하는 데는 분명한 이유가 있습니다.
코드 에디터의 장점:
결론: 이러한 이유로 웹사이트 개발 입문 단계에서는 VS Code 같은 코드 에디터가 최적의 선택입니다. 나중에 특정 언어나 프레임워크에 집중하게 되면 그때 IDE를 고려해도 늦지 않습니다.
2. VS Code 완벽 가이드
2-1. VS Code가 세계 1위 에디터가 된 이유
VS Code(Visual Studio Code)는 2015년 Microsoft에서 출시했습니다. 이후 급속도로 성장하여 현재 전 세계 개발자의 70% 이상이 사용하는 가장 인기 있는 코드 에디터가 되었습니다.
주요 선택 이유:
| 특징 | 설명 |
|---|---|
| 무료 오픈소스 | 개인이든 기업이든 완전 무료 |
| 압도적인 점유율 | Stack Overflow 설문 매년 1위 |
| 풍부한 확장 | 3만 개 이상의 확장 프로그램 |
| 웹사이트 개발 최적화 | Emmet, IntelliSense 기본 지원 |
| AI 도구 연동 | GitHub Copilot, Claude 등 지원 |
2-2. 설치부터 필수 설정까지
다운로드 과정:
공식 웹사이트 https://code.visualstudio.com에 접속합니다. 메인 페이지에 큰 "Download for Windows" 버튼을 클릭하면 자동으로 사용 중인 운영체제에 맞는 버전이 다운로드됩니다.
설치 시 중요한 옵션들 (반드시 체크):
설치 과정에서 "Select Additional Tasks" 화면이 나타납니다. 이때 다음 옵션들을 반드시 체크해야 합니다:
- ☑ Add "Open with Code" action to Windows Explorer file context menu: 파일을 우클릭했을 때 "Code로 열기" 메뉴가 추가됩니다.
- ☑ Add "Open with Code" action to Windows Explorer directory context menu: 폴더를 우클릭했을 때도 "Code로 열기" 메뉴가 나타납니다.
- ☑ Register Code as an editor for supported file types: .html, .css, .js 같은 코드 파일을 더블클릭하면 자동으로 VS Code에서 열립니다.
- ☑ Add to PATH: 명령 프롬프트에서
code명령어로 VS Code를 실행할 수 있게 됩니다.
한국어 설정:
Ctrl + Shift + X를 눌러 확장 프로그램 패널을 엽니다2-3. 기본 사용법과 필수 확장
화면 구성 이해하기
VS Code를 처음 열면 크게 세 영역으로 나뉘어져 있습니다:
- 왼쪽 사이드바: 파일 탐색기, 검색, Git 등의 도구
- 중앙: 코드를 편집하는 공간
- 하단: 터미널을 열 수 있는 공간
필수 확장 프로그램
| 확장 프로그램 | 기능 |
|---|---|
| **Prettier** | 코드를 자동으로 보기 좋게 정렬 |
| **Live Server** | HTML 저장 시 브라우저 자동 새로고침 |
| **Auto Rename Tag** | HTML 태그 수정 시 짝 태그 자동 수정 |
Prettier - Code formatter
코드를 자동으로 보기 좋게 정렬해주는 도구입니다. 들여쓰기가 뒤죽박죽이거나 줄바꿈이 일관성 없어도, 저장할 때마다 자동으로 깔끔하게 정리됩니다.
Live Server
HTML 파일을 저장하면 브라우저가 자동으로 새로고침되어 변경사항을 즉시 확인할 수 있습니다. 파일을 우클릭하고 "Open with Live Server"를 선택하면 로컬 서버가 실행됩니다.
Auto Rename Tag
HTML 태그를 수정할 때 짝이 되는 태그를 자동으로 함께 수정해줍니다. 도 자동으로 으로 바꾸면 닫는 태그
2-4. VS Code로 문서 작성하기
왜 VS Code로 문서를 작성할까?
| Word의 한계 | VS Code의 장점 |
|---|---|
| 파일 개별 관리로 일관성 유지 어려움 | 여러 문서를 하나의 프로젝트로 관리 |
| 여러 파일 간 이동 불편 | 전체 문서에서 키워드 검색 가능 |
| 검색/치환 기능 제한적 | Git으로 자동 버전 관리 |
마크다운으로 문서 작성하기
마크다운은 VS Code에서 지원하는 문서 작성 방식으로 .md 확장자로 저장하며, 간단한 기호로 문서를 구조화할 수 있습니다.
`markdown
프로젝트 계획서
1단계: 기획
- 아이디어 정리
- 핵심 기능 정의
2단계: 개발
- 코딩 시작
- 테스트 진행
`
2-5. VS Code에서 AI 도구 활용하기
VS Code에서 AI를 사용하면 코드 작성 효율이 대폭 향상됩니다. 에디터를 벗어나지 않고 AI 도움을 받을 수 있고, 코드 작성 중 즉시 질문과 해결이 가능합니다.
| AI 도구 | 특징 |
|---|---|
| **Claude Code (터미널)** | 파일 편집과 프로젝트 분석 등 실제 작업 수행 |
| **Claude Chat (패널)** | 빠른 질문과 답변에 적합 |
| **GitHub Copilot** | 코드 자동완성 특화 |
에러가 발생하면 Chat으로 빠른 질문을 하고, 복잡한 기능 구현이 필요하면 Claude Code로 실제 작업을 수행하는 방식으로 활용할 수 있습니다.
2-6. 실제 작업 흐름
VS Code로 간단한 웹페이지 만들기
1단계: 프로젝트 폴더 준비
- 바탕화면에 "내첫웹사이트" 폴더 생성
- VS Code에서 "폴더 열기"로 해당 폴더 선택
- 우클릭 → "새 파일" →
index.html생성
2단계: 기본 코드 작성
`html
안녕하세요
이것은 VS Code로 만든 첫 웹페이지입니다.
`
3단계: 브라우저에서 확인
- Live Server 확장 설치
- 파일 우클릭 → "Open with Live Server"
- 코드 수정 시 자동 반영
3. Cursor - AI 특화 코드 에디터
3-1. Cursor를 고려하는 이유
VS Code로 기본기를 다진 후, 더 강력한 AI 기능이 필요하다면 Cursor를 고려해볼 수 있습니다. Cursor는 2023년에 등장한 새로운 코드 에디터로, AI와의 협업을 중심으로 설계되었습니다.
Cursor의 특징:
Cursor는 VS Code를 포크(fork)해서 만든 완전 독립적인 에디터입니다. 포크란 기존 소프트웨어의 소스코드를 복사해서 새로운 프로젝트로 개발하는 것을 말합니다. 따라서 VS Code의 모든 장점을 그대로 가지면서도 AI 기능에 특화된 추가 기능들을 제공합니다.
3-2. Cursor 핵심 기능 3가지
1. Tab 자동완성
코드를 작성하다가 주석으로 "// 사용자 정보를 데이터베이스에 저장하는 함수"라고 쓰고 Tab 키를 누르면, AI가 해당 기능을 구현한 전체 함수 코드를 자동으로 생성합니다.
2. Ctrl+K 수정
이미 작성된 코드를 선택한 후 Ctrl+K를 누르고 "이 코드를 더 효율적으로 만들어줘"같은 자연어 요청을 입력하면, AI가 코드를 자동으로 수정해줍니다.
3. AI 채팅
오른쪽 패널에 있는 채팅창에서 코드에 대한 질문을 할 수 있습니다. 현재 열려 있는 파일의 컨텍스트를 이해하고 있어서 더 정확한 답변을 제공합니다.
3-3. VS Code vs Cursor 언제 사용할까?
| 상황 | 권장 도구 |
|---|---|
| 안정적인 개발 환경 필요 | VS Code |
| 팀 협업 표준 도구 | VS Code |
| 기본적인 AI 도움 | VS Code |
| AI 자동완성 적극 활용 | Cursor |
| 실험적 코드/프로토타이핑 | Cursor |
| 새로운 기술 학습 | Cursor |
많은 개발자들이 두 도구를 병행해서 사용합니다. 메인 프로젝트는 VS Code로, 실험이나 학습은 Cursor로 진행하는 식입니다.
4. 기타 에디터 및 IDE 소개
4-1. 기타 에디터
| 에디터 | 특징 | 적합한 용도 |
|---|---|---|
| **Sublime Text** | 매우 빠른 속도, 유료 | 가벼운 편집 작업 |
| **Notepad++** | Windows 전용, 무료, 가벼움 | 간단한 텍스트 편집 |
| **Vim** | 터미널 기반, 높은 학습 곡선 | 서버 환경 파일 편집 |
| **Windsurf** | AI 특화, Cursor와 유사 | AI 활용 개발 |
4-2. 기타 IDE
| IDE | 특징 | 적합한 용도 |
|---|---|---|
| **IntelliJ IDEA** | Java 최적화, 유료 | 대규모 Java 프로젝트 |
| **Visual Studio** | .NET 전용 | Windows 앱/게임 개발 |
| **Eclipse** | 오픈소스, 무료 | Java 개발 (점유율 감소 중) |
정리
코드 에디터는 개발자의 생산성을 결정하는 핵심 도구입니다.
핵심 포인트:
다음 편에서는 코드의 버전을 관리하는 도구인 Git과 GitHub를 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 5,500자 / 작성자: Claude / 프롬프터: 써니
5편 | Git과 GitHub
이번 편에서는 코드를 체계적으로 관리하는 방법을 살펴봅니다. 모든 개발자가 반드시 알아야 할 버전 관리 시스템 Git과 협업 플랫폼 GitHub를 배웁니다. 코드의 변경 이력을 체계적으로 관리하는 방법부터 팀 협업을 위한 브랜치 전략, Pull Request를 통한 코드 리뷰까지 현대 개발 워크플로우의 핵심을 알아봅니다.
1. Git 기초와 핵심 개념
1-1. Git이란 무엇인가
Git을 코드의 타임머신이라고 생각하면 됩니다. 프로젝트 파일들의 모든 변경 사항을 카메라로 찍듯 기록하는 버전 관리 시스템입니다.
개발을 하다 보면 자주 겪는 상황이 있습니다:
> "어제까지 완벽하게 작동하던 코드가 오늘 갑자기 안 됩니다!"
하지만 Git이 있으면 전혀 문제없습니다! 마치 게임에서 세이브 파일로 되돌아가는 것처럼, 언제든지 제대로 작동하던 이전 버전으로 되돌릴 수 있습니다.
Git을 쓰지 않으면:
project_최종.zipproject_진짜최종.zipproject_진짜진짜최종.zip
이런 방식으로 백업하게 됩니다. Git을 사용하면 이런 번거로움 없이 체계적으로 버전을 관리할 수 있습니다.
Git은 2005년 리누스 토르발스(Linux 창시자)가 만든 분산형 버전 관리 시스템입니다. 여러 개발자가 동시에 작업할 수 있고, 인터넷 연결 없이도 버전 관리가 가능하며, 데이터 손실 위험이 매우 낮습니다.
1-2. Git의 핵심 개념
| 용어 | 설명 |
|---|---|
| **저장소(Repository)** | Git으로 관리되는 프로젝트 폴더 |
| **커밋(Commit)** | 프로젝트의 스냅샷을 찍는 것 |
| **브랜치(Branch)** | 독립적인 작업 공간 |
| **클론(Clone)** | 원격 저장소를 내 컴퓨터로 복사 |
저장소(Repository)
프로젝트 폴더 안에 .git이라는 숨겨진 폴더가 생기면서 버전 관리가 시작됩니다. 이 폴더에는 프로젝트의 모든 변경 이력과 메타데이터가 저장됩니다.
커밋(Commit)
게임에서 중요한 순간에 세이브하는 것과 같습니다. "로그인 기능 추가", "버그 수정" 같은 의미 있는 메시지와 함께 변경사항을 기록합니다. 각 커밋은 전 세계에서 단 하나뿐인 고유한 ID(해시값)를 가집니다.
브랜치(Branch)
독립적인 작업 공간입니다. 예를 들어 온라인 쇼핑몰에서 결제 기능을 개선해야 하는데, 지금 사이트는 정상 운영 중이어야 합니다. 이럴 때 메인 브랜치는 그대로 두고 feature/payment-improvement 같은 새 브랜치에서 개선 작업을 합니다. 테스트가 완료되면 메인에 합칩니다.
1-3. Git의 3단계 관리
Git은 파일을 세 단계로 관리합니다:
`
작업 디렉토리 → 스테이징 영역 → Git 디렉토리
(편집) (커밋 준비) (버전 저장)
`
2. Git 설치와 초기 설정
2-1. 설치 과정
Windows:
- https://git-scm.com 에서 Git 다운로드
- 설치 과정에서는 기본 설정 그대로 사용 권장
Linux(Ubuntu/Debian): 터미널에서 sudo apt-get install git 명령어로 설치합니다.
설치 확인: git --version 명령어로 버전이 표시되면 설치 완료입니다.
2-2. 초기 설정하기
설치 후에는 사용자 이름과 이메일을 등록해야 합니다. 이 정보는 커밋할 때 "누가 작성했는지" 기록됩니다. Claude Code가 이 설정을 도와줍니다.
2-3. .gitignore 파일 설정
.gitignore 파일은 Git이 추적하지 않을 파일을 지정합니다.
| 제외 대상 | 이유 |
|---|---|
| `node_modules/` | 용량이 크고, 언제든 다시 설치 가능 |
| `.env` | 비밀번호 등 민감 정보 포함 |
| `*.log` | 임시 로그 파일 |
Claude Code가 프로젝트 시작 시 자동으로 생성해줍니다.
2-4. VS Code에서 Git 사용하기
VS Code는 Git을 기본으로 지원합니다. 왼쪽 사이드바에서 소스 제어 아이콘을 클릭하면 변경된 파일을 보고, 스테이징하고, 커밋할 수 있습니다. 터미널을 사용하지 않고도 Git을 사용할 수 있어 초보자에게 편리합니다.
GitHub Desktop은 더욱 시각적인 Git 관리 도구입니다. 복잡한 명령어 없이 클릭만으로 커밋, 푸시, 브랜치 관리를 할 수 있습니다.
3. 필수 Git 명령어
3-1. 기본 명령어
| 명령어 | 설명 | 예시 |
|---|---|---|
| `git init` | 새 저장소 생성 | `git init` |
| `git status` | 현재 상태 확인 | `git status` |
| `git add` | 스테이징 영역에 추가 | `git add .` |
| `git commit` | 커밋 생성 | `git commit -m "메시지"` |
| `git log` | 커밋 이력 확인 | `git log --oneline` |
| `git diff` | 변경사항 확인 | `git diff` |
git init
새 프로젝트를 Git으로 관리하기 시작할 때 사용합니다. 프로젝트 폴더에서 이 명령어를 실행하면 .git 폴더가 생성됩니다.
git status
현재 Git 저장소의 상태를 확인합니다. 어떤 파일이 변경되었는지, 어떤 파일이 커밋 준비가 되었는지 알려줍니다. 가장 자주 쓰는 명령어입니다.
git add
변경된 파일을 커밋 준비 상태로 옮깁니다:
git add .- 모든 변경사항 추가git add index.html- 특정 파일만 추가
git commit
스테이징 영역의 파일들을 실제로 Git 저장소에 저장합니다. -m 옵션 뒤에 "로그인 기능 추가"처럼 변경 내용을 설명하는 메시지를 작성합니다.
4. GitHub와 원격 저장소 관리
4-1. GitHub란 무엇인가
GitHub은 Git 저장소를 온라인에서 호스팅해주는 서비스입니다. 내 컴퓨터에 있는 Git 저장소를 GitHub에 업로드하면:
- 어디서든 접근 가능
- 다른 사람들과 코드 공유
- 이슈 관리, 코드 리뷰, 프로젝트 관리 기능
전 세계 개발자들이 오픈소스 프로젝트를 공유하는 곳이기도 합니다.
4-2. 원격 저장소 명령어
| 명령어 | 설명 |
|---|---|
| `git remote add origin [URL]` | 원격 저장소 연결 |
| `git push` | 로컬 → GitHub 업로드 |
| `git pull` | GitHub → 로컬 다운로드 |
| `git clone [URL]` | 저장소 전체 복사 |
git remote - 로컬 저장소를 GitHub의 원격 저장소와 연결합니다.
git push - 로컬의 커밋들을 GitHub으로 업로드합니다. "밀어 올린다"고 생각하면 됩니다.
git pull - GitHub의 최신 내용을 로컬로 다운로드합니다. "당겨 온다"고 생각하면 됩니다. 다른 사람이 코드를 수정했거나, 다른 컴퓨터에서 작업한 내용이 있을 때 사용합니다.
git clone - GitHub에 있는 저장소를 통째로 내 컴퓨터에 복사해옵니다.
> 참고: 이 명령어들은 Claude Code가 대신 실행해줍니다. 명령어를 외울 필요 없이, "GitHub에 올려줘"라고 말하면 됩니다.
5. 브랜치 활용과 협업 전략
5-1. 브랜치 기본 명령어
| 명령어 | 설명 |
|---|---|
| `git branch 브랜치명` | 새 브랜치 생성 |
| `git switch 브랜치명` | 브랜치 전환 |
| `git switch -c 브랜치명` | 생성과 동시에 전환 |
| `git merge 브랜치명` | 브랜치 병합 |
> 참고: git switch는 2019년에 추가된 최신 명령어입니다. 구버전 자료에서는 git checkout을 사용하는데, 같은 기능입니다. Claude Code는 최신 명령어를 사용합니다.
브랜치 활용 흐름:
feature-login)5-2. 브랜치 이름 규칙
| 접두사 | 용도 | 예시 |
|---|---|---|
| `feature/` | 새로운 기능 | `feature/user-login` |
| `bugfix/` | 버그 수정 | `bugfix/payment-error` |
| `hotfix/` | 긴급 수정 | `hotfix/security-patch` |
5-3. Pull Request와 코드 리뷰
Pull Request(PR)는 GitHub에서 제공하는 협업 도구입니다. "내가 작성한 코드를 메인 프로젝트에 합쳐달라"고 요청하는 기능입니다.
협업 과정:
코드 리뷰는 버그를 미리 찾고, 코드 품질을 높이며, 팀원들이 서로 학습할 수 있는 중요한 과정입니다.
6. GitHub 고급 기능
6-1. 오픈소스와 Fork
Fork는 다른 사람의 저장소를 내 계정으로 복사하는 기능입니다. 오픈소스 프로젝트에 기여할 때 사용합니다:
6-2. Issues와 프로젝트 관리
| 기능 | 설명 |
|---|---|
| **Issues** | 버그 리포트, 기능 요청, 질문 관리 |
| **Milestone** | 여러 이슈를 버전별로 그룹화 |
| **Projects** | 칸반 보드 스타일 프로젝트 관리 |
| **Wiki** | 프로젝트 문서 작성 공간 |
README.md 파일은 프로젝트의 첫인상을 결정하는 중요한 문서입니다. 프로젝트 소개, 설치 방법, 사용법, 기여 방법 등을 명확하게 작성해야 합니다.
7. Git 문제 해결
7-1. 충돌 해결
두 명이 같은 파일의 같은 부분을 수정했을 때 충돌(Conflict)이 발생합니다.
충돌 해결 단계:
git pull 실행 시 "충돌 발생!" 메시지 확인<<<<<<<, =======, >>>>>>> 표시가 보임git add로 해결 완료 알림git commit으로 충돌 해결 완료VS Code에서는 '현재 변경사항 수락', '수신 변경사항 수락', '모두 수락' 버튼으로 쉽게 해결할 수 있습니다.
7-2. 자주 사용하는 되돌리기 명령어
| 상황 | 명령어 |
|---|---|
| 커밋 메시지 수정 | `git commit --amend -m "새 메시지"` |
| 파일 되돌리기 | `git checkout -- 파일명` |
| 마지막 커밋 취소 | `git reset --soft HEAD~1` |
7-3. 고급 Git 기법
| 명령어 | 설명 |
|---|---|
| `git stash` | 작업 중인 변경사항 임시 저장 |
| `git stash pop` | 임시 저장한 변경사항 복원 |
| `git rebase` | 커밋 히스토리 정리 |
| `git cherry-pick` | 특정 커밋만 가져오기 |
8. 팀 협업 모범 사례
8-1. 커밋 메시지 작성법
명확하고 일관된 메시지로 미래의 나와 동료들을 도와줍니다:
| 접두사 | 의미 | 예시 |
|---|---|---|
| `feat:` | 새 기능 | "feat: 사용자 로그인 기능 추가" |
| `fix:` | 버그 수정 | "fix: 결제 오류 수정" |
| `docs:` | 문서 변경 | "docs: README 업데이트" |
| `style:` | 코드 정리 | "style: 코드 포맷팅" |
> Claude Code가 커밋 메시지를 자동으로 작성해줍니다. 변경 내용을 분석해서 적절한 메시지를 제안합니다.
8-2. 협업 핵심 규칙
정리
Git과 GitHub는 현대 개발의 필수 도구입니다.
핵심 포인트:
다음 편에서는 분류체계를 알아봅니다. 개발 영역과 기술 스택을 체계적으로 이해하는 방법을 배웁니다.
작성일: 2025-12-21 / 글자수: 약 5,200자 / 작성자: Claude / 프롬프터: 써니
6편 | 분류체계 (1) - 개발 영역과 기술 스택
웹사이트 개발을 배우다 보면 수많은 기술과 도구들이 쏟아져 나옵니다. 이번 편에서는 이 복잡한 기술들을 체계적으로 분류하는 방법을 알아봅니다. 분류체계를 이해하면 새로운 기술을 만났을 때 "아, 이건 이 카테고리구나"하고 바로 파악할 수 있습니다.
1. 개발 영역 7가지
웹사이트 개발은 크게 7개의 영역으로 나눌 수 있습니다.
7개 영역 한눈에 보기
| # | 영역 | 역할 | 레스토랑 비유 |
|---|---|---|---|
| 1 | **Frontend** | 사용자가 보는 화면 | 홀, 인테리어 |
| 2 | **Backend Infra** | 서버 환경 구축 | 주방 시설 |
| 3 | **Backend API** | 데이터 처리 로직 | 요리사의 레시피 |
| 4 | **Database** | 데이터 저장/관리 | 식재료 창고 |
| 5 | **Security** | 인증/인가/보호 | 출입 관리 |
| 6 | **Testing** | 품질 검증 | 품질 검사관 |
| 7 | **DevOps** | 배포/운영 자동화 | 배송 시스템 |
1. Frontend (프론트엔드)
정의: 사용자가 직접 보고 클릭하는 화면
담당 업무:
- 버튼, 메뉴, 이미지, 텍스트 배치
- 색상, 폰트, 애니메이션 적용
- 스마트폰/태블릿/PC 화면 대응 (반응형)
- 사용자 입력 처리 (클릭, 스크롤, 타이핑)
SSALWorks 적용 기술:
- HTML, CSS, JavaScript, TypeScript
- React (UI 라이브러리)
- Next.js (프레임워크)
- Tailwind CSS (스타일링)
2. Backend Infra (백엔드 기반)
정의: 서버가 돌아가는 기반 환경
담당 업무:
- 서버 실행 환경 구성
- 실시간 통신 (채팅, 알림)
- 파일 업로드/다운로드 처리
- 이메일 발송
SSALWorks 적용 기술:
- Node.js (서버 실행 환경)
- Socket.io (실시간 통신)
- Resend (이메일 발송 서비스)
3. Backend API (백엔드 API)
정의: 프론트엔드와 데이터베이스를 연결하는 다리
담당 업무:
- 비즈니스 로직 처리 (회원가입, 로그인, 결제)
- 데이터 검증 (입력값이 올바른지 확인)
- 프론트엔드 요청 처리 후 응답 반환
SSALWorks 적용 기술:
- Next.js API Routes (API 엔드포인트)
- Zod (데이터 검증 라이브러리)
- Edge Runtime (빠른 응답)
4. Database (데이터베이스)
정의: 모든 데이터를 저장하고 관리하는 창고
담당 업무:
- 회원 정보 저장 (이메일, 비밀번호)
- 게시글, 댓글, 주문 내역 저장
- 데이터 조회, 수정, 삭제
- 데이터 관계 설정 (회원 ↔ 주문)
SSALWorks 적용 기술:
- Supabase (BaaS - Backend as a Service)
- PostgreSQL (관계형 데이터베이스)
- SQL (데이터베이스 질의 언어)
5. Security (보안)
정의: 누가 접근하고 무엇을 할 수 있는지 관리
담당 업무:
- 인증(Authentication): 누구인지 확인 (로그인)
- 인가(Authorization): 무엇을 할 수 있는지 확인 (권한)
- 비밀번호 암호화
- 세션/토큰 관리
SSALWorks 적용 기술:
- Supabase Auth (인증 시스템)
- Google OAuth, Kakao OAuth (소셜 로그인)
- JWT (JSON Web Token)
6. Testing (테스트)
정의: 코드가 제대로 작동하는지 검증
담당 업무:
- 단위 테스트 (함수 하나씩 검증)
- 통합 테스트 (여러 기능 연결 검증)
- E2E 테스트 (실제 사용자 시나리오 검증)
- 버그 사전 발견
SSALWorks 적용 기술:
- Jest (단위 테스트)
- Playwright (E2E 테스트, 브라우저 자동화)
7. DevOps (데브옵스)
정의: 개발(Dev)과 운영(Ops)을 연결하는 자동화
담당 업무:
- 코드를 서버에 배포
- 자동 빌드/배포 파이프라인
- 도메인 연결
- 서버 모니터링
SSALWorks 적용 기술:
- Vercel (PaaS - Platform as a Service)
- GitHub Actions (CI/CD 자동화)
- Git (버전 관리)
2. 기술 스택 7가지
각 개발 영역 안에서 사용하는 기술들은 7가지 유형으로 분류됩니다.
7가지 유형 한눈에 보기
| # | 유형 | 설명 | 비유 |
|---|---|---|---|
| 1 | **Language** | 코드 작성 언어 | 한국어, 영어 |
| 2 | **Runtime** | 코드 실행 환경 | 무대 |
| 3 | **Package Manager** | 라이브러리 설치/관리 | 택배 시스템 |
| 4 | **Tools** | 개발 보조 도구 | 연장통 |
| 5 | **Library** | 기능별 코드 모음 | 레고 블록 |
| 6 | **Framework** | 전체 구조 제공 | 건물 뼈대 |
| 7 | **External Service** | 외부 서비스 | 외주 업체 |
1. Language (언어)
정의: 컴퓨터에게 명령을 내리는 언어
특징:
- 정해진 문법과 규칙이 있음
- 사람이 읽을 수 있는 코드 작성
- 컴파일러/인터프리터가 기계어로 변환
주요 언어:
| 언어 | 용도 |
|---|---|
| JavaScript | 웹 동작, 서버 |
| TypeScript | JavaScript + 타입 안전성 |
| HTML | 웹페이지 구조 |
| CSS | 웹페이지 스타일 |
| SQL | 데이터베이스 질의 |
2. Runtime (실행 환경)
정의: 작성한 코드가 실제로 돌아가는 곳
주요 실행 환경:
| 환경 | 설명 |
|---|---|
| **Browser** | 사용자 컴퓨터의 브라우저에서 실행 |
| **Node.js** | 서버 컴퓨터에서 JavaScript 실행 |
| **Edge Runtime** | CDN 가장자리에서 빠르게 실행 |
3. Package Manager (패키지 관리자)
정의: 다른 사람이 만든 코드를 쉽게 가져다 쓰게 해줌
주요 패키지 관리자:
| 도구 | 명령어 예시 |
|---|---|
| **npm** | `npm install react` |
| **yarn** | `yarn add react` |
하는 일:
- 라이브러리 설치/삭제
- 버전 관리
- 의존성(다른 라이브러리와의 관계) 관리
4. Tools (도구)
정의: 개발 생산성을 높여주는 보조 도구
주요 도구:
| 도구 | 역할 |
|---|---|
| **ESLint** | 코드 문법 오류 검사 |
| **Prettier** | 코드 자동 정렬 |
| **Git** | 버전 관리 |
| **Vite** | 빠른 개발 서버 |
| **DevTools** | 브라우저 디버깅 |
5. Library (라이브러리)
정의: 특정 기능을 수행하는 코드 모음
특징:
- 필요한 기능만 골라서 사용
- 개발자가 주도권을 가짐 (내가 라이브러리를 호출)
주요 라이브러리:
| 라이브러리 | 기능 |
|---|---|
| **React** | UI 컴포넌트 구성 |
| **Zod** | 데이터 검증 |
| **Jest** | 테스트 |
| **Zustand** | 상태 관리 |
6. Framework (프레임워크)
정의: 전체적인 구조와 규칙을 제공하는 틀
특징:
- 정해진 구조를 따라야 함
- 프레임워크가 주도권을 가짐 (프레임워크가 내 코드를 호출)
주요 프레임워크:
| 프레임워크 | 용도 |
|---|---|
| **Next.js** | React 기반 풀스택 |
| **Tailwind CSS** | 유틸리티 기반 CSS |
라이브러리 vs 프레임워크:
- 라이브러리: 내가 필요할 때 호출 (도구)
- 프레임워크: 프레임워크가 내 코드를 호출 (구조)
7. External Service (외부 서비스, XaaS)
정의: 외부 회사가 제공하는 완성된 기능
XaaS 종류:
| 유형 | 의미 | 예시 |
|---|---|---|
| **BaaS** | Backend as a Service | **Supabase** |
| **PaaS** | Platform as a Service | **Vercel** |
| **SaaS** | Software as a Service | **Resend** |
장점:
- 직접 구축할 필요 없음
- 유지보수 부담 감소
- 빠른 개발 가능
정리
| 분류 | 개수 | 핵심 |
|---|---|---|
| 개발 영역 | 7개 | 무엇을 만드는가 |
| 기술 스택 | 7개 | 무엇으로 만드는가 |
다음 편에서는 이 두 분류를 조합한 7×7 매트릭스와 코드 구성 단계, 아키텍처를 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 4,900자 / 작성자: Claude / 프롬프터: 써니
7편 | 분류체계 (2) - 매트릭스와 아키텍처
앞서 개발 영역 7가지와 기술 스택 7가지를 알아봤습니다. 이번에는 이 둘을 조합한 7×7 매트릭스와 코드가 조직되는 단계, 그리고 시스템 아키텍처를 알아봅니다.
1. 개발 영역 × 기술 스택 매트릭스 (7×7)
7개 영역과 7개 기술 스택을 조합하면 49개의 셀로 이루어진 매트릭스가 만들어집니다. 이것이 웹사이트 개발의 전체 지도입니다.
SSALWorks 기술 스택 매트릭스
| Language | Runtime | Pkg Mgr | Tools | Library | Framework | External Service | |
|---|---|---|---|---|---|---|---|
| **Frontend** | HTML, CSS, JS, TS | Browser | npm | Vite, ESLint | React, Zustand | Next.js, Tailwind | - |
| **Backend Infra** | JS, TS | Node.js | npm | Webpack | Socket.io | - | Resend |
| **Backend API** | JS, TS | Node.js | npm | Postman | Zod | Next.js API | - |
| **Database** | SQL | PostgreSQL | - | Supabase Dashboard | supabase-js | - | **Supabase** |
| **Security** | - | - | - | - | Supabase Auth | - | OAuth |
| **Testing** | JS, TS | Node.js | npm | - | Jest, Playwright | - | - |
| **DevOps** | YAML | - | - | Git, GitHub | - | - | **Vercel** |
매트릭스 읽는 법
질문: React는 뭐야?
- 행(영역): Frontend
- 열(스택): Library
- 답: "React는 Frontend 영역의 Library"
질문: Supabase는 뭐야?
- 행(영역): Database
- 열(스택): Service
- 답: "Supabase는 Database 영역의 External Service(BaaS)"
질문: Next.js는 뭐야?
- 행(영역): Frontend + Backend API (둘 다!)
- 열(스택): Framework
- 답: "Next.js는 풀스택 Framework"
빈 셀의 의미
매트릭스에서 -로 표시된 빈 셀은 해당 조합이 필요 없거나 다른 영역에서 처리한다는 의미입니다.
예시:
- Security × Language =
-→ 보안은 별도 언어가 아닌 기존 언어로 구현 - Database × Package Manager =
-→ DB는 패키지 관리자 불필요
2. 코드 구성 7단계
코드는 작은 단위에서 큰 단위로 조직됩니다.
7단계 구조
`
[작은 단위] ─────────────────────────────────> [큰 단위]
Function → Component → Module → Package → Library → Framework → Architecture
`
각 단계 설명
| 단계 | 명칭 | 설명 | 예시 |
|---|---|---|---|
| 1 | **Function** | 하나의 작업 수행 | `add(a, b)` |
| 2 | **Component** | UI 조각 | `` |
| 3 | **Module** | 관련 코드 모음 (파일) | `auth.js` |
| 4 | **Package** | 배포 가능한 단위 | `react`, `lodash` |
| 5 | **Library** | 기능별 패키지 모음 | React, jQuery |
| 6 | **Framework** | 전체 구조 제공 | Next.js |
| 7 | **Architecture** | 시스템 설계 방식 | MVC, 마이크로서비스 |
실제 코드 예시
`javascript
// 1. Function - 가장 작은 단위
function formatPrice(price) {
return price.toLocaleString() + '원';
}
// 2. Component - 함수들이 모여 UI 조각
function PriceTag({ price }) {
return {formatPrice(price)};
}
// 3. Module - 컴포넌트들이 모인 파일 (price.js)
export { PriceTag, formatPrice };
`
단계별 관계
- Function이 모이면 → Component
- Component가 모이면 → Module (파일)
- Module이 모이면 → Package (npm 배포 단위)
- Package가 모이면 → Library
- Library 위에 구조를 입히면 → Framework
- Framework들을 조합하면 → Architecture
3. 3계층 아키텍처
웹 애플리케이션은 전통적으로 3개의 계층으로 나뉩니다.
3계층 구조
`
┌─────────────────────────────────────┐
│ Presentation Layer │ ← 화면 (보이는 것)
│ (프레젠테이션 계층) │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Logic Layer │ ← 로직 (처리하는 것)
│ (로직 계층) │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Data Layer │ ← 데이터 (저장하는 것)
│ (데이터 계층) │
└─────────────────────────────────────┘
`
각 계층 역할
| 계층 | 역할 | SSALWorks 기술 |
|---|---|---|
| **Presentation** | 사용자에게 화면 표시 | React, Next.js, Tailwind |
| **Logic** | 비즈니스 규칙 처리 | Next.js API Routes |
| **Data** | 데이터 저장/조회 | Supabase (PostgreSQL) |
실제 흐름: 회원가입
4. 4계층 아키텍처
현대 웹 개발에서는 인프라 계층을 추가한 4계층이 더 현실적입니다.
4계층 구조
`
┌─────────────────────────────────────┐
│ Client Tier │ ← 사용자 기기
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Server Tier │ ← 애플리케이션 서버
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Database Tier │ ← 데이터베이스 서버
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Infrastructure Tier │ ← 클라우드 인프라
└─────────────────────────────────────┘
`
각 계층과 SSALWorks
| 계층 | 역할 | SSALWorks |
|---|---|---|
| **Client** | 브라우저에서 실행 | React, Next.js |
| **Server** | 서버에서 로직 처리 | Vercel Edge |
| **Database** | 데이터 저장 | Supabase |
| **Infrastructure** | 호스팅, CDN | Vercel, Supabase Cloud |
3계층 vs 4계층
| 구분 | 3계층 | 4계층 |
|---|---|---|
| 관점 | 소프트웨어 구조 | 물리적 배포 구조 |
| 인프라 | 포함 안 됨 | 별도 계층 |
| 용도 | 코드 설계 | 시스템 설계 |
전체 분류체계 정리
| 분류 | 개수 | 내용 |
|---|---|---|
| 개발 영역 | 7개 | Frontend, Backend Infra/API, Database, Security, Testing, DevOps |
| 기술 스택 | 7개 | Language, Runtime, Pkg Mgr, Tools, Library, Framework, External Service |
| 매트릭스 | 49셀 | 영역 × 스택 조합 |
| 코드 구성 | 7단계 | Function → Architecture |
| 아키텍처 | 3~4계층 | Presentation → Logic → Data (+ Infra) |
이 분류체계를 머릿속에 넣어두면, 어떤 기술을 만나도 "이건 어디에 속하는구나"하고 바로 파악할 수 있습니다.
다음 편부터는 기술 스택 7가지를 하나씩 자세히 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 5,200자 / 작성자: Claude / 프롬프터: 써니
8편 | 기술 스택 - Language (언어)
기술 스택의 첫 번째 요소는 Language(언어)입니다. 컴퓨터에게 명령을 내리는 수단이자, 개발자의 생각을 코드로 표현하는 도구입니다. 웹사이트 개발에서 사용하는 핵심 언어들을 알아봅니다.
1. Language란 무엇인가
1-1. 프로그래밍 언어의 정의
Language(프로그래밍 언어)는 컴퓨터에게 명령을 내리는 언어입니다. 마치 영어, 한국어처럼 정해진 문법과 규칙이 있습니다.
| 특징 | 설명 |
|---|---|
| **문법** | 정해진 규칙에 따라 작성 |
| **가독성** | 사람이 읽을 수 있는 형태 |
| **변환** | 컴파일러/인터프리터가 기계어로 변환 |
비유:
- 한국어로 말하면 한국인이 이해
- JavaScript로 코드 작성하면 컴퓨터가 이해
1-2. 웹사이트 개발의 핵심 언어
웹사이트 개발에는 주로 5가지 언어가 사용됩니다:
| 언어 | 역할 | 영역 |
|---|---|---|
| **HTML** | 웹페이지 구조 | Frontend |
| **CSS** | 웹페이지 스타일 | Frontend |
| **JavaScript** | 동적 기능 | Frontend + Backend |
| **TypeScript** | JavaScript + 타입 | Frontend + Backend |
| **SQL** | 데이터베이스 질의 | Database |
2. HTML - 웹페이지의 구조
2-1. HTML이란?
HTML(HyperText Markup Language)은 웹페이지의 뼈대를 만드는 언어입니다.
> HTML은 문단<태그>내용태그> 형태로 작성됩니다. 예: , 제목
Claude Code가 HTML을 자동으로 생성해줍니다. 여러분은 "로그인 페이지 만들어줘"라고 요청하면 됩니다.
2-2. HTML의 구성 요소
| 요소 | 역할 | 예시 |
|---|---|---|
| **태그** | 콘텐츠 종류 표시 | ``, ``, ` ` |
| **속성** | 태그에 정보 추가 | `class`, `id`, `href` |
| **콘텐츠** | 실제 내용 | 텍스트, 이미지 등 |
핵심 태그:
: 메타 정보: 실제 내용- : 영역 구분
: 링크: 이미지
3. CSS - 웹페이지의 스타일
3-1. CSS란?
CSS(Cascading Style Sheets)는 HTML에 옷을 입히는 언어입니다.
> CSS는
선택자 { 속성: 값; }형태로 작성됩니다. 예:h1 { color: blue; }SSALWorks에서는 Tailwind CSS를 사용해서 더 간편하게 스타일을 적용합니다. CSS 문법을 직접 외울 필요 없이, 미리 정의된 클래스를 사용합니다.
3-2. CSS의 주요 기능
기능 설명 예시 **색상** 글자, 배경 색 `color: red;` **크기** 너비, 높이, 여백 `width: 100px;` **배치** 요소 위치 지정 `display: flex;` **반응형** 화면 크기 대응 `@media screen` 현대적 CSS:
- Flexbox: 유연한 레이아웃
- Grid: 2차원 레이아웃
- CSS Variables: 변수 사용
4. JavaScript - 웹페이지의 동작
4-1. JavaScript란?
JavaScript는 웹페이지에 생명을 불어넣는 언어입니다. 버튼 클릭, 애니메이션, 데이터 처리 등 모든 동적 기능을 담당합니다.
> JavaScript는 "이벤트가 발생하면 이 동작을 실행해라"는 방식으로 작동합니다.
예시 흐름:
- 사용자가 버튼 클릭 → JavaScript가 감지 → 알림창 표시
- 사용자가 폼 제출 → JavaScript가 데이터 검증 → 서버로 전송
Claude Code가 JavaScript를 자동으로 작성해줍니다.
4-2. JavaScript의 특징
특징 설명 **동적 타입** 변수 타입 자동 결정 **이벤트 기반** 사용자 상호작용 처리 **비동기 처리** 여러 작업 동시 처리 **풀스택** 프론트엔드 + 백엔드 모두 가능 최신 문법 (ES6+):
const,let: 변수 선언- 화살표 함수:
() => {} - 템플릿 리터럴:
`안녕, ${name}` - 구조 분해:
const { a, b } = obj
5. TypeScript - JavaScript + 타입
5-1. TypeScript란?
TypeScript는 JavaScript에 타입 시스템을 추가한 언어입니다. Microsoft가 만들었으며, 대규모 프로젝트에서 버그를 줄여줍니다.
> TypeScript는 "이 변수는 숫자만 넣을 수 있어"처럼 규칙을 정해서 실수를 방지합니다.
비유:
- JavaScript: 빈 칸에 아무거나 적어도 됨 (자유롭지만 실수 가능)
- TypeScript: 빈 칸에 "숫자만"이라고 미리 적혀 있음 (제한적이지만 안전)
SSALWorks는 TypeScript를 사용합니다. Claude Code가 타입을 자동으로 지정해줍니다.
5-2. TypeScript의 장점
장점 설명 **에러 조기 발견** 컴파일 시 타입 오류 검출 **코드 자동완성** IDE에서 정확한 제안 **리팩토링 안전** 타입 기반 수정 **문서화** 타입이 곧 문서
6. SQL - 데이터베이스 언어
6-1. SQL이란?
SQL(Structured Query Language)은 데이터베이스와 대화하는 언어입니다.
> SQL은 "이 조건에 맞는 데이터를 찾아줘"처럼 질문(Query)하는 방식으로 작동합니다.
비유: 도서관 사서에게 "2020년 이후에 나온 소설책 목록 보여주세요"라고 요청하는 것과 같습니다.
SSALWorks에서는 Supabase를 사용합니다. SQL을 직접 작성할 일은 거의 없고, Supabase가 제공하는 인터페이스나 Claude Code를 통해 데이터를 관리합니다.
6-2. SQL의 핵심 명령어
명령어 역할 CRUD **SELECT** 조회 Read **INSERT** 삽입 Create **UPDATE** 수정 Update **DELETE** 삭제 Delete
정리
언어 역할 SSALWorks 활용 HTML 구조 웹페이지 뼈대 CSS 스타일 Tailwind CSS 기반 JavaScript 동작 React, Next.js에서 사용 TypeScript 타입 안전 전체 프로젝트 적용 SQL DB 조작 Supabase PostgreSQL 다음 편에서는 코드가 실행되는 환경인 Runtime을 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 3,500자 / 작성자: Claude / 프롬프터: 써니
099편 | 기술 스택 - Runtime (실행 환경)9편 | 기술 스택 - Runtime (실행 환경)
기술 스택의 두 번째 요소는 Runtime(실행 환경)입니다. 코드를 작성해도 어딘가에서 실행되어야 합니다. 그 "어딘가"가 바로 Runtime입니다.
1. Runtime이란 무엇인가
1-1. 실행 환경의 정의
Runtime(런타임)은 작성한 코드가 실제로 돌아가는 환경입니다.
비유 설명 코드 = 악보 연주될 음악 Runtime = 무대 연주가 일어나는 장소 JavaScript의 경우:
- 브라우저에서 실행되면 → Browser Runtime
- 서버에서 실행되면 → Node.js Runtime
1-2. 웹사이트 개발의 주요 Runtime
Runtime 실행 위치 역할 **Browser** 사용자 컴퓨터 프론트엔드 실행 **Node.js** 서버 컴퓨터 백엔드 실행 **Edge Runtime** CDN 엣지 빠른 응답
2. Browser Runtime
2-1. 브라우저에서 JavaScript 실행
모든 웹 브라우저에는 JavaScript 엔진이 내장되어 있습니다.
브라우저 JavaScript 엔진 Chrome V8 Firefox SpiderMonkey Safari JavaScriptCore Edge V8 2-2. 브라우저가 제공하는 기능
기능 설명 예시 **DOM** HTML 조작 `document.getElementById()` **이벤트** 사용자 상호작용 `addEventListener()` **Storage** 데이터 저장 `localStorage` **Fetch** 네트워크 요청 `fetch()` > 브라우저에서는 버튼 클릭 감지, 데이터 저장, 서버 요청 등이 가능합니다. Claude Code가 이 코드들을 자동으로 작성해줍니다.
2-3. 브라우저 Runtime의 특징
특징 설명 **샌드박스** 보안을 위한 격리 환경 **제한된 접근** 파일 시스템 직접 접근 불가 **사용자 기기 실행** 클라이언트 사이드
3. Node.js Runtime
3-1. Node.js란?
Node.js는 브라우저 밖에서 JavaScript를 실행할 수 있게 해주는 Runtime입니다. 2009년 Ryan Dahl이 Chrome V8 엔진을 기반으로 만들었습니다.
Node.js가 할 수 있는 일:
- 서버 컴퓨터의 파일 읽기/쓰기
- 웹 서버 만들기 (API 서버)
- 데이터베이스 연결
> SSALWorks에서는 Next.js가 Node.js 위에서 실행됩니다. 서버 코드는 Claude Code가 자동으로 작성해줍니다.
3-2. Node.js의 특징
특징 설명 **비동기 처리** 여러 작업 동시 처리 **싱글 스레드** 효율적인 메모리 사용 **이벤트 기반** 이벤트 루프로 작업 관리 **npm 생태계** 수백만 개의 패키지 3-3. 비동기 처리 이해하기
카페 알바생 비유:
처리 방식 비유 특징 **동기 처리** (일반) 주문 1번 받고 → 커피 만들고 → 서빙 후 → 주문 2번 한 번에 하나씩, 느림 **비동기 처리** (Node.js) 주문 1,2,3,4번 쭉쭉 받고 → 동시에 처리 여러 개 동시, 빠름 3-4. Node.js가 잘하는 일
용도 예시 **API 서버** REST API, GraphQL **실시간 서비스** 채팅, 알림 **마이크로서비스** 가벼운 서버 **빌드 도구** Webpack, Vite
4. Edge Runtime
4-1. Edge Runtime이란?
Edge Runtime은 CDN의 엣지 서버에서 코드를 실행하는 환경입니다. 사용자와 가까운 곳에서 실행되어 응답이 매우 빠릅니다.
비교 일반 서버 Edge Runtime 위치 한 곳 (미국, 서울 등) 전 세계 분산 응답 속도 느림 매우 빠름 기능 완전한 Node.js 제한된 API 4-2. Edge Runtime의 특징
특징 설명 **빠른 시작** 콜드 스타트 거의 없음 **글로벌 배포** 사용자 가까이에서 실행 **경량화** 제한된 Node.js API 4-3. Vercel Edge Functions
Vercel Edge Functions은 전 세계 분산된 서버에서 코드를 실행합니다.
SSALWorks 활용:
기능 설명 Next.js Middleware 요청 전처리 API Routes (Edge) 빠른 API 응답 인증 처리 로그인/권한 확인 > Claude Code가 Edge 설정을 자동으로 해줍니다. 여러분은 "빠른 응답이 필요해"라고 요청하면 됩니다.
5. Runtime 선택 가이드
5-1. 상황별 Runtime 선택
상황 권장 Runtime 웹페이지 동작 Browser API 서버 개발 Node.js 빠른 응답 필요 Edge Runtime 데이터 집약적 처리 Node.js 인증/리다이렉트 Edge Runtime 5-2. SSALWorks 기술 스택
Runtime 사용처 Browser React 컴포넌트 실행 Node.js Next.js API Routes Edge Vercel Edge Functions
정리
Runtime 위치 용도 SSALWorks Browser 사용자 PC 프론트엔드 React Node.js 서버 백엔드 API Next.js Edge CDN 빠른 처리 Vercel 다음 편에서는 패키지를 관리하는 Package Manager를 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 3,200자 / 작성자: Claude / 프롬프터: 써니
1010편 | 기술 스택 - Package Manager (패키지 관리자)10편 | 기술 스택 - Package Manager (패키지 관리자)
기술 스택의 세 번째 요소는 Package Manager(패키지 관리자)입니다. 다른 개발자들이 만들어 놓은 코드를 쉽게 가져다 쓸 수 있게 해주는 도구입니다.
1. Package Manager란 무엇인가
1-1. 패키지의 정의
패키지(Package)는 다른 개발자가 만들어서 공유한 코드 묶음입니다.
비유 설명 패키지 = 조미료 마트에서 사오는 완제품 직접 만들기 = 간장 담그기 처음부터 만드는 것 예시:
- 날짜 계산 필요 →
moment패키지 사용 - HTTP 요청 필요 →
axios패키지 사용 - UI 컴포넌트 필요 →
react패키지 사용
1-2. Package Manager의 역할
Package Manager는 패키지를 관리하는 도구입니다.
역할 설명 **설치** 패키지 다운로드 **삭제** 패키지 제거 **버전 관리** 특정 버전 유지 **의존성 관리** 필요한 패키지 자동 설치
2. npm (Node Package Manager)
2-1. npm이란?
npm은 JavaScript의 표준 패키지 관리자입니다. Node.js를 설치하면 자동으로 함께 설치됩니다.
> Claude Code가 필요한 패키지를 자동으로 설치해줍니다. 여러분은 "React 프로젝트 만들어줘"라고 요청하면 됩니다.
2-2. npm의 특징
특징 설명 **npmjs.com** 수백만 개 패키지 저장소 **Node.js 포함** 별도 설치 불필요 **node_modules** 패키지 저장 폴더 **package.json** 프로젝트 설정 파일 2-3. 주요 npm 명령어
명령어 설명 `npm init` 새 프로젝트 생성 `npm install` 모든 패키지 설치 `npm install [패키지]` 특정 패키지 설치 `npm uninstall [패키지]` 패키지 제거 `npm update` 패키지 업데이트 `npm run [스크립트]` 스크립트 실행
3. package.json 이해하기
3-1. package.json이란?
package.json은 프로젝트의 설명서입니다. 필요한 패키지 목록, 실행 스크립트 등이 기록됩니다.
package.json에 들어가는 내용:
항목 설명 예시 name 프로젝트 이름 "my-project" version 버전 "1.0.0" scripts 실행 명령어 모음 "dev", "build", "start" dependencies 필수 패키지 목록 React, Next.js devDependencies 개발용 패키지 TypeScript, Jest > Claude Code가 package.json을 자동으로 생성하고 관리해줍니다.
3-2. dependencies vs devDependencies
구분 설명 예시 **dependencies** 서비스 실행에 필수 React, Next.js **devDependencies** 개발할 때만 필요 Jest, TypeScript 3-3. 버전 표기법
표기 의미 `4.18.2` 정확히 이 버전만 `^4.18.2` 4.x.x 중 최신 `~4.18.2` 4.18.x 중 최신 `*` 어떤 버전이든 버전 번호의 의미 (4.18.2):
- 4 = Major (큰 변화, 호환성 문제 가능)
- 18 = Minor (새 기능, 호환 유지)
- 2 = Patch (버그 수정)
4. 기타 Package Manager
4-1. yarn
yarn은 Facebook에서 만든 패키지 관리자입니다. npm보다 빠른 설치 속도가 장점입니다.
npm 명령어 yarn 명령어 `npm install` `yarn` `npm install react` `yarn add react` `npm run dev` `yarn dev` > npm과 yarn은 같은 역할을 합니다. SSALWorks에서는 npm을 사용합니다.
4-2. pnpm
pnpm은 디스크 공간을 효율적으로 사용하는 패키지 관리자입니다.
특징 설명 **공간 절약** 같은 패키지는 한 번만 저장 **빠른 속도** 링크 방식으로 설치 **엄격한 구조** 잘못된 의존성 방지 4-3. npm vs yarn vs pnpm
항목 npm yarn pnpm 설치 Node.js 포함 별도 설치 별도 설치 속도 보통 빠름 매우 빠름 디스크 많이 사용 많이 사용 적게 사용 인기 1위 2위 3위
5. node_modules와 .gitignore
5-1. node_modules 폴더
패키지가 설치되는 폴더입니다. 용량이 매우 큽니다.
`my-project/
├── node_modules/ ← 수백 MB ~ 수 GB
├── package.json
└── package-lock.json
`5-2. Git에 올리면 안 되는 이유
문제 설명 **용량** 너무 큼 (수백 MB) **불필요** package.json만 있으면 재설치 가능 **충돌** 환경마다 다를 수 있음 5-3. .gitignore 설정
.gitignore 파일에
node_modules/를 추가하면 Git이 해당 폴더를 무시합니다.> Claude Code가 .gitignore 파일을 자동으로 설정해줍니다.
협업 방법:
- package.json 파일을 Git에 올림
- 팀원이
npm install실행- 동일한 패키지가 설치됨
정리
항목 설명 **패키지** 다른 사람이 만든 코드 묶음 **npm** JavaScript 표준 패키지 관리자 **package.json** 프로젝트 설정 파일 **node_modules** 패키지 저장 폴더 (Git 제외) 다음 편에서는 개발을 도와주는 Tools를 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 3,400자 / 작성자: Claude / 프롬프터: 써니
1111편 | 기술 스택 - Tools (도구)11편 | 기술 스택 - Tools (도구)
기술 스택의 네 번째 요소는 Tools(도구)입니다. 코드를 작성하고, 검사하고, 빌드하는 과정을 도와주는 도구들입니다.
1. Tools란 무엇인가
1-1. 개발 도구의 정의
Tools(도구)는 개발 생산성을 높여주는 보조 프로그램입니다. 코드 자체는 아니지만, 코드를 더 잘 작성하고 관리할 수 있게 해줍니다.
비유 설명 코드 = 요리 최종 결과물 Tools = 조리도구 요리를 돕는 도구들 도구의 역할:
- 코드 품질 검사
- 코드 자동 정리
- 빌드 및 번들링
- 디버깅 지원
1-2. 주요 도구 분류
분류 도구 역할 **코드 검사** ESLint 문법 오류 탐지 **코드 정리** Prettier 코드 자동 포맷팅 **빌드 도구** Vite, Webpack 코드 번들링 **버전 관리** Git 변경 이력 관리 **디버깅** DevTools 브라우저 디버깅
2. ESLint - 코드 검사 도구
2-1. ESLint란?
ESLint는 JavaScript/TypeScript 코드의 문법 오류와 잠재적 버그를 찾아주는 도구입니다.
`javascript// ESLint가 잡아주는 오류 예시
// 1. 사용하지 않는 변수
const unusedVariable = 'hello'; // 경고: 사용되지 않음
// 2. 세미콜론 누락
const name = 'Kim' // 오류: 세미콜론 필요
// 3. 정의되지 않은 변수
console.log(undefined Variable); // 오류: 정의되지 않음
`2-2. ESLint 설정
`javascript// .eslintrc.js
module.exports = {
extends: ['next/core-web-vitals'],
rules: {
'no-unused-vars': 'warn', // 미사용 변수 경고
'no-console': 'off', // console 허용
'semi': ['error', 'always'], // 세미콜론 필수
},
};
`2-3. ESLint 명령어
명령어 설명 `npx eslint .` 전체 코드 검사 `npx eslint --fix .` 자동 수정 `npx eslint src/` 특정 폴더 검사
3. Prettier - 코드 포맷터
3-1. Prettier란?
Prettier는 코드를 일관된 스타일로 자동 정리해주는 도구입니다. 들여쓰기, 따옴표, 줄바꿈 등을 통일합니다.
변환 전:
`javascriptconst user={name:'Kim',age:25,email:'kim@email.com'};
function greet(name){return
Hello, ${name}!}`변환 후:
`javascriptconst user = {
name: 'Kim',
age: 25,
email: 'kim@email.com',
};
function greet(name) {
return
Hello, ${name}!;}
`3-2. Prettier 설정
`json// .prettierrc
{
"semi": true,
"singleQuote": true,
"tabWidth": 4,
"trailingComma": "es5",
"printWidth": 80
}
`3-3. ESLint vs Prettier
구분 ESLint Prettier 역할 코드 품질 검사 코드 스타일 정리 검사 대상 버그, 오류, 규칙 들여쓰기, 따옴표, 줄바꿈 수정 범위 로직 오류 포함 스타일만 사용 시점 코드 저장 시 코드 저장 시 함께 사용하는 것이 좋습니다:
- ESLint → 버그 잡기
- Prettier → 스타일 통일
4. Vite - 빌드 도구
4-1. Vite란?
Vite는 빠른 개발 서버와 빌드 도구입니다. 기존 Webpack보다 훨씬 빠릅니다.
특징 설명 **빠른 시작** 서버 시작이 즉각적 **빠른 HMR** 변경 사항 즉시 반영 **최적화 빌드** 프로덕션용 최적화 4-2. Vite vs Webpack
항목 Vite Webpack 서버 시작 즉시 느림 (번들링 필요) HMR 속도 매우 빠름 보통 설정 복잡도 간단 복잡 생태계 성장 중 성숙함 4-3. 빌드 과정 이해
`[개발 시]
여러 JS/CSS 파일 → Vite 개발 서버 → 브라우저에서 직접 로드
[배포 시]
여러 JS/CSS 파일 → Vite 빌드 → 하나의 번들 파일 → 서버 배포
`번들링 필요한 이유:
- 파일 수 줄이기 (HTTP 요청 감소)
- 코드 압축 (용량 감소)
- 브라우저 호환성 확보
5. 브라우저 DevTools
5-1. DevTools란?
DevTools(개발자 도구)는 브라우저에 내장된 디버깅 도구입니다. F12 또는 우클릭 → 검사로 열 수 있습니다.
5-2. 주요 탭 기능
탭 기능 용도 **Elements** HTML/CSS 확인 레이아웃 수정 **Console** 로그 확인 오류 추적 **Network** 네트워크 요청 API 확인 **Sources** 소스 코드 디버깅 **Application** 저장소 쿠키, 로컬스토리지 5-3. Console 활용
`javascript// 디버깅용 출력
console.log('일반 로그');
console.warn('경고 메시지');
console.error('에러 메시지');
console.table([{ name: 'Kim', age: 25 }]); // 테이블 형태
`5-4. Network 탭 활용
확인 항목 설명 **Status** 응답 코드 (200, 404, 500) **Time** 응답 시간 **Size** 응답 크기 **Preview** 응답 데이터 미리보기
6. 기타 유용한 도구
6-1. Postman
Postman은 API를 테스트하는 도구입니다.
기능 설명 요청 전송 GET, POST, PUT, DELETE 응답 확인 JSON, 상태 코드 환경 변수 개발/운영 환경 분리 컬렉션 요청 모음 저장 6-2. GitHub Copilot
GitHub Copilot은 AI 기반 코드 자동완성 도구입니다.
기능 설명 코드 제안 다음 줄 예측 함수 생성 주석 기반 코드 생성 설명 제공 코드 설명
정리
도구 역할 SSALWorks 활용 **ESLint** 코드 품질 검사 Next.js 기본 설정 **Prettier** 코드 스타일 정리 일관된 코드 형식 **Vite** 빌드 도구 빠른 개발 서버 **DevTools** 브라우저 디버깅 오류 추적 **Postman** API 테스트 API 개발 확인 다음 편에서는 기능별 코드 모음인 Library를 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 4,200자 / 작성자: Claude / 프롬프터: 써니
1212편 | 기술 스택 - Library (라이브러리)12편 | 기술 스택 - Library (라이브러리)
기술 스택의 다섯 번째 요소는 Library(라이브러리)입니다. 다른 개발자가 만들어 놓은 기능을 가져다 쓸 수 있게 해주는 코드 모음입니다.
1. Library란 무엇인가
1-1. 라이브러리의 정의
Library(라이브러리)는 특정 기능을 수행하는 코드 모음입니다. 직접 만들지 않고 가져다 쓸 수 있습니다.
비유 설명 라이브러리 = 레고 블록 필요한 블록만 골라 사용 직접 구현 = 나무 깎기 처음부터 모두 직접 제작 예시:
- 날짜 계산 필요 →
date-fns라이브러리 사용 - HTTP 요청 필요 →
axios라이브러리 사용 - UI 구성 필요 →
React라이브러리 사용
1-2. 라이브러리의 특징
특징 설명 **선택적 사용** 필요한 기능만 골라 사용 **개발자 주도** 내가 라이브러리를 호출 **독립적** 프로젝트 구조에 영향 없음 **교체 가능** 다른 라이브러리로 쉽게 교체
2. React - UI 라이브러리
2-1. React란?
React는 Facebook에서 만든 UI 라이브러리입니다. 화면을 컴포넌트 단위로 만듭니다.
컴포넌트 = 레고 블록
컴포넌트 용도 ` ` 페이지 상단 헤더 `` 클릭 버튼 ` ` 정보 카드 → 이런 컴포넌트들을 조합해서 전체 화면을 만듭니다.
> Claude Code가 React 컴포넌트를 자동으로 생성해줍니다. "로그인 폼 만들어줘"라고 요청하면 됩니다.
2-2. React의 핵심 개념
개념 설명 예시 **컴포넌트** UI 조각 ``, ` ` **Props** 데이터 전달 ` ` **State** 상태 관리 `useState(0)` **JSX** JavaScript + HTML ` {name}`2-3. 왜 React를 사용하는가?
장점 설명 **재사용성** 컴포넌트를 여러 곳에서 재사용 **효율적 렌더링** 변경된 부분만 업데이트 (Virtual DOM) **큰 생태계** 수많은 라이브러리와 도구 **취업 시장** 가장 많이 사용되는 프론트엔드 기술
3. Zustand - 상태 관리
3-1. 상태 관리란?
상태(State)는 애플리케이션의 데이터입니다. 여러 컴포넌트에서 같은 데이터를 공유해야 할 때 상태 관리가 필요합니다.
문제 상황:
`Header 컴포넌트 ← 로그인 정보 필요
Sidebar 컴포넌트 ← 로그인 정보 필요
Profile 컴포넌트 ← 로그인 정보 필요
`→ 로그인 정보를 한 곳에서 관리하고 모두가 접근하게 하자!
3-2. Zustand란?
Zustand는 간단하고 가벼운 상태 관리 라이브러리입니다.
Zustand가 하는 일:
기능 설명 공용 저장소 로그인 정보를 한 곳에 저장 어디서든 접근 Header, Sidebar, Profile 모두 같은 정보 사용 자동 업데이트 정보 바뀌면 모든 화면 자동 변경 > Claude Code가 Zustand 상태 관리 코드를 자동으로 작성해줍니다.
3-3. 상태 관리 라이브러리 비교
라이브러리 복잡도 학습 곡선 특징 **Zustand** 낮음 쉬움 간단, 가벼움 **Redux** 높음 어려움 대규모 앱에 적합 **Jotai** 중간 보통 원자적 상태 **Recoil** 중간 보통 Facebook 제작
4. Zod - 데이터 검증
4-1. 데이터 검증이란?
사용자가 입력한 데이터가 올바른지 확인하는 과정입니다.
검증 필요한 상황:
- 이메일 형식이 맞는지?
- 비밀번호가 8자 이상인지?
- 나이가 숫자인지?
4-2. Zod가 검증하는 것들
검증 항목 규칙 예시 오류 메시지 이름 2자 이상 "이름은 2자 이상이어야 합니다" 이메일 이메일 형식 "올바른 이메일 형식이 아닙니다" 나이 0~120 사이 숫자 "유효하지 않은 나이입니다" 비밀번호 8자 이상 "비밀번호는 8자 이상이어야 합니다" > Claude Code가 Zod 검증 코드를 자동으로 작성해줍니다. "회원가입 입력 검증해줘"라고 요청하면 됩니다.
4-3. Zod의 장점
장점 설명 **TypeScript 통합** 타입 자동 추론 **에러 메시지** 한글 메시지 커스텀 **체이닝** `.min().max().email()` 연결 **안전성** 런타임 검증
5. Jest - 테스트 라이브러리
5-1. 테스트란?
코드가 예상대로 동작하는지 자동으로 확인하는 것입니다.
테스트 예시:
테스트 항목 입력 기대 결과 1 + 2는 3이어야 함 1, 2 3 음수도 계산해야 함 -1, 1 0 로그인 성공 올바른 이메일/비번 성공 메시지 로그인 실패 틀린 비밀번호 오류 메시지 > Claude Code가 테스트 코드를 자동으로 작성해줍니다. "로그인 테스트 만들어줘"라고 요청하면 됩니다.
5-2. Jest 주요 기능
기능 설명 예시 `test()` 테스트 정의 `test('설명', () => {})` `expect()` 기대값 설정 `expect(result)` `toBe()` 정확히 일치 `.toBe(3)` `toEqual()` 깊은 비교 `.toEqual({ a: 1 })` 5-3. 테스트의 이점
이점 설명 **버그 조기 발견** 배포 전에 문제 발견 **안전한 리팩토링** 수정해도 기능 보장 **문서 역할** 코드 동작 방식 설명 **자신감** 코드 품질 확신
6. 기타 유용한 라이브러리
6-1. 자주 사용되는 라이브러리
라이브러리 용도 설치 **axios** HTTP 요청 `npm install axios` **date-fns** 날짜 처리 `npm install date-fns` **lodash** 유틸리티 함수 `npm install lodash` **uuid** 고유 ID 생성 `npm install uuid` 6-2. UI 컴포넌트 라이브러리
라이브러리 특징 **shadcn/ui** Tailwind 기반, 커스텀 용이 **Chakra UI** 접근성 우수, 간편한 API **Ant Design** 기업용 대시보드에 적합
정리
라이브러리 역할 SSALWorks 활용 **React** UI 구성 전체 프론트엔드 **Zustand** 상태 관리 전역 상태 관리 **Zod** 데이터 검증 API 입력 검증 **Jest** 테스트 단위 테스트 라이브러리 vs 프레임워크 핵심 차이:
- 라이브러리: 내가 호출함 (나에게 주도권)
- 프레임워크: 나를 호출함 (프레임워크에 주도권)
다음 편에서는 전체 구조를 제공하는 Framework를 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 4,500자 / 작성자: Claude / 프롬프터: 써니
1313편 | 기술 스택 - Framework (프레임워크)13편 | 기술 스택 - Framework (프레임워크)
기술 스택의 여섯 번째 요소는 Framework(프레임워크)입니다. 개발의 전체 구조와 규칙을 제공하는 큰 틀입니다.
1. Framework란 무엇인가
1-1. 프레임워크의 정의
Framework(프레임워크)는 애플리케이션 개발을 위한 뼈대와 규칙을 제공합니다. 정해진 구조 안에서 개발하면 됩니다.
비유 설명 프레임워크 = 건물 골조 기본 구조가 잡혀 있음 내 코드 = 인테리어 구조 안에서 꾸미기 1-2. 라이브러리 vs 프레임워크
구분 라이브러리 프레임워크 **주도권** 개발자 프레임워크 **호출 방향** 내가 라이브러리 호출 프레임워크가 내 코드 호출 **구조** 자유롭게 사용 정해진 규칙 따름 **비유** 레고 블록 레고 설계도 쉬운 비교:
구분 라이브러리 프레임워크 행동 내가 "날짜 포맷해줘" 요청 프레임워크가 "여기에 코드 넣어" 지시 비유 도구 상자에서 망치 꺼내기 설계도대로 집 짓기 > Claude Code가 프레임워크 구조에 맞게 코드를 자동으로 작성해줍니다.
2. Next.js - 풀스택 프레임워크
2-1. Next.js란?
Next.js는 React 기반의 풀스택 웹 프레임워크입니다. Vercel에서 만들었으며, 프론트엔드와 백엔드를 모두 개발할 수 있습니다.
특징 설명 **풀스택** 프론트엔드 + 백엔드 **파일 기반 라우팅** 폴더 구조 = URL 구조 **서버 사이드 렌더링** 빠른 초기 로딩 **API Routes** 백엔드 API 기능 2-2. 파일 기반 라우팅
Next.js에서는 폴더 구조가 곧 URL이 됩니다.
`app/
├── page.tsx → /
├── about/
│ └── page.tsx → /about
├── blog/
│ ├── page.tsx → /blog
│ └── [id]/
│ └── page.tsx → /blog/1, /blog/2, ...
└── api/
└── users/
└── route.ts → /api/users
`2-3. 렌더링 방식
방식 약자 설명 사용 시점 **서버 사이드 렌더링** SSR 요청마다 서버에서 렌더링 실시간 데이터 **정적 사이트 생성** SSG 빌드 시 HTML 생성 블로그, 문서 **클라이언트 사이드 렌더링** CSR 브라우저에서 렌더링 대시보드 2-4. API Routes
Next.js에서 백엔드 API를 만들 수 있습니다.
HTTP 메서드 용도 예시 GET 데이터 조회 회원 목록 가져오기 POST 데이터 생성 새 회원 등록 PUT 데이터 수정 회원 정보 변경 DELETE 데이터 삭제 회원 탈퇴 > Claude Code가 API 코드를 자동으로 작성해줍니다. "회원 목록 API 만들어줘"라고 요청하면 됩니다.
3. Tailwind CSS - 스타일 프레임워크
3-1. Tailwind CSS란?
Tailwind CSS는 유틸리티 기반의 CSS 프레임워크입니다. 미리 정의된 클래스를 조합해서 스타일을 만듭니다.
전통적인 CSS vs Tailwind CSS:
방식 작업 특징 전통적인 CSS 별도 CSS 파일에 스타일 정의 → HTML에서 클래스로 연결 파일 왔다갔다 Tailwind CSS HTML에 직접 `bg-blue-500 text-white` 같은 클래스 작성 한 곳에서 완성 > Tailwind는
bg-blue-500(파란 배경),text-white(흰 글자)처럼 의미가 명확한 클래스를 조합합니다. Claude Code가 Tailwind 클래스를 자동으로 적용해줍니다.3-2. Tailwind의 장점
장점 설명 **빠른 개발** 클래스 조합만으로 스타일링 **일관성** 정해진 색상, 크기 시스템 **반응형** `md:`, `lg:` 접두사로 간편 **작은 번들** 사용한 클래스만 포함 3-3. 반응형 디자인
Tailwind는 접두사로 화면 크기별 스타일을 쉽게 지정합니다.
접두사 화면 크기 의미 (없음) 0px~ 모바일 `sm:` 640px~ 작은 태블릿 `md:` 768px~ 태블릿 `lg:` 1024px~ 데스크톱 `xl:` 1280px~ 대형 화면 3-4. 자주 사용하는 클래스
레이아웃:
클래스 설명 `flex` Flexbox 레이아웃 `grid` Grid 레이아웃 `hidden` 숨김 `block` 블록 표시 여백:
클래스 설명 `p-4` padding: 16px `m-4` margin: 16px `px-4` 좌우 padding `py-4` 상하 padding 색상:
클래스 설명 `bg-blue-500` 배경색 파란색 `text-white` 글자색 흰색 `border-gray-300` 테두리색 회색
4. 프레임워크 선택 가이드
4-1. 프론트엔드 프레임워크 비교
프레임워크 특징 사용 시점 **Next.js** React 기반 풀스택 대부분의 프로젝트 **Nuxt** Vue 기반 풀스택 Vue 선호 시 **Remix** React 기반, 웹 표준 복잡한 데이터 로딩 **SvelteKit** Svelte 기반 가벼운 번들 4-2. CSS 프레임워크 비교
프레임워크 특징 사용 시점 **Tailwind CSS** 유틸리티 기반 커스텀 디자인 **Bootstrap** 컴포넌트 기반 빠른 프로토타입 **Material UI** 구글 디자인 머티리얼 디자인 필요 시 4-3. SSALWorks 기술 선택 이유
기술 선택 이유 **Next.js** 풀스택, Vercel 최적화, 큰 생태계 **Tailwind CSS** 빠른 개발, 커스텀 용이, 반응형 **React** 컴포넌트 기반, 재사용성, 취업 시장
정리
프레임워크 역할 SSALWorks 활용 **Next.js** 풀스택 웹 개발 메인 프레임워크 **Tailwind CSS** 스타일링 전체 UI 스타일 핵심 개념:
- 프레임워크 = 뼈대 + 규칙
- 라이브러리와 달리 주도권이 프레임워크에 있음
- Next.js로 프론트엔드 + 백엔드 모두 개발 가능
다음 편에서는 외부 제공 기능인 External Service (외부 서비스, XaaS)를 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 4,800자 / 작성자: Claude / 프롬프터: 써니
1414편 | 기술 스택 - External Service (외부 서비스, XaaS)14편 | 기술 스택 - External Service (외부 서비스, XaaS)
기술 스택의 마지막 요소는 External Service(외부 서비스)입니다. 외부 회사가 제공하는 완성된 기능을 API로 가져다 쓰는 방식입니다.
1. External Service란 무엇인가
1-1. 외부 서비스의 정의
External Service(외부 서비스)는 외부 회사가 인프라나 기능을 제공하고, 개발자는 API로 사용하는 방식입니다. 직접 구축하지 않아도 됩니다.
비유 설명 직접 구축 집에서 빵 굽기 외부 서비스 사용 빵집에서 사오기 장점:
- 직접 구축/관리 부담 없음
- 전문 업체가 운영하므로 안정적
- 빠른 개발 가능
- 필요한 만큼만 비용 지불
1-2. XaaS 종류
XaaS = "X as a Service" (X를 서비스로 제공)
유형 의미 제공 범위 예시 **IaaS** Infrastructure as a Service 서버, 네트워크 AWS EC2, GCP **PaaS** Platform as a Service 개발 플랫폼 Vercel, Heroku **BaaS** Backend as a Service 백엔드 전체 Supabase, Firebase **SaaS** Software as a Service 완성된 소프트웨어 Gmail, Notion 1-3. 직접 구축 vs 외부 서비스
항목 직접 구축 외부 서비스 초기 비용 높음 낮음 개발 시간 오래 걸림 빠름 유지보수 직접 해야 함 업체가 해줌 커스터마이징 자유로움 제한적 확장성 직접 설계 자동 지원
2. Supabase - BaaS
2-1. Supabase란?
Supabase는 오픈소스 Firebase 대안입니다. 데이터베이스, 인증, 스토리지, 실시간 기능을 모두 제공합니다.
기능 설명 **Database** PostgreSQL 데이터베이스 **Auth** 회원가입, 로그인, 소셜 로그인 **Storage** 파일 업로드, 이미지 저장 **Realtime** 실시간 데이터 동기화 **Edge Functions** 서버리스 함수 2-2. Supabase로 할 수 있는 일
작업 설명 예시 데이터 조회 DB에서 정보 가져오기 회원 목록 불러오기 데이터 삽입 DB에 새 정보 저장 새 회원 등록 로그인/인증 사용자 로그인 처리 이메일+비밀번호 로그인 파일 저장 이미지, 문서 저장 프로필 사진 업로드 > Claude Code가 Supabase 연동 코드를 자동으로 작성해줍니다. "회원 목록 가져와줘"라고 요청하면 됩니다.
2-3. Supabase vs Firebase
항목 Supabase Firebase 데이터베이스 PostgreSQL (SQL) Firestore (NoSQL) 오픈소스 ✅ 예 ❌ 아니오 셀프 호스팅 ✅ 가능 ❌ 불가능 가격 더 저렴 비쌈 소유 업체 독립 회사 Google
3. Vercel - PaaS
3-1. Vercel이란?
Vercel은 프론트엔드 배포 플랫폼입니다. Next.js를 만든 회사이며, Git push만 하면 자동 배포됩니다.
기능 설명 **자동 배포** Git push → 자동 빌드 및 배포 **프리뷰** PR마다 미리보기 URL 생성 **CDN** 전 세계 엣지 서버에 배포 **도메인** 커스텀 도메인 연결 **분석** 트래픽, 성능 분석 3-2. Vercel 배포 과정
`- GitHub에 코드 push
↓
- Vercel이 자동으로 감지
↓
- 빌드 실행 (npm run build)
↓
- 빌드 결과물을 CDN에 배포
↓
- URL로 접속 가능 (xxx.vercel.app)
`3-3. Vercel 장점
장점 설명 **무료 티어** 개인 프로젝트 무료 **빠른 배포** 수 초 내 배포 완료 **Next.js 최적화** 최상의 성능 **서버리스** 서버 관리 불필요
4. Resend - 이메일 외부 서비스
4-1. Resend란?
Resend는 개발자 친화적인 이메일 발송 외부 서비스입니다. 회원가입 확인, 비밀번호 재설정 등 트랜잭션 이메일에 사용합니다.
4-2. Resend로 할 수 있는 일
이메일 종류 용도 환영 이메일 회원가입 완료 안내 비밀번호 재설정 비밀번호 변경 링크 발송 알림 이메일 결제 완료, 구독 갱신 안내 > Claude Code가 Resend 이메일 발송 코드를 자동으로 작성해줍니다. "환영 이메일 보내줘"라고 요청하면 됩니다.
4-3. 이메일 외부 서비스 비교
서비스 특징 무료 티어 **Resend** 개발자 친화적 월 3,000통 **SendGrid** 대규모 서비스 일 100통 **Mailgun** API 중심 제한적
5. 기타 유용한 외부 서비스
5-1. 인증/결제 외부 서비스
서비스 용도 특징 **Auth0** 인증 전문 소셜 로그인, SSO **Clerk** 인증 + 사용자 관리 쉬운 통합 **Stripe** 결제 글로벌 표준 **Toss Payments** 한국 결제 국내 최적화 5-2. AI/분석 외부 서비스
서비스 용도 특징 **OpenAI API** AI 기능 GPT, DALL-E **Anthropic API** AI 기능 Claude **Google Analytics** 웹 분석 무료 **Mixpanel** 제품 분석 이벤트 추적 5-3. 파일/미디어 외부 서비스
서비스 용도 특징 **Cloudinary** 이미지 처리 변환, 최적화 **Uploadthing** 파일 업로드 Next.js 통합 **AWS S3** 파일 저장 대용량
6. SSALWorks 외부 서비스 스택
6-1. 핵심 외부 서비스
서비스 역할 선택 이유 **Supabase** 백엔드 전체 오픈소스, PostgreSQL **Vercel** 호스팅/배포 Next.js 최적화 **Resend** 이메일 발송 개발자 친화적 6-2. 외부 서비스 연동 구조
`[사용자]
↓
[Vercel - 호스팅]
↓
[Next.js 앱]
↓
┌───────────┬───────────┬───────────┐
│ Supabase │ Resend │ Toss Pay │
│ (DB/Auth) │ (이메일) │ (결제) │
└───────────┴───────────┴───────────┘
`6-3. 비용 구조 (무료 티어)
서비스 무료 제공량 **Supabase** DB 500MB, Auth 50,000 MAU **Vercel** 무제한 배포, 월 100GB 대역폭 **Resend** 월 3,000 이메일
정리
유형 외부 서비스 SSALWorks 활용 **BaaS** Supabase 데이터베이스, 인증 **PaaS** Vercel 배포, 호스팅 **SaaS** Resend 이메일 발송 핵심 개념:
- XaaS = 외부 서비스로 제공받는 것
- 직접 구축 대신 API로 사용
- 빠른 개발, 유지보수 부담 감소
- 스타트업/MVP에 특히 유용
다음 편부터는 개발 영역 7가지를 자세히 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 4,600자 / 작성자: Claude / 프롬프터: 써니
1515편 | 개발 영역 - Frontend (프론트엔드)15편 | 개발 영역 - Frontend (프론트엔드)
사용자가 직접 보고 상호작용하는 화면, 바로 Frontend입니다. 버튼을 클릭하고, 폼에 입력하고, 애니메이션을 보는 모든 것이 프론트엔드 영역입니다.
15.1 Language (언어)
프론트엔드의 3대 언어와 TypeScript를 알아봅니다.
HTML (HyperText Markup Language)
웹페이지의 구조를 정의합니다.
`html헤더 본문 `- 태그로 요소를 정의
- 시맨틱 태그로 의미 부여 (
,,) - 접근성과 SEO에 직접 영향
CSS (Cascading Style Sheets)
웹페이지의 스타일을 정의합니다.
`css.button {
background: #10B981;
color: white;
padding: 12px 24px;
border-radius: 8px;
}
`- 색상, 크기, 여백, 레이아웃 지정
- Flexbox, Grid로 복잡한 레이아웃 구성
- 반응형 디자인 (미디어 쿼리)
JavaScript
웹페이지의 동작을 정의합니다.
`javascriptbutton.addEventListener('click', () => {
alert('클릭!');
});
`- 사용자 이벤트 처리
- DOM 조작
- API 호출 (fetch)
- 동적 콘텐츠 렌더링
TypeScript
JavaScript에 타입을 추가한 언어입니다.
`typescriptfunction greet(name: string): string {
return
안녕, ${name}!;}
`- 컴파일 타임에 오류 발견
- 자동완성, 리팩토링 지원
- 대규모 프로젝트에 필수
SSALWorks: TypeScript를 기본으로 사용합니다.
15.2 Runtime (실행 환경)
Browser (브라우저)
프론트엔드 코드가 실행되는 곳입니다.
브라우저 엔진 Chrome V8 Firefox SpiderMonkey Safari JavaScriptCore Edge V8 브라우저가 하는 일:
- HTML 파싱 → DOM 트리 생성
- CSS 파싱 → CSSOM 생성
- JavaScript 실행
- 렌더링 (화면에 그리기)
주의: 브라우저마다 약간의 차이가 있어 크로스 브라우저 테스트가 필요합니다.
15.3 Package Manager (패키지 관리자)
npm (Node Package Manager)
가장 널리 쓰이는 패키지 관리자입니다.
`bashnpm install react # 패키지 설치
npm install -D eslint # 개발 의존성 설치
npm run build # 스크립트 실행
`yarn
npm의 대안으로, 더 빠른 설치 속도를 제공합니다.
`bashyarn add react
yarn add -D eslint
yarn build
`SSALWorks: npm을 기본으로 사용합니다.
15.4 Tools (도구)
Vite
빠른 개발 서버와 빌드 도구입니다.
`bashnpm create vite@latest my-app
cd my-app && npm install && npm run dev
`- HMR (Hot Module Replacement) 지원
- 빠른 콜드 스타트
- 최적화된 프로덕션 빌드
ESLint
코드 품질을 검사합니다.
`javascript// ❌ ESLint 경고: 사용하지 않는 변수
const unused = 'hello';
// ✅ 올바른 코드
const message = 'hello';
console.log(message);
`Prettier
코드 포맷을 자동으로 정리합니다.
`javascript// 저장 전
const x={a:1,b:2}
// Prettier 적용 후
const x = { a: 1, b: 2 };
`DevTools (브라우저 개발자 도구)
- Elements: DOM, CSS 검사
- Console: JavaScript 로그, 에러
- Network: API 호출 모니터링
- Performance: 성능 분석
15.5 Library (라이브러리)
React
UI를 컴포넌트 단위로 구성하는 라이브러리입니다.
`jsxfunction Button({ label, onClick }) {
return ;
}
`- 컴포넌트 기반 개발
- Virtual DOM으로 효율적 렌더링
- 풍부한 생태계
Zustand
가벼운 상태 관리 라이브러리입니다.
`javascriptimport { create } from 'zustand';
const useStore = create((set) => ({
count: 0,
increase: () => set((state) => ({ count: state.count + 1 })),
}));
`- Redux보다 간단한 문법
- 보일러플레이트 최소화
- TypeScript 지원 우수
React Hook Form
폼 상태 관리를 쉽게 해주는 라이브러리입니다.
`jsxconst { register, handleSubmit } = useForm();
`- 비제어 컴포넌트 방식
- 렌더링 최적화
- 유효성 검사 통합
SSALWorks: React + Zustand + React Hook Form 조합을 사용합니다.
15.6 Framework (프레임워크)
Next.js
React 기반 풀스택 프레임워크입니다.
`app/
├── page.tsx # / 라우트
├── about/
│ └── page.tsx # /about 라우트
└── api/
└── hello/
└── route.ts # API 엔드포인트
`주요 기능:
- 파일 기반 라우팅
- SSR (Server-Side Rendering)
- API Routes (백엔드 통합)
- 이미지 최적화
Tailwind CSS
유틸리티 기반 CSS 프레임워크입니다.
`html버튼
`- 클래스 조합으로 스타일링
- CSS 파일 따로 안 만들어도 됨
- 일관된 디자인 시스템
SSALWorks: Next.js + Tailwind CSS를 기본 스택으로 사용합니다.
15.7 External Service (외부 서비스)
Frontend 영역에서는 별도의 외부 서비스를 사용하지 않습니다. 필요한 서비스는 다른 영역(Database, DevOps 등)에서 연동합니다.
정리
기술 스택 SSALWorks 선택 Language HTML, CSS, JavaScript, **TypeScript** Runtime Browser Package Manager **npm** Tools Vite, ESLint, Prettier, DevTools Library **React**, Zustand, React Hook Form Framework **Next.js**, Tailwind CSS External Service - 프론트엔드는 사용자와 직접 만나는 영역입니다. 다음 편에서는 서버 환경을 구축하는 Backend Infra를 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 5,100자 / 작성자: Claude / 프롬프터: 써니
1616편 | 개발 영역 - Backend Infra (백엔드 기반)16편 | 개발 영역 - Backend Infra (백엔드 기반)
서버가 돌아가는 기반 환경, Backend Infra입니다. 실시간 통신, 파일 처리, 이메일 발송 등 서버 인프라를 구성하는 기술들을 다룹니다.
16.1 Language (언어)
JavaScript & TypeScript
백엔드에서도 프론트엔드와 동일한 언어를 사용합니다.
`typescript// 서버 사이드 TypeScript
import express from 'express';
const app = express();
app.get('/api/hello', (req, res) => {
res.json({ message: 'Hello from server!' });
});
`장점:
- 프론트엔드/백엔드 동일 언어 → 학습 비용 감소
- 코드 공유 가능 (유틸리티, 타입 정의)
- npm 생태계 공유
SSALWorks: TypeScript를 기본으로 사용합니다.
16.2 Runtime (실행 환경)
Node.js
서버에서 JavaScript를 실행하는 런타임입니다.
`bashnode server.js # Node.js로 서버 실행
`특징:
- V8 엔진 기반 (Chrome과 동일)
- 비동기 I/O (높은 동시성)
- 이벤트 루프 기반
- 단일 스레드 (멀티 프로세스로 확장)
버전 관리:
`bashnvm으로 Node.js 버전 관리
nvm install 20
nvm use 20
node -v # v20.x.x
`SSALWorks: Node.js 20 LTS를 사용합니다.
Node.js vs Browser
구분 Browser Node.js DOM ✅ 있음 ❌ 없음 window ✅ 있음 ❌ 없음 fs (파일) ❌ 없음 ✅ 있음 네트워크 fetch fetch, http
16.3 Package Manager (패키지 관리자)
npm & yarn
프론트엔드와 동일한 패키지 관리자를 사용합니다.
`bash백엔드 패키지 설치 예시
npm install express socket.io
npm install -D nodemon typescript
`package.json 스크립트:
`json{
"scripts": {
"dev": "nodemon src/server.ts",
"build": "tsc",
"start": "node dist/server.js"
}
}
`
16.4 Tools (도구)
Webpack
모듈 번들러입니다. 여러 파일을 하나로 묶어줍니다.
`javascript// webpack.config.js
module.exports = {
entry: './src/index.ts',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{ test: /\.ts$/, use: 'ts-loader' },
],
},
};
`하는 일:
- 여러 파일 → 하나의 번들로
- TypeScript → JavaScript 변환
- 코드 압축 (minify)
- 트리 쉐이킹 (사용 안 하는 코드 제거)
참고: Next.js를 사용하면 Webpack 설정이 자동으로 처리됩니다.
nodemon
개발 중 파일 변경 시 자동으로 서버를 재시작합니다.
`bashnpx nodemon src/server.ts
파일 저장할 때마다 서버 자동 재시작
`
16.5 Library (라이브러리)
Socket.io
실시간 양방향 통신 라이브러리입니다.
`javascript// 서버
import { Server } from 'socket.io';
const io = new Server(server);
io.on('connection', (socket) => {
console.log('사용자 연결됨');
socket.on('chat', (message) => {
io.emit('chat', message); // 모든 사용자에게 전송
});
});
``javascript// 클라이언트
import { io } from 'socket.io-client';
const socket = io();
socket.emit('chat', '안녕하세요!');
socket.on('chat', (msg) => console.log(msg));
`사용 사례:
- 실시간 채팅
- 실시간 알림
- 협업 도구 (동시 편집)
- 게임
chokidar
파일 시스템 변경을 감지하는 라이브러리입니다.
`javascriptimport chokidar from 'chokidar';
chokidar.watch('./uploads').on('all', (event, path) => {
console.log(event, path);
// add, change, unlink 등 이벤트 감지
});
`사용 사례:
- 파일 업로드 감지
- 자동 빌드 트리거
- 로그 파일 모니터링
16.6 Framework (프레임워크)
Backend Infra 영역에서는 별도의 프레임워크를 사용하지 않습니다. Next.js가 API Routes를 통해 백엔드 기능을 제공하므로, 별도의 Express 등을 사용하지 않아도 됩니다.
16.7 External Service (외부 서비스)
Resend (이메일 발송 서비스)
개발자 친화적인 이메일 API 서비스입니다.
`typescriptimport { Resend } from 'resend';
const resend = new Resend('re_xxxxx');
await resend.emails.send({
from: 'SSALWorks
', to: 'user@example.com',
subject: '가입을 환영합니다!',
html: '
환영합니다!
SSALWorks에 가입해 주셔서 감사합니다.
',});
`특징:
- 간단한 API
- React Email 지원 (React 컴포넌트로 이메일 작성)
- 높은 전달률
- 상세한 분석 (열람, 클릭 추적)
사용 사례:
- 회원가입 확인 이메일
- 비밀번호 재설정
- 결제 영수증
- 마케팅 이메일
SSALWorks: Resend를 이메일 발송에 사용합니다.
왜 Resend인가?
서비스 장점 단점 **Resend** 간단한 API, React Email 신생 서비스 SendGrid 안정성, 기능 풍부 복잡한 설정 AWS SES 저렴함 설정 어려움 Mailgun 좋은 전달률 유럽 중심
정리
기술 스택 SSALWorks 선택 Language JavaScript, **TypeScript** Runtime **Node.js** 20 LTS Package Manager **npm** Tools Webpack (Next.js 내장) Library Socket.io, chokidar Framework - (Next.js 사용) External Service **Resend** Backend Infra는 서버가 돌아가는 기반을 담당합니다. 다음 편에서는 비즈니스 로직을 처리하는 Backend API를 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 4,800자 / 작성자: Claude / 프롬프터: 써니
1717편 | 개발 영역 - Backend API (백엔드 API)17편 | 개발 영역 - Backend API (백엔드 API)
프론트엔드와 데이터베이스를 연결하는 다리, Backend API입니다. 비즈니스 로직을 처리하고, 데이터를 검증하고, 응답을 반환하는 핵심 영역입니다.
17.1 Language (언어)
JavaScript & TypeScript
API 개발에도 TypeScript를 사용합니다.
TypeScript의 이점:
이점 설명 요청/응답 타입 정의 어떤 데이터가 오가는지 명확 실수 방지 잘못된 필드명 자동 감지 IDE 자동완성 개발 속도 향상 > Claude Code가 TypeScript API를 자동으로 작성해줍니다.
17.2 Runtime (실행 환경)
Node.js
전통적인 서버 실행 환경입니다. 파일 읽기/쓰기 등 모든 서버 기능을 사용할 수 있습니다.
Edge Runtime
CDN 엣지에서 실행되는 경량 런타임입니다. 사용자와 가까운 곳에서 빠르게 응답합니다.
Node.js vs Edge Runtime:
구분 Node.js Edge 콜드 스타트 느림 빠름 API 지원 전체 제한적 실행 위치 특정 리전 전 세계 CDN 용도 복잡한 로직 간단한 API SSALWorks: 대부분 Node.js, 간단한 API는 Edge 사용.
17.3 Package Manager (패키지 관리자)
npm
API 개발에 필요한 패키지를 관리합니다.
SSALWorks API 필수 패키지:
패키지 용도 zod 데이터 검증 @supabase/supabase-js DB 연동 > Claude Code가 필요한 패키지를 자동으로 설치해줍니다.
17.4 Tools (도구)
Postman
API를 테스트하는 도구입니다.
주요 기능:
- 요청 보내기 (GET, POST, PUT, DELETE)
- 헤더, 바디 설정
- 환경 변수 관리
- 자동화 테스트
사용 예시: 로그인 API를 테스트할 때, Postman에서 URL, 이메일, 비밀번호를 입력하고 요청을 보내면 결과를 바로 확인할 수 있습니다.
Thunder Client
VS Code 확장 프로그램으로, Postman과 유사한 기능을 제공합니다.
장점:
- VS Code 내에서 바로 사용
- 가볍고 빠름
- 무료
SSALWorks: Thunder Client를 주로 사용합니다.
17.5 Library (라이브러리)
Zod
TypeScript 기반 데이터 검증 라이브러리입니다.
Zod가 하는 일: "이메일은 이메일 형식이어야 해", "비밀번호는 8자 이상이어야 해" 같은 규칙을 정의하고, 입력값이 규칙에 맞는지 자동으로 검증합니다.
Zod의 장점:
장점 설명 런타임 검증 실제 실행 시 데이터 확인 타입 추론 TypeScript 타입 자동 생성 상세한 에러 "이메일 형식이 아닙니다" 같은 메시지 Next.js 호환 SSALWorks와 완벽 호환 > Claude Code가 Zod 검증 코드를 자동으로 작성해줍니다. 여러분은 "이메일과 비밀번호 검증해줘"라고 요청하면 됩니다.
17.6 Framework (프레임워크)
Next.js API Routes
Next.js의 내장 API 기능입니다. 폴더 구조가 곧 API URL이 됩니다.
폴더 구조 = API URL:
폴더 경로 API URL 기능 `app/api/auth/login/route.ts` `/api/auth/login` 로그인 `app/api/users/route.ts` `/api/users` 회원 목록/등록 `app/api/users/[id]/route.ts` `/api/users/123` 특정 회원 조회 HTTP 메서드:
메서드 용도 GET 조회 POST 생성 PUT 수정 DELETE 삭제 > Claude Code가 API 코드를 자동으로 생성해줍니다. 여러분은 "로그인 API 만들어줘"라고 요청하면 됩니다.
17.7 External Service (외부 서비스)
Backend API 영역에서는 별도의 외부 서비스를 사용하지 않습니다. 필요한 서비스는 다른 영역에서 연동합니다:
- 데이터베이스 → Database 영역 (Supabase)
- 인증 → Security 영역 (Supabase Auth)
- 이메일 → Backend Infra 영역 (Resend)
API 설계 원칙
RESTful API
URL GET POST PUT DELETE `/api/users` 목록 조회 생성 - - `/api/users/123` 단일 조회 - 수정 삭제 응답 형식
결과 응답 내용 성공 `{ success: true, data: {...} }` 에러 `{ success: false, error: {...} }`
정리
기술 스택 SSALWorks 선택 Language JavaScript, **TypeScript** Runtime **Node.js**, Edge Runtime Package Manager **npm** Tools Postman, **Thunder Client** Library **Zod** Framework **Next.js API Routes** External Service - Backend API는 비즈니스 로직의 핵심입니다. 다음 편에서는 데이터를 저장하는 Database를 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 5,200자 / 작성자: Claude / 프롬프터: 써니
1818편 | 개발 영역 - Database (데이터베이스)18편 | 개발 영역 - Database (데이터베이스)
모든 데이터를 저장하고 관리하는 창고, Database입니다. 회원 정보, 게시글, 주문 내역 등 애플리케이션의 모든 데이터가 여기에 저장됩니다.
18.1 Language (언어)
SQL (Structured Query Language)
데이터베이스와 대화하는 언어입니다.
데이터 조회 (SELECT):
`sql-- 모든 사용자 조회
SELECT * FROM users;
-- 특정 조건으로 조회
SELECT name, email FROM users WHERE status = 'active';
-- 정렬
SELECT * FROM posts ORDER BY created_at DESC;
-- 제한
SELECT * FROM posts LIMIT 10;
`데이터 삽입 (INSERT):
`sqlINSERT INTO users (name, email, password)
VALUES ('홍길동', 'hong@example.com', 'hashed_password');
`데이터 수정 (UPDATE):
`sqlUPDATE users
SET name = '김철수'
WHERE id = 123;
`데이터 삭제 (DELETE):
`sqlDELETE FROM users WHERE id = 123;
`테이블 생성:
`sqlCREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
`
18.2 Runtime (실행 환경)
PostgreSQL
오픈소스 관계형 데이터베이스입니다.
특징:
- ACID 트랜잭션 지원
- JSON 데이터 타입 지원
- 전문 검색 (Full-Text Search)
- 확장성 (Extensions)
주요 데이터 타입:
타입 설명 예시 `UUID` 고유 식별자 `'a1b2c3d4-...'` `VARCHAR(n)` 가변 길이 문자열 `'홍길동'` `TEXT` 긴 텍스트 게시글 본문 `INTEGER` 정수 `42` `BOOLEAN` 참/거짓 `true`, `false` `TIMESTAMP` 날짜/시간 `'2025-12-21 15:30:00'` `JSONB` JSON 데이터 `{"key": "value"}` SSALWorks: Supabase가 제공하는 PostgreSQL을 사용합니다.
18.3 Package Manager (패키지 관리자)
Database 영역에서는 패키지 관리자를 사용하지 않습니다. 데이터베이스는 SQL로 직접 관리합니다.
18.4 Tools (도구)
Supabase Dashboard
웹 기반 데이터베이스 관리 도구입니다.
주요 기능:
- Table Editor: 테이블 생성/수정/삭제
- SQL Editor: SQL 쿼리 직접 실행
- Database: 스키마, 인덱스, 정책 관리
- Authentication: 사용자 관리
- Storage: 파일 저장소
- Logs: 쿼리 로그, 에러 로그
사용법:
- https://supabase.com 접속
- 프로젝트 선택
- 좌측 메뉴에서 기능 선택
pgAdmin
PostgreSQL 전용 GUI 관리 도구입니다.
특징:
- 로컬 설치형
- 복잡한 쿼리 작성에 유용
- ERD (Entity Relationship Diagram) 지원
SSALWorks: Supabase Dashboard를 주로 사용합니다.
18.5 Library (라이브러리)
@supabase/supabase-js
Supabase JavaScript 클라이언트입니다.
설치:
`bashnpm install @supabase/supabase-js
`초기화:
`typescriptimport { createClient } from '@supabase/supabase-js';
const supabase = createClient(
process.env.SUPABASE_URL!,
process.env.SUPABASE_ANON_KEY!
);
`데이터 조회:
`typescript// 전체 조회
const { data, error } = await supabase
.from('users')
.select('*');
// 조건 조회
const { data } = await supabase
.from('users')
.select('name, email')
.eq('status', 'active')
.order('created_at', { ascending: false })
.limit(10);
`데이터 삽입:
`typescriptconst { data, error } = await supabase
.from('users')
.insert({ name: '홍길동', email: 'hong@example.com' })
.select();
`데이터 수정:
`typescriptconst { data, error } = await supabase
.from('users')
.update({ name: '김철수' })
.eq('id', 123)
.select();
`데이터 삭제:
`typescriptconst { error } = await supabase
.from('users')
.delete()
.eq('id', 123);
`SSALWorks: 모든 DB 작업에 supabase-js를 사용합니다.
18.6 Framework (프레임워크)
Database 영역에서는 별도의 프레임워크를 사용하지 않습니다. Supabase가 ORM 없이도 충분한 기능을 제공합니다.
18.7 External Service (외부 서비스)
Supabase (BaaS - Backend as a Service)
Firebase의 오픈소스 대안으로, PostgreSQL 기반의 BaaS입니다.
Supabase가 제공하는 기능:
기능 설명 **Database** PostgreSQL 데이터베이스 **Auth** 인증/인가 시스템 **Storage** 파일 저장소 **Realtime** 실시간 데이터 동기화 **Edge Functions** 서버리스 함수 왜 Supabase인가?
항목 Firebase Supabase 데이터베이스 NoSQL **PostgreSQL** (SQL) 오픈소스 ❌ ✅ 셀프호스팅 ❌ ✅ 가격 비쌈 저렴함 확장성 제한적 PostgreSQL 생태계 Supabase 무료 플랜:
- 500MB 데이터베이스
- 1GB 파일 스토리지
- 50,000 MAU (월간 활성 사용자)
- 무제한 API 요청
SSALWorks: Supabase를 데이터베이스 서비스로 사용합니다.
데이터베이스 설계 원칙
1. 정규화
데이터 중복을 최소화합니다.
`sql-- ❌ 나쁜 예: 중복 데이터
CREATE TABLE orders (
id UUID PRIMARY KEY,
user_name VARCHAR(100), -- 중복!
user_email VARCHAR(255), -- 중복!
product_name VARCHAR(100)
);
-- ✅ 좋은 예: 정규화
CREATE TABLE users (
id UUID PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(255)
);
CREATE TABLE orders (
id UUID PRIMARY KEY,
user_id UUID REFERENCES users(id), -- 외래 키
product_name VARCHAR(100)
);
`2. 인덱스
자주 검색하는 컬럼에 인덱스를 추가합니다.
`sqlCREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_orders_user_id ON orders(user_id);
`3. RLS (Row Level Security)
행 단위 보안 정책입니다.
`sql-- RLS 활성화
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
-- 정책: 본인 게시글만 수정 가능
CREATE POLICY "Users can update own posts"
ON posts FOR UPDATE
USING (auth.uid() = user_id);
`
정리
기술 스택 SSALWorks 선택 Language **SQL** Runtime **PostgreSQL** Package Manager - Tools **Supabase Dashboard**, pgAdmin Library **@supabase/supabase-js** Framework - External Service **Supabase (BaaS)** Database는 애플리케이션의 심장입니다. 다음 편에서는 인증과 인가를 담당하는 Security를 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 5,400자 / 작성자: Claude / 프롬프터: 써니
1919편 | 개발 영역 - Security (보안)19편 | 개발 영역 - Security (보안)
누가 접근하고 무엇을 할 수 있는지 관리하는 영역, Security입니다. 인증(Authentication)과 인가(Authorization)를 통해 애플리케이션을 보호합니다.
인증 vs 인가
시작하기 전에 두 개념을 명확히 구분합니다.
구분 인증 (Authentication) 인가 (Authorization) 질문 "누구세요?" "뭘 할 수 있나요?" 목적 신원 확인 권한 확인 예시 로그인 관리자 페이지 접근 시점 먼저 나중에 흐름:
`사용자 → [인증] 로그인 → [인가] 권한 확인 → 리소스 접근
`
19.1~19.4 Language, Runtime, Package Manager, Tools
Security 영역에서는 별도의 언어, 런타임, 패키지 관리자, 도구를 사용하지 않습니다. 기존 스택(TypeScript, Node.js)을 그대로 활용하며, Supabase Auth가 대부분의 기능을 제공합니다.
19.5 Library (라이브러리)
Supabase Auth
Supabase에 내장된 인증 시스템입니다.
지원하는 인증 방식:
- 이메일/비밀번호
- 매직 링크 (비밀번호 없이 이메일로 로그인)
- 소셜 로그인 (Google, GitHub, Kakao 등)
- 전화번호 (SMS)
이메일/비밀번호 인증
회원가입:
`typescriptconst { data, error } = await supabase.auth.signUp({
email: 'user@example.com',
password: 'securePassword123',
});
`로그인:
`typescriptconst { data, error } = await supabase.auth.signInWithPassword({
email: 'user@example.com',
password: 'securePassword123',
});
`로그아웃:
`typescriptconst { error } = await supabase.auth.signOut();
`현재 사용자 확인:
`typescriptconst { data: { user } } = await supabase.auth.getUser();
if (user) {
console.log('로그인됨:', user.email);
} else {
console.log('로그인 안 됨');
}
`세션 관리
Supabase Auth는 JWT(JSON Web Token) 기반으로 세션을 관리합니다.
`typescript// 세션 확인
const { data: { session } } = await supabase.auth.getSession();
// 세션 토큰
const accessToken = session?.access_token;
// 세션 갱신
const { data, error } = await supabase.auth.refreshSession();
`JWT 구조:
`header.payload.signature
예시:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwiZW1haWwiOiJ1c2VyQGV4YW1wbGUuY29tIn0.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
`
19.6 Framework (프레임워크)
Security 영역에서는 별도의 프레임워크를 사용하지 않습니다. Supabase Auth가 프레임워크 역할을 합니다.
19.7 External Service (외부 서비스)
OAuth (Open Authorization)
타사 서비스를 통해 로그인하는 표준 프로토콜입니다.
흐름:
`- 사용자 → "Google로 로그인" 클릭
- 앱 → Google 인증 페이지로 리다이렉트
- 사용자 → Google에서 로그인 및 권한 승인
- Google → 앱으로 인증 코드 전달
- 앱 → 인증 코드로 토큰 교환
- 앱 → 로그인 완료
`Google OAuth
가장 널리 쓰이는 소셜 로그인입니다.
Supabase에서 Google 로그인:
`typescriptconst { data, error } = await supabase.auth.signInWithOAuth({
provider: 'google',
options: {
redirectTo: 'https://yourapp.com/auth/callback',
},
});
`설정 필요:
- Google Cloud Console에서 OAuth 클라이언트 생성
- Supabase Dashboard에서 Google Provider 활성화
- Client ID, Client Secret 입력
Kakao OAuth
한국에서 많이 사용하는 소셜 로그인입니다.
Supabase에서 Kakao 로그인:
`typescriptconst { data, error } = await supabase.auth.signInWithOAuth({
provider: 'kakao',
options: {
redirectTo: 'https://yourapp.com/auth/callback',
},
});
`설정 필요:
- Kakao Developers에서 앱 생성
- Supabase Dashboard에서 Kakao Provider 활성화
- REST API 키, Client Secret 입력
SSALWorks: Google OAuth와 Kakao OAuth를 지원합니다.
보안 모범 사례
1. 비밀번호 보안
`typescript// ❌ 절대 안 됨: 평문 저장
const password = 'mypassword123';
db.insert({ password: password });
// ✅ Supabase Auth 사용 (자동으로 해싱)
await supabase.auth.signUp({
email: 'user@example.com',
password: 'mypassword123', // 자동으로 bcrypt 해싱됨
});
`2. HTTPS 필수
`❌ http://yourapp.com → 데이터 노출 위험
✅ https://yourapp.com → 암호화된 통신
`Vercel, Supabase 모두 HTTPS를 기본 제공합니다.
3. 환경 변수 관리
`typescript// ❌ 절대 안 됨: 코드에 키 노출
const supabase = createClient(
'https://xxx.supabase.co',
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' // 노출!
);
// ✅ 환경 변수 사용
const supabase = createClient(
process.env.SUPABASE_URL!,
process.env.SUPABASE_ANON_KEY!
);
`4. RLS (Row Level Security)
데이터베이스 수준에서 접근 제어합니다.
`sql-- 본인 데이터만 조회 가능
CREATE POLICY "Users can view own data"
ON profiles FOR SELECT
USING (auth.uid() = user_id);
-- 본인 데이터만 수정 가능
CREATE POLICY "Users can update own data"
ON profiles FOR UPDATE
USING (auth.uid() = user_id);
`5. 입력값 검증
`typescriptimport { z } from 'zod';
const LoginSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
});
// 검증 후 사용
const result = LoginSchema.safeParse(input);
if (!result.success) {
throw new Error('Invalid input');
}
`
인증 흐름 예시
회원가입 흐름
`- 사용자: 이메일, 비밀번호 입력
- 프론트엔드: supabase.auth.signUp() 호출
- Supabase: 이메일 확인 메일 발송
- 사용자: 이메일 링크 클릭
- Supabase: 계정 활성화
- 프론트엔드: 로그인 완료, 대시보드 이동
`소셜 로그인 흐름
`- 사용자: "Google로 로그인" 클릭
- 프론트엔드: supabase.auth.signInWithOAuth() 호출
- 브라우저: Google 로그인 페이지로 이동
- 사용자: Google 계정으로 로그인
- Google: 앱으로 리다이렉트
- Supabase: 사용자 정보 저장, 세션 생성
- 프론트엔드: 로그인 완료, 대시보드 이동
`
정리
기술 스택 SSALWorks 선택 Language - Runtime - Package Manager - Tools - Library **Supabase Auth** Framework - External Service **Google OAuth**, **Kakao OAuth** Security는 애플리케이션의 방패입니다. 다음 편에서는 코드 품질을 검증하는 Testing을 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 5,100자 / 작성자: Claude / 프롬프터: 써니
2020편 | 개발 영역 - Testing (테스트)20편 | 개발 영역 - Testing (테스트)
코드가 제대로 작동하는지 검증하는 영역, Testing입니다. 버그를 사전에 발견하고, 리팩토링에 자신감을 갖게 해주는 안전망입니다.
테스트의 종류
테스트 피라미드
`△ E2E 테스트 (적음)
╱ ╲ - 실제 사용자 시나리오
╱ ╲ - 느리고 비용 높음
╱ ╲
╱ 통합 테스트 (중간)
╱ ╲ - 여러 모듈 연결
╱ ╲ - 중간 속도
╱ 단위 테스트 (많음)
╱ ╲ - 함수/컴포넌트 단위
━━━━━━━━━━━━━━━━━ - 빠르고 저렴
`종류 대상 속도 비용 단위 테스트 함수, 컴포넌트 빠름 낮음 통합 테스트 API, DB 연동 중간 중간 E2E 테스트 전체 시나리오 느림 높음
20.1 Language (언어)
JavaScript & TypeScript
테스트 코드도 동일한 언어로 작성합니다.
`typescript// 테스트 코드 예시
import { add } from './math';
test('1 + 2 = 3', () => {
expect(add(1, 2)).toBe(3);
});
`
20.2 Runtime (실행 환경)
Node.js
테스트는 Node.js 환경에서 실행됩니다.
`bashJest 실행
npm test
특정 파일만 테스트
npm test -- auth.test.ts
`
20.3 Package Manager (패키지 관리자)
npm
테스트 도구를 설치합니다.
`bashnpm install -D jest @types/jest ts-jest
npm install -D playwright @playwright/test
`package.json 스크립트:
`json{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:e2e": "playwright test"
}
}
`
20.4 Tools (도구)
Testing 영역에서는 별도의 도구를 사용하지 않습니다. Jest와 Playwright가 CLI 도구를 제공합니다.
20.5 Library (라이브러리)
Jest
JavaScript 테스트 프레임워크입니다.
설치:
`bashnpm install -D jest @types/jest ts-jest
`설정 (jest.config.js):
`javascriptmodule.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['*/.test.ts'],
};
`기본 문법:
`typescript// describe: 테스트 그룹
describe('Math functions', () => {
// test 또는 it: 개별 테스트
test('add function works', () => {
expect(add(1, 2)).toBe(3);
});
it('subtract function works', () => {
expect(subtract(5, 3)).toBe(2);
});
});
`매처(Matcher):
`typescript// 값 비교
expect(value).toBe(3); // 정확히 같음
expect(value).toEqual({ a: 1 }); // 객체 내용 같음
expect(value).not.toBe(5); // 같지 않음
// 타입 확인
expect(value).toBeNull();
expect(value).toBeDefined();
expect(value).toBeTruthy();
// 숫자
expect(value).toBeGreaterThan(3);
expect(value).toBeLessThan(10);
// 문자열
expect(str).toMatch(/hello/);
// 배열
expect(array).toContain('item');
// 에러
expect(() => func()).toThrow();
expect(() => func()).toThrow('error message');
`비동기 테스트:
`typescript// async/await
test('fetches user data', async () => {
const user = await fetchUser(1);
expect(user.name).toBe('홍길동');
});
// Promise
test('fetches user data', () => {
return fetchUser(1).then(user => {
expect(user.name).toBe('홍길동');
});
});
`Mock:
`typescript// 함수 모킹
const mockFn = jest.fn();
mockFn.mockReturnValue(42);
expect(mockFn()).toBe(42);
// 모듈 모킹
jest.mock('./api', () => ({
fetchUser: jest.fn().mockResolvedValue({ name: '홍길동' }),
}));
`Playwright
E2E(End-to-End) 테스트 도구입니다.
설치:
`bashnpm install -D @playwright/test
npx playwright install # 브라우저 설치
`설정 (playwright.config.ts):
`typescriptimport { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './e2e',
use: {
baseURL: 'http://localhost:3000',
},
});
`테스트 작성:
`typescriptimport { test, expect } from '@playwright/test';
test('로그인 페이지 테스트', async ({ page }) => {
// 페이지 이동
await page.goto('/login');
// 요소 찾기 및 입력
await page.fill('input[name="email"]', 'user@example.com');
await page.fill('input[name="password"]', 'password123');
// 버튼 클릭
await page.click('button[type="submit"]');
// 결과 확인
await expect(page).toHaveURL('/dashboard');
await expect(page.locator('h1')).toContainText('대시보드');
});
`주요 기능:
`typescript// 페이지 이동
await page.goto('/about');
// 요소 찾기
const button = page.locator('button');
const input = page.locator('input[name="email"]');
const text = page.locator('text=로그인');
// 액션
await button.click();
await input.fill('hello');
await page.keyboard.press('Enter');
// 대기
await page.waitForURL('/dashboard');
await page.waitForSelector('.loading', { state: 'hidden' });
// 스크린샷
await page.screenshot({ path: 'screenshot.png' });
`SSALWorks: Jest(단위/통합)와 Playwright(E2E)를 사용합니다.
20.6 Framework (프레임워크)
Testing 영역에서는 별도의 프레임워크를 사용하지 않습니다. Jest와 Playwright가 프레임워크 역할을 합니다.
20.7 External Service (외부 서비스)
Testing 영역에서는 별도의 외부 서비스를 사용하지 않습니다.
테스트 작성 모범 사례
1. AAA 패턴
`typescripttest('사용자 생성', async () => {
// Arrange (준비)
const userData = { name: '홍길동', email: 'hong@example.com' };
// Act (실행)
const user = await createUser(userData);
// Assert (검증)
expect(user.name).toBe('홍길동');
expect(user.id).toBeDefined();
});
`2. 명확한 테스트 이름
`typescript// ❌ 나쁜 예
test('test1', () => { ... });
// ✅ 좋은 예
test('이메일 형식이 올바르지 않으면 에러를 반환한다', () => { ... });
`3. 독립적인 테스트
`typescript// ❌ 나쁜 예: 다른 테스트에 의존
let user;
test('사용자 생성', () => { user = createUser(); });
test('사용자 조회', () => { getUser(user.id); }); // 첫 번째 테스트에 의존!
// ✅ 좋은 예: 독립적
test('사용자 조회', () => {
const user = createUser(); // 각 테스트에서 직접 생성
const result = getUser(user.id);
expect(result).toBeDefined();
});
`
정리
기술 스택 SSALWorks 선택 Language JavaScript, **TypeScript** Runtime **Node.js** Package Manager **npm** Tools - Library **Jest**, **Playwright** Framework - External Service - Testing은 코드의 안전망입니다. 다음 편에서는 배포와 운영을 담당하는 DevOps를 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 5,000자 / 작성자: Claude / 프롬프터: 써니
2121편 | 개발 영역 - DevOps (데브옵스)21편 | 개발 영역 - DevOps (데브옵스)
개발(Development)과 운영(Operations)을 연결하는 영역, DevOps입니다. 코드를 서버에 배포하고, 자동화하고, 모니터링하는 모든 활동을 다룹니다.
DevOps의 핵심
CI/CD 파이프라인
`[개발] → [커밋] → [빌드] → [테스트] → [배포] → [모니터링]
└─────────── 자동화 ───────────┘
`용어 의미 예시 CI Continuous Integration (지속적 통합) 커밋마다 자동 빌드/테스트 CD Continuous Deployment (지속적 배포) 테스트 통과 시 자동 배포
21.1 Language (언어)
YAML
설정 파일 작성에 사용하는 언어입니다.
`yamlGitHub Actions 예시
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
`특징:
- 들여쓰기로 구조 표현
- JSON보다 읽기 쉬움
- 주석 지원 (
#)
Bash
쉘 스크립트 작성에 사용합니다.
`bash#!/bin/bash
빌드 스크립트
echo "Building..."
npm run build
배포
echo "Deploying..."
vercel --prod
`
21.2~21.3 Runtime, Package Manager
DevOps 영역에서는 별도의 런타임이나 패키지 관리자를 사용하지 않습니다.
21.4 Tools (도구)
Git
분산 버전 관리 시스템입니다.
기본 명령어:
`bash저장소 초기화
git init
변경사항 추적
git add .
git commit -m "feat: 로그인 기능 추가"
원격 저장소
git push origin main
git pull origin main
브랜치
git checkout -b feature/login
git merge feature/login
`커밋 메시지 규칙:
`feat: 새 기능 추가
fix: 버그 수정
docs: 문서 수정
style: 코드 포맷팅
refactor: 리팩토링
test: 테스트 추가
chore: 기타 변경
`GitHub
Git 저장소 호스팅 서비스입니다.
주요 기능:
- 코드 저장소
- Pull Request (코드 리뷰)
- Issues (이슈 관리)
- Actions (CI/CD)
- Pages (정적 사이트 호스팅)
Vercel CLI
Vercel 배포를 위한 CLI 도구입니다.
설치:
`bashnpm install -g vercel
`사용법:
`bash로그인
vercel login
배포 (프리뷰)
vercel
프로덕션 배포
vercel --prod
환경 변수 설정
vercel env add SUPABASE_URL
`
21.5~21.6 Library, Framework
DevOps 영역에서는 별도의 라이브러리나 프레임워크를 사용하지 않습니다.
21.7 External Service (외부 서비스)
Vercel (PaaS - Platform as a Service)
Next.js를 만든 회사의 호스팅 서비스입니다.
특징:
- Next.js 완벽 지원
- Git 연동 자동 배포
- 서버리스 함수
- Edge 네트워크 (CDN)
- 무료 HTTPS
배포 방법:
방법 1: Git 연동 (권장)
`- GitHub에 코드 푸시
- Vercel에서 저장소 연결
- 자동 배포 완료
`방법 2: CLI 배포
`bashvercel --prod
`환경 변수 설정:
`Vercel Dashboard → Project → Settings → Environment Variables
SUPABASE_URL=https://xxx.supabase.co
SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIs...
`도메인 연결:
`Vercel Dashboard → Project → Settings → Domains
yourapp.com → Vercel DNS 설정
`무료 플랜:
- 무제한 사이트
- 100GB 대역폭/월
- 서버리스 함수 100GB-hours
- 자동 HTTPS
GitHub Actions
GitHub에서 제공하는 CI/CD 서비스입니다.
워크플로우 파일 위치:
`.github/
└── workflows/
├── ci.yml # CI 파이프라인
└── deploy.yml # 배포 파이프라인
`CI 워크플로우 예시:
`yaml.github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint
- name: Run tests
run: npm test
- name: Build
run: npm run build
`주요 개념:
개념 설명 Workflow 자동화 프로세스 전체 Job 워크플로우 내 작업 단위 Step Job 내 개별 단계 Action 재사용 가능한 작업 Runner 워크플로우 실행 환경 SSALWorks: Vercel + GitHub Actions를 사용합니다.
배포 전략
1. 브랜치 전략
`main (프로덕션)
↑
develop (개발)
↑
feature/xxx (기능 개발)
`2. 환경 분리
환경 용도 URL Production 실제 서비스 yourapp.com Preview PR 미리보기 xxx.vercel.app Development 로컬 개발 localhost:3000 3. 롤백
문제 발생 시 이전 버전으로 되돌립니다.
`bashVercel: 이전 배포로 롤백
vercel rollback
Git: 이전 커밋으로 되돌리기
git revert HEAD
git push
`
모니터링
Vercel Analytics
`Vercel Dashboard → Project → Analytics
- 방문자 수
- 페이지 조회수
- Core Web Vitals
`로그 확인
`Vercel Dashboard → Project → Logs
- 함수 실행 로그
- 에러 로그
- 빌드 로그
`
정리
기술 스택 SSALWorks 선택 Language **YAML**, Bash Runtime - Package Manager - Tools **Git**, **GitHub**, **Vercel CLI** Library - Framework - External Service **Vercel (PaaS)**, **GitHub Actions** DevOps는 개발과 운영의 다리입니다. 다음 편에서는 SEO와 웹 접근성을 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 5,000자 / 작성자: Claude / 프롬프터: 써니
2222편 | 최적화 - SEO (검색 엔진 최적화)22편 | 최적화 - SEO (검색 엔진 최적화)
검색 엔진에서 찾기 쉬운 웹사이트를 만드는 기술, SEO(Search Engine Optimization)입니다. 구글, 네이버 등에서 검색 순위를 높이는 방법을 다룹니다.
SEO의 핵심
검색 엔진이 보는 것
`[사용자] → 검색어 입력 → [검색 엔진] → 웹사이트 순위 결정
↓
- 메타 태그
- 콘텐츠 품질
- 페이지 속도
- 모바일 최적화
`요소 설명 중요도 콘텐츠 유용하고 고유한 내용 매우 높음 메타 태그 제목, 설명, 키워드 높음 페이지 속도 로딩 시간 높음 모바일 대응 반응형 디자인 높음 HTTPS 보안 연결 중간
22.1 Language (언어)
HTML (시맨틱 태그)
시맨틱 태그는 의미를 가진 HTML 태그입니다. 검색 엔진이 콘텐츠 구조를 이해하는 데 도움됩니다.
`html......사이트 헤더 글 제목
본문 섹션 `주요 시맨틱 태그:
태그 용도 ` ` 페이지/섹션 헤더 ` 네비게이션 ` ` 주요 콘텐츠 ` ` 독립적인 콘텐츠 ` ` 콘텐츠 섹션 ` 사이드바 ` 페이지/섹션 푸터 메타 태그
`htmlSSALWorks - AI 기반 학습 플랫폼 `
22.2~22.3 Runtime, Package Manager
SEO 영역에서는 별도의 런타임이나 패키지 관리자를 사용하지 않습니다.
22.4 Tools (도구)
Lighthouse
Chrome DevTools에 내장된 웹 품질 측정 도구입니다.
사용법:
`- Chrome DevTools 열기 (F12)
- Lighthouse 탭 선택
- "Analyze page load" 클릭
`측정 항목:
항목 설명 목표 점수 Performance 로딩 속도 90+ Accessibility 접근성 90+ Best Practices 모범 사례 90+ SEO 검색 최적화 90+ PageSpeed Insights
Google의 웹 성능 분석 서비스입니다.
사용법:
`- https://pagespeed.web.dev/ 접속
- URL 입력
- 분석 결과 확인
`SSALWorks: Lighthouse + PageSpeed Insights를 사용합니다.
22.5 Library (라이브러리)
next-seo
Next.js용 SEO 라이브러리입니다.
설치:
`bashnpm install next-seo
`사용법:
`tsx// app/layout.tsx
import { DefaultSeo } from 'next-seo';
export default function RootLayout({ children }) {
return (
title="SSALWorks"
description="AI 기반 학습 플랫폼"
openGraph={{
type: 'website',
locale: 'ko_KR',
url: 'https://ssalworks.com',
siteName: 'SSALWorks',
}}
/>
{children});
}
`페이지별 SEO:
`tsx// app/about/page.tsx
import { NextSeo } from 'next-seo';
export default function AboutPage() {
return (
<>
title="소개 | SSALWorks"
description="SSALWorks 서비스를 소개합니다"
/>
... >
);
}
`
22.6 Framework (프레임워크)
Next.js (SEO 기능)
Next.js는 SEO에 최적화된 기능을 제공합니다.
Metadata API:
`tsx// app/page.tsx
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'SSALWorks - 홈',
description: 'AI 기반 학습 플랫폼',
keywords: ['AI', '학습', '교육'],
openGraph: {
title: 'SSALWorks',
description: 'AI와 함께 성장하는 학습 플랫폼',
images: ['/og-image.png'],
},
};
export default function HomePage() {
return
... ;}
`동적 메타데이터:
`tsx// app/posts/[id]/page.tsx
export async function generateMetadata({ params }) {
const post = await getPost(params.id);
return {
title: post.title,
description: post.excerpt,
openGraph: {
title: post.title,
images: [post.thumbnail],
},
};
}
`sitemap.xml 생성:
`tsx// app/sitemap.ts
export default async function sitemap() {
const posts = await getAllPosts();
return [
{ url: 'https://ssalworks.com', lastModified: new Date() },
{ url: 'https://ssalworks.com/about', lastModified: new Date() },
...posts.map(post => ({
url:
https://ssalworks.com/posts/${post.id},lastModified: post.updatedAt,
})),
];
}
`SSALWorks: Next.js Metadata API를 사용합니다.
22.7 External Service (외부 서비스)
Google Search Console
Google 검색 성능을 모니터링하는 서비스입니다.
주요 기능:
- 검색 노출 현황 확인
- 클릭률(CTR) 분석
- 색인 상태 확인
- 사이트맵 제출
설정 방법:
`- https://search.google.com/search-console 접속
- 속성 추가 (도메인 또는 URL)
- 소유권 확인 (DNS 또는 HTML 태그)
- sitemap.xml 제출
`Naver Search Advisor
네이버 검색 최적화 서비스입니다.
설정 방법:
`- https://searchadvisor.naver.com 접속
- 사이트 등록
- 소유권 확인
- 사이트맵 제출
`SSALWorks: Google Search Console + Naver Search Advisor를 사용합니다.
SEO 체크리스트
기술적 SEO
- [ ] 시맨틱 HTML 태그 사용
- [ ] 메타 태그 (title, description) 설정
- [ ] Open Graph 태그 설정
- [ ] sitemap.xml 생성
- [ ] robots.txt 설정
- [ ] HTTPS 사용
- [ ] 모바일 반응형 디자인
콘텐츠 SEO
- [ ] 고유하고 유용한 콘텐츠
- [ ] 적절한 헤딩 구조 (h1 → h2 → h3)
- [ ] 이미지 alt 텍스트
- [ ] 내부 링크 구조
- [ ] 페이지 로딩 속도
정리
기술 스택 SSALWorks 선택 Language **HTML (시맨틱 태그)**, 메타 태그 Runtime - Package Manager - Tools **Lighthouse**, **PageSpeed Insights** Library **next-seo** Framework **Next.js (Metadata API)** External Service **Google Search Console**, **Naver Search Advisor** SEO는 검색에서 발견되기 위한 필수 기술입니다. 다음 편에서는 모든 사용자를 위한 웹 접근성을 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 4,800자 / 작성자: Claude / 프롬프터: 써니
2323편 | 최적화 - 웹 접근성 (WCAG)23편 | 최적화 - 웹 접근성 (WCAG)
장애인을 포함한 모든 사용자가 사용할 수 있는 웹사이트를 만드는 기술, 웹 접근성입니다. 시각, 청각, 운동 장애가 있는 사용자도 웹을 이용할 수 있도록 배려합니다.
웹 접근성이란?
접근성이 필요한 사용자
유형 예시 필요한 배려 시각 장애 전맹, 저시력, 색맹 스크린 리더, 고대비 청각 장애 농인, 난청 자막, 텍스트 대안 운동 장애 손 사용 어려움 키보드 네비게이션 인지 장애 난독증, ADHD 단순한 구조, 명확한 언어 고령자 노안, 반응 속도 저하 큰 글씨, 충분한 클릭 영역 WCAG 4대 원칙 (POUR)
`P - Perceivable (인식 가능)
O - Operable (운용 가능)
U - Understandable (이해 가능)
R - Robust (견고함)
`원칙 의미 예시 인식 가능 정보를 감각으로 인식할 수 있어야 함 이미지 대체 텍스트 운용 가능 인터페이스를 조작할 수 있어야 함 키보드 네비게이션 이해 가능 내용을 이해할 수 있어야 함 명확한 레이블 견고함 다양한 기술에서 작동해야 함 표준 HTML 사용
23.1 Language (언어)
HTML (접근성 속성)
이미지 대체 텍스트:
`html


`폼 접근성:
`htmltype="password"
id="password"
aria-describedby="password-error"
>
비밀번호는 8자 이상이어야 합니다
`ARIA 속성:
`html... 메뉴 열기
새 알림이 도착했습니다
`
23.2~23.3 Runtime, Package Manager
웹 접근성 영역에서는 별도의 런타임이나 패키지 관리자를 사용하지 않습니다.
23.4 Tools (도구)
WAVE
웹 접근성 평가 도구입니다.
사용법:
`- https://wave.webaim.org/ 접속
- URL 입력
- 접근성 문제 확인
`또는 브라우저 확장 프로그램:
- Chrome: WAVE Evaluation Tool
- Firefox: WAVE Toolbar
axe DevTools
Chrome 확장 프로그램으로, 접근성 자동 테스트를 제공합니다.
설치:
`- Chrome 웹 스토어에서 "axe DevTools" 검색
- 확장 프로그램 설치
- DevTools에서 axe 탭 확인
`Lighthouse (접근성 탭)
`- Chrome DevTools 열기 (F12)
- Lighthouse 탭 선택
- "Accessibility" 체크
- "Analyze page load" 클릭
`SSALWorks: WAVE + axe DevTools + Lighthouse를 사용합니다.
23.5 Library (라이브러리)
React Aria
Adobe가 만든 접근성 라이브러리입니다.
설치:
`bashnpm install react-aria
`버튼 예시:
`tsximport { useButton } from 'react-aria';
import { useRef } from 'react';
function AccessibleButton(props) {
const ref = useRef();
const { buttonProps } = useButton(props, ref);
return (
{props.children}
);
}
`Radix UI
접근성이 내장된 UI 컴포넌트 라이브러리입니다.
설치:
`bashnpm install @radix-ui/react-dialog
`Dialog 예시:
`tsximport * as Dialog from '@radix-ui/react-dialog';
function AccessibleDialog() {
return (
열기 제목 설명 닫기 );
}
`SSALWorks: Radix UI를 사용합니다.
23.6 Framework (프레임워크)
웹 접근성 영역에서는 별도의 프레임워크를 사용하지 않습니다. React/Next.js에서 접근성 라이브러리를 활용합니다.
23.7 External Service (외부 서비스)
웹 접근성 영역에서는 별도의 외부 서비스를 사용하지 않습니다. 도구(WAVE, axe)로 충분합니다.
접근성 구현 가이드
1. 색상 대비
`css/ 4.5:1 이상의 대비율 필요 (일반 텍스트) /
/ 3:1 이상의 대비율 필요 (큰 텍스트) /
.text {
color: #333; / 충분한 대비 /
background: #fff;
}
/ 색상만으로 정보 전달 금지 /
.error {
color: red; / 색상 /
border-left: 3px solid red; / + 시각적 단서 /
}
.error::before {
content: "⚠️ "; / + 아이콘 /
}
`2. 키보드 접근성
`css/ focus 스타일 절대 제거 금지! /
button:focus {
outline: 2px solid #007bff;
outline-offset: 2px;
}
/ :focus-visible로 마우스/키보드 구분 /
button:focus-visible {
outline: 2px solid #007bff;
}
``html... 포커스 가능한 영역에러 메시지본문으로 건너뛰기
`3. 스크린 리더 지원
`html장바구니에 3개의 상품이 있습니다
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
좋아요
`4. 충분한 클릭/터치 영역
`css/ 최소 44x44px (모바일 터치 기준) /
button, a {
min-width: 44px;
min-height: 44px;
padding: 12px 16px;
}
`
접근성 체크리스트
인식 가능
- [ ] 이미지에 alt 텍스트 제공
- [ ] 색상 대비 4.5:1 이상
- [ ] 색상 외 추가 단서 제공
- [ ] 비디오에 자막 제공
운용 가능
- [ ] 키보드로 모든 기능 사용 가능
- [ ] 포커스 표시 유지
- [ ] 충분한 클릭 영역 (44px 이상)
- [ ] Skip Link 제공
이해 가능
- [ ] label과 input 연결
- [ ] 에러 메시지 명확
- [ ] 일관된 네비게이션
- [ ] 명확한 언어 사용
견고함
- [ ] 유효한 HTML
- [ ] ARIA 올바르게 사용
- [ ] 다양한 브라우저에서 테스트
정리
기술 스택 SSALWorks 선택 Language **HTML (ARIA 속성)** Runtime - Package Manager - Tools **WAVE**, **axe DevTools**, **Lighthouse** Library **Radix UI** Framework - External Service - 웹 접근성은 모든 사용자를 위한 배려입니다. 다음 편에서는 성능 최적화를 알아봅니다.
작성일: 2025-12-21 / 글자수: 약 5,200자 / 작성자: Claude / 프롬프터: 써니
2424편 | 최적화 - 성능 (Performance)24편 | 최적화 - 성능 (Performance)
웹사이트를 빠르게 만드는 기술, 성능 최적화입니다. 사용자 경험을 향상시키고, 검색 순위에도 영향을 미치는 중요한 영역입니다.
성능의 핵심 지표
Core Web Vitals
Google이 정의한 웹 성능 핵심 지표입니다.
지표 의미 목표 측정 대상 **LCP** Largest Contentful Paint < 2.5초 가장 큰 콘텐츠 로딩 **FID** First Input Delay < 100ms 첫 상호작용 응답 **CLS** Cumulative Layout Shift < 0.1 레이아웃 밀림 `[페이지 로드 타임라인]
0s ─── FCP ─── LCP ─── TTI ─── 완료
│ │ │
│ │ └─ Time to Interactive (상호작용 가능)
│ └─ 가장 큰 콘텐츠 로딩
└─ First Contentful Paint (첫 콘텐츠)
`
24.1 Language (언어)
JavaScript 최적화
`javascript// 나쁜 예: 동기 로딩 (렌더링 차단)
// 좋은 예: 비동기 로딩
`defer vs async:
속성 실행 시점 순서 보장 용도 `defer` DOM 파싱 후 보장됨 일반 스크립트 `async` 다운로드 완료 즉시 보장 안 됨 독립 스크립트 CSS 최적화
`css/ 나쁜 예: 불필요하게 깊은 선택자 /
div.container > ul.list > li.item > a.link { }
/ 좋은 예: 단순한 선택자 /
.link { }
`Critical CSS:
`html/ 첫 화면에 필요한 스타일만 /
.hero { background: #007bff; }
`
24.2 Runtime (실행 환경)
Edge Runtime
CDN 엣지에서 실행되어 지연 시간을 최소화합니다.
`typescript// Edge에서 실행
export const runtime = 'edge';
export async function GET() {
// 사용자와 가까운 서버에서 응답
return Response.json({ message: 'Fast!' });
}
`Node.js vs Edge:
항목 Node.js Edge 콜드 스타트 ~500ms ~50ms 실행 위치 특정 리전 전 세계 CDN 적합한 용도 복잡한 로직 간단한 API
24.3 Package Manager (패키지 관리자)
npm (번들 분석)
`bash번들 크기 분석 도구 설치
npm install -D @next/bundle-analyzer
`next.config.js:
`javascriptconst withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
});
module.exports = withBundleAnalyzer({
// Next.js 설정
});
`분석 실행:
`bashANALYZE=true npm run build
`
24.4 Tools (도구)
Chrome DevTools
Performance 탭:
- 페이지 로딩 프로파일링
- JavaScript 실행 시간 분석
- 렌더링 병목 지점 확인
Network 탭:
- 리소스 로딩 순서 확인
- 파일 크기 확인
- 캐싱 상태 확인
PageSpeed Insights
Google의 웹 성능 분석 서비스입니다.
사용법:
`- https://pagespeed.web.dev/ 접속
- URL 입력
- 분석 결과 확인
`결과 항목:
- Core Web Vitals 점수
- 개선 제안
- 진단 정보
SSALWorks: PageSpeed Insights + Chrome DevTools를 사용합니다.
24.5 Library (라이브러리)
next/image
이미지 자동 최적화 컴포넌트입니다.
`tsximport Image from 'next/image';
export default function Hero() {
return (
src="/hero.jpg"
alt="히어로 이미지"
width={1200}
height={600}
priority // LCP 이미지
placeholder="blur" // 블러 효과
/>
);
}
`자동 최적화:
- WebP/AVIF 변환
- 반응형 이미지 생성
- Lazy loading
- 이미지 크기 최적화
next/font
폰트 자동 최적화입니다.
`tsximport { Noto_Sans_KR } from 'next/font/google';
const notoSansKR = Noto_Sans_KR({
subsets: ['latin'],
weight: ['400', '700'],
display: 'swap', // FOUT 방지
});
export default function RootLayout({ children }) {
return (
{children});
}
`장점:
- 폰트 셀프 호스팅
- 레이아웃 시프트 방지
- 서브셋 자동 생성
24.6 Framework (프레임워크)
Next.js (성능 기능)
자동 코드 분할:
`tsx// 자동으로 페이지별 번들 생성
// app/page.tsx → 별도 청크
// app/about/page.tsx → 별도 청크
`동적 임포트:
`tsximport dynamic from 'next/dynamic';
// 무거운 컴포넌트는 동적 로딩
const HeavyChart = dynamic(() => import('./HeavyChart'), {
loading: () =>
로딩 중...
,ssr: false, // 클라이언트에서만 렌더링
});
`정적 생성 (SSG):
`tsx// 빌드 시 HTML 미리 생성
export default async function Page() {
const data = await fetch('https://api.example.com/data');
return
{data};}
// 또는 명시적으로
export const dynamic = 'force-static';
`캐싱 전략:
`tsx// 데이터 캐싱
const data = await fetch('https://api.example.com/data', {
next: { revalidate: 3600 } // 1시간 캐시
});
// 캐시 안 함
const realtime = await fetch('https://api.example.com/realtime', {
cache: 'no-store'
});
`SSALWorks: Next.js의 모든 최적화 기능을 활용합니다.
24.7 External Service (외부 서비스)
Vercel (CDN + Edge)
전 세계 CDN으로 빠른 콘텐츠 전송을 제공합니다.
최적화 기능:
- 자동 이미지 최적화
- Edge 캐싱
- 압축 (Brotli, Gzip)
- HTTP/2, HTTP/3
캐싱 설정:
`javascript// next.config.js
module.exports = {
async headers() {
return [
{
source: '/static/:path*',
headers: [
{
key: 'Cache-Control',
value: 'public, max-age=31536000, immutable',
},
],
},
];
},
};
`Cloudflare (선택적)
추가 CDN 레이어로 사용할 수 있습니다.
주요 기능:
- DDoS 방어
- 이미지 최적화
- 캐싱
SSALWorks: Vercel CDN을 기본으로 사용합니다.
성능 최적화 체크리스트
이미지
- [ ] next/image 사용
- [ ] 적절한 크기 지정
- [ ] WebP/AVIF 포맷
- [ ] Lazy loading 적용
- [ ] priority 속성 (LCP 이미지)
JavaScript
- [ ] 번들 크기 분석
- [ ] 동적 임포트 활용
- [ ] Tree shaking 확인
- [ ] defer/async 사용
- [ ] 불필요한 라이브러리 제거
폰트
- [ ] next/font 사용
- [ ] 서브셋 적용
- [ ] display: swap 설정
- [ ] 필요한 굵기만 로드
캐싱
- [ ] 정적 리소스 캐싱
- [ ] API 응답 캐싱
- [ ] ISR/SSG 활용
- [ ] CDN 캐싱
렌더링
- [ ] SSG 우선 적용
- [ ] SSR은 필요한 경우만
- [ ] 클라이언트 컴포넌트 최소화
- [ ] Suspense 활용
정리
기술 스택 SSALWorks 선택 Language JavaScript 최적화, CSS 최적화 Runtime **Edge Runtime** Package Manager **npm** (bundle-analyzer) Tools **Chrome DevTools**, **PageSpeed Insights** Library **next/image**, **next/font** Framework **Next.js** (코드 분할, SSG, ISR) External Service **Vercel (CDN)** 성능 최적화는 사용자 경험의 핵심입니다. 다음은 부록: 용어 사전에서 전체 용어를 정리합니다.
작성일: 2025-12-21 / 글자수: 약 5,300자 / 작성자: Claude / 프롬프터: 써니
2525편 | 심화 - HTML25편 | 심화 - HTML
08편에서 HTML의 기본 개념을 소개했습니다. 이번 편에서는 HTML을 더 깊이 이해하고, 실제 웹페이지를 구성할 때 필요한 핵심 지식을 다룹니다.
1. HTML이란
1-1. 정의
HTML(HyperText Markup Language)은 웹페이지의 구조와 내용을 정의하는 마크업 언어입니다. 프로그래밍 언어가 아니라 문서 구조를 표현하는 언어입니다.
집을 짓는다면 HTML은 뼈대와 벽입니다. 방이 몇 개인지, 거실이 어디인지, 화장실이 어디인지를 정하는 역할입니다.
1-2. 작동 원리
`브라우저가 HTML 파일 다운로드
↓
HTML 코드를 해석 (파싱)
↓
DOM(Document Object Model) 생성
↓
화면에 렌더링
`브라우저는 HTML 코드를 위에서 아래로 순차적으로 읽으면서 화면을 그립니다.
2. HTML 기본 구조
2-1. 필수 구조
`html페이지 제목 `요소 역할 `` HTML5 문서임을 선언 `` 전체 문서의 루트 `` 메타 정보 (보이지 않음) `` 실제 화면에 보이는 내용 2-2. head 태그 필수 요소
`htmlSSALWorks - AI 개발 협업 플랫폼 `
3. 시맨틱 태그
3-1. 시맨틱 태그란
시맨틱(Semantic) 태그는 의미를 가진 태그입니다.
대신 용도에 맞는 태그를 사용하면 코드 가독성과 SEO가 좋아집니다.3-2. 주요 시맨틱 태그
`html`3-3. 올바른 구조 예시
`html글 제목
본문 내용...
관련 링크
© 2025 SSALWorks
`
4. 자주 쓰는 태그
4-1. 텍스트 관련
`html~
`4-2. 링크와 이미지
`html
`alt 속성은 이미지가 로드되지 않을 때, 스크린 리더가 읽을 때 사용됩니다. 반드시 작성하세요.
4-3. 목록
`html- 항목 1
- 항목 2
- 첫 번째
- 두 번째
`4-4. 테이블
`html이름 나이 홍길동 30 `
5. 폼(Form) 태그
5-1. 기본 구조
`html`5-2. input 타입
타입 용도 `text` 일반 텍스트 `email` 이메일 (형식 검증) `password` 비밀번호 (가려짐) `number` 숫자 `date` 날짜 선택 `checkbox` 체크박스 `radio` 라디오 버튼 `file` 파일 업로드 5-3. 폼 요소
`html`
6. 블록 vs 인라인
6-1. 블록 요소
한 줄을 전부 차지하는 요소입니다.
`html,,
~
,
- ,
- ,
, `6-2. 인라인 요소
내용만큼만 차지하는 요소입니다.
`html`6-3. 중요한 규칙
- 블록 요소 안에 인라인 요소 O
- 인라인 요소 안에 블록 요소 X (오류)
`html텍스트텍스트`
7. 속성(Attributes)
7-1. 전역 속성
모든 태그에서 사용 가능한 속성입니다.
`html`7-2. id vs class
속성 특징 사용 `id` 고유, 페이지당 1개 JavaScript에서 요소 선택 `class` 중복 가능, 여러 개 CSS 스타일 적용 `html`
8. 실전 예시: 로그인 페이지
`html로그인 - SSALWorks 로그인
또는Google로 로그인
계정이 없으신가요? 회원가입
`
정리
HTML은 웹페이지의 구조와 내용을 담당합니다.
핵심 포인트:
- 시맨틱 태그로 의미 있는 구조 작성
- form 태그로 사용자 입력 처리
- id는 고유, class는 스타일용
- alt, label 등 접근성 속성 필수
HTML만으로는 못생긴 페이지입니다. 다음 편에서 CSS로 스타일을 입힙니다.
작성일: 2025-12-21 / 작성자: Claude Code
2626편 | 심화 - CSS26편 | 심화 - CSS
25편에서 HTML로 웹페이지의 구조를 만들었습니다. 이번 편에서는 CSS를 사용해 스타일과 레이아웃을 적용하는 방법을 깊이 다룹니다.
1. CSS란
1-1. 정의
CSS(Cascading Style Sheets)는 웹페이지의 스타일을 정의하는 언어입니다.
집을 짓는다면 HTML이 뼈대라면, CSS는 인테리어입니다. 벽지 색깔, 가구 배치, 조명 등 외관을 꾸미는 역할입니다.
1-2. CSS 적용 방법
`htmlbody { color: black; }
텍스트`외부 파일 방식을 권장합니다. HTML과 CSS를 분리하면 유지보수가 쉽습니다.
2. 선택자(Selector)
2-1. 기본 선택자
`css/ 요소 선택자 /
p { color: blue; }
/ 클래스 선택자 /
.card { background: white; }
/ ID 선택자 /
#header { height: 60px; }
/ 전체 선택자 /
- { margin: 0; padding: 0; }
`2-2. 조합 선택자
`css/ 자손 선택자 (하위 모든 요소) /
nav a { color: white; }
/ 자식 선택자 (직접 자식만) /
ul > li { list-style: none; }
/ 여러 선택자 동시 적용 /
h1, h2, h3 { font-weight: bold; }
/ 클래스 조합 /
.btn.primary { background: blue; }
`2-3. 가상 클래스
`css/ 마우스 오버 /
button:hover { background: darkblue; }
/ 클릭 시 /
button:active { transform: scale(0.98); }
/ 포커스 /
input:focus { border-color: blue; }
/ 첫 번째/마지막 자식 /
li:first-child { font-weight: bold; }
li:last-child { border-bottom: none; }
/ n번째 자식 /
tr:nth-child(even) { background: #f5f5f5; }
`
3. 박스 모델
3-1. 구성 요소
모든 HTML 요소는 박스로 이루어져 있습니다.
`┌─────────────────────────────┐
│ margin │ ← 요소 바깥 여백
│ ┌──────────────────────┐ │
│ │ border │ │ ← 테두리
│ │ ┌───────────────┐ │ │
│ │ │ padding │ │ │ ← 요소 안쪽 여백
│ │ │ ┌─────────┐ │ │ │
│ │ │ │ content │ │ │ │ ← 실제 내용
│ │ │ └─────────┘ │ │ │
│ │ └───────────────┘ │ │
│ └──────────────────────┘ │
└─────────────────────────────┘
`3-2. 속성
`css.box {
/ 내용 크기 /
width: 300px;
height: 200px;
/ 안쪽 여백 /
padding: 20px;
padding: 10px 20px; / 상하 10, 좌우 20 /
padding: 10px 20px 30px 40px; / 상 우 하 좌 /
/ 테두리 /
border: 1px solid #ccc;
border-radius: 8px; / 둥근 모서리 /
/ 바깥 여백 /
margin: 20px;
margin: 0 auto; / 가로 중앙 정렬 /
}
`3-3. box-sizing
`css/ 기본값: width = content만 /
box-sizing: content-box;
/ 권장: width = content + padding + border /
box-sizing: border-box;
/ 전체 요소에 적용 (권장) /
, ::before, *::after {
box-sizing: border-box;
}
`
4. Flexbox
4-1. 기본 개념
Flexbox는 1차원 레이아웃 시스템입니다. 가로 또는 세로 방향으로 요소를 배치합니다.
`css.container {
display: flex; / Flexbox 활성화 /
}
`4-2. 주요 속성
`css.container {
display: flex;
/ 방향 /
flex-direction: row; / 가로 (기본) /
flex-direction: column; / 세로 /
/ 주축 정렬 /
justify-content: flex-start; / 시작 /
justify-content: center; / 중앙 /
justify-content: flex-end; / 끝 /
justify-content: space-between;/ 양끝 + 균등 /
justify-content: space-around; / 균등 (양쪽 여백) /
/ 교차축 정렬 /
align-items: stretch; / 늘리기 (기본) /
align-items: flex-start; / 시작 /
align-items: center; / 중앙 /
align-items: flex-end; / 끝 /
/ 줄바꿈 /
flex-wrap: nowrap; / 안 함 (기본) /
flex-wrap: wrap; / 줄바꿈 /
/ 간격 /
gap: 20px;
}
`4-3. 자식 요소 속성
`css.item {
flex: 1; / 남은 공간 균등 분배 /
flex: 2; / 다른 요소보다 2배 /
flex-shrink: 0; / 줄어들지 않음 /
align-self: center; / 개별 정렬 /
}
`4-4. 실전 예시: 가운데 정렬
`css/ 완벽한 가운데 정렬 /
.center {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
`
5. Grid
5-1. 기본 개념
Grid는 2차원 레이아웃 시스템입니다. 행과 열을 동시에 다룹니다.
`css.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr; / 3열 균등 /
grid-template-rows: auto auto; / 2행 /
gap: 20px;
}
`5-2. 열 정의
`css.container {
/ 고정 크기 /
grid-template-columns: 200px 200px 200px;
/ 비율 /
grid-template-columns: 1fr 2fr 1fr;
/ 반복 /
grid-template-columns: repeat(3, 1fr);
/ 최소/최대 /
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}
`5-3. 실전 예시: 카드 그리드
`css.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
padding: 24px;
}
`
6. 반응형 디자인
6-1. 미디어 쿼리
`css/ 기본 스타일 (모바일 우선) /
.container {
width: 100%;
padding: 16px;
}
/ 태블릿 (768px 이상) /
@media (min-width: 768px) {
.container {
max-width: 720px;
margin: 0 auto;
}
}
/ 데스크톱 (1024px 이상) /
@media (min-width: 1024px) {
.container {
max-width: 960px;
}
}
`6-2. 반응형 단위
단위 설명 사용 `px` 고정 픽셀 작은 요소 `%` 부모 기준 비율 너비 `vw/vh` 뷰포트 기준 전체 화면 `rem` 루트 폰트 크기 기준 폰트, 여백 `em` 부모 폰트 크기 기준 폰트 `csshtml { font-size: 16px; }
.text {
font-size: 1rem; / 16px /
font-size: 1.5rem; / 24px /
}
.full-screen {
width: 100vw;
height: 100vh;
}
`
7. 색상과 배경
7-1. 색상 표현
`css.element {
/ 이름 /
color: red;
/ HEX /
color: #ff0000;
color: #f00; / 축약 /
/ RGB /
color: rgb(255, 0, 0);
/ RGBA (투명도) /
color: rgba(255, 0, 0, 0.5);
/ HSL /
color: hsl(0, 100%, 50%);
}
`7-2. 배경
`css.element {
background-color: #f5f5f5;
/ 이미지 /
background-image: url('bg.jpg');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
/ 그라데이션 /
background: linear-gradient(to right, #667eea, #764ba2);
}
`
8. 트랜지션과 애니메이션
8-1. 트랜지션
`css.button {
background: #3b82f6;
transition: all 0.3s ease;
}
.button:hover {
background: #2563eb;
transform: translateY(-2px);
}
`8-2. 애니메이션
`css@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.element {
animation: fadeIn 0.5s ease-out;
}
`
9. 실전 예시: 버튼 스타일
`css.btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 12px 24px;
font-size: 1rem;
font-weight: 500;
border: none;
border-radius: 8px;
cursor: pointer;
transition: all 0.2s ease;
}
.btn-primary {
background: #3b82f6;
color: white;
}
.btn-primary:hover {
background: #2563eb;
}
.btn-outline {
background: transparent;
border: 1px solid #3b82f6;
color: #3b82f6;
}
.btn-outline:hover {
background: #3b82f6;
color: white;
}
`
정리
CSS는 웹페이지의 외관과 레이아웃을 담당합니다.
핵심 포인트:
- 선택자로 스타일 적용 대상 지정
- 박스 모델 이해 (content, padding, border, margin)
- Flexbox로 1차원 레이아웃
- Grid로 2차원 레이아웃
- 미디어 쿼리로 반응형
다음 편에서 JavaScript로 동적 기능을 추가합니다.
작성일: 2025-12-21 / 작성자: Claude Code
2727편 | 심화 - JavaScript27편 | 심화 - JavaScript
HTML로 구조를, CSS로 스타일을 만들었습니다. 이번 편에서는 JavaScript로 웹페이지에 동적 기능을 추가하는 방법을 다룹니다.
1. JavaScript란
1-1. 정의
JavaScript는 웹페이지에 동적 기능을 추가하는 프로그래밍 언어입니다.
집을 짓는다면 HTML이 뼈대, CSS가 인테리어라면, JavaScript는 전자기기입니다. 버튼을 누르면 불이 켜지고, 리모컨으로 TV를 조작하는 것처럼, 사용자의 행동에 반응하는 역할입니다.
1-2. JavaScript가 하는 일
- 버튼 클릭 시 동작
- 폼 입력값 검증
- 서버에서 데이터 불러오기 (AJAX)
- 페이지 내용 동적 변경
- 애니메이션 효과
2. 기본 문법
2-1. 변수 선언
`javascript// let: 변경 가능
let count = 0;
count = 1; // OK
// const: 변경 불가 (상수)
const PI = 3.14;
PI = 3; // 에러!
// var: 옛날 방식 (쓰지 마세요)
var oldStyle = "deprecated";
`권장: 기본적으로
const사용, 변경 필요할 때만let2-2. 데이터 타입
`javascript// 문자열
const name = "홍길동";
const greeting =
안녕하세요, ${name}님!; // 템플릿 리터럴// 숫자
const age = 30;
const price = 29.99;
// 불리언
const isActive = true;
const isLoggedIn = false;
// 배열
const colors = ["red", "green", "blue"];
console.log(colors[0]); // "red"
// 객체
const user = {
name: "홍길동",
age: 30,
email: "hong@example.com"
};
console.log(user.name); // "홍길동"
`2-3. 연산자
`javascript// 비교 연산자
== // 값만 비교 (타입 무시)
=== // 값과 타입 모두 비교 (권장)
!= // 값만 비교
!== // 값과 타입 모두 비교 (권장)
// 예시
"1" == 1 // true (위험!)
"1" === 1 // false (안전)
// 논리 연산자
&& // AND
// OR ! // NOT
`
3. 함수
3-1. 함수 선언
`javascript// 함수 선언식
function greet(name) {
return
안녕하세요, ${name}님!;}
// 함수 표현식
const greet2 = function(name) {
return
안녕하세요, ${name}님!;};
// 화살표 함수 (권장)
const greet3 = (name) => {
return
안녕하세요, ${name}님!;};
// 화살표 함수 (한 줄일 때)
const greet4 = (name) =>
안녕하세요, ${name}님!;`4가지 방식 모두 같은 동작을 합니다. 화살표 함수가 가장 간결합니다.
3-2. 함수 호출
`javascriptconst message = greet("홍길동");
console.log(message); // "안녕하세요, 홍길동님!"
`
4. 조건문과 반복문
4-1. 조건문
`javascript// if문
if (age >= 18) {
console.log("성인입니다");
} else if (age >= 13) {
console.log("청소년입니다");
} else {
console.log("어린이입니다");
}
// 삼항 연산자
const status = age >= 18 ? "성인" : "미성년";
`4-2. 반복문
`javascript// for문
for (let i = 0; i < 5; i++) {
console.log(i);
}
// for...of (배열)
const fruits = ["사과", "바나나", "오렌지"];
for (const fruit of fruits) {
console.log(fruit);
}
// forEach (배열 메서드)
fruits.forEach((fruit) => {
console.log(fruit);
});
`
5. 배열 메서드
5-1. 자주 쓰는 메서드
`javascriptconst numbers = [1, 2, 3, 4, 5];
// map: 변환
const doubled = numbers.map(n => n * 2);
// [2, 4, 6, 8, 10]
// filter: 조건에 맞는 것만
const even = numbers.filter(n => n % 2 === 0);
// [2, 4]
// find: 첫 번째 매칭
const found = numbers.find(n => n > 3);
// 4
// reduce: 누적
const sum = numbers.reduce((acc, n) => acc + n, 0);
// 15
// includes: 포함 여부
numbers.includes(3); // true
// push/pop: 끝에서 추가/제거
numbers.push(6); // [1, 2, 3, 4, 5, 6]
numbers.pop(); // 6 반환, [1, 2, 3, 4, 5]
`5-2. 메서드 체이닝
`javascriptconst users = [
{ name: "홍길동", age: 30 },
{ name: "김철수", age: 25 },
{ name: "이영희", age: 35 }
];
// 30세 이상 이름만 추출
const names = users
.filter(user => user.age >= 30)
.map(user => user.name);
// ["홍길동", "이영희"]
`
6. DOM 조작
6-1. 요소 선택
`javascript// ID로 선택
const header = document.getElementById("header");
// CSS 선택자로 선택 (첫 번째 하나)
const button = document.querySelector(".btn-primary");
// CSS 선택자로 선택 (모두)
const items = document.querySelectorAll(".item");
`6-2. 내용 변경
`javascript// 텍스트 변경
element.textContent = "새로운 텍스트";
// HTML 변경
element.innerHTML = "굵은 텍스트";
// 속성 변경
img.src = "new-image.jpg";
input.value = "입력값";
link.href = "https://example.com";
// 클래스 조작
element.classList.add("active");
element.classList.remove("active");
element.classList.toggle("active");
`6-3. 스타일 변경
`javascriptelement.style.color = "red";
element.style.display = "none";
element.style.backgroundColor = "#f5f5f5";
`
7. 이벤트
7-1. 이벤트 리스너
`javascriptconst button = document.querySelector("#submit-btn");
button.addEventListener("click", () => {
console.log("버튼 클릭!");
});
`7-2. 주요 이벤트
이벤트 발생 시점 `click` 클릭 `submit` 폼 제출 `input` 입력값 변경 `change` 값 변경 완료 `keydown` 키 누름 `keyup` 키 뗌 `focus` 포커스 얻음 `blur` 포커스 잃음 `load` 페이지 로드 완료 7-3. 이벤트 객체
`javascriptbutton.addEventListener("click", (event) => {
event.preventDefault(); // 기본 동작 방지
event.stopPropagation(); // 이벤트 전파 중단
console.log(event.target); // 클릭된 요소
});
// 폼 제출 시 페이지 새로고침 방지
form.addEventListener("submit", (e) => {
e.preventDefault();
// 폼 처리 로직
});
`
8. 비동기 처리
8-1. Promise와 async/await
`javascript// Promise 방식
fetch("/api/users")
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
// async/await 방식 (권장)
async function getUsers() {
try {
const response = await fetch("/api/users");
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}
`8-2. fetch API
`javascript// GET 요청
const response = await fetch("/api/users");
const users = await response.json();
// POST 요청
const response = await fetch("/api/users", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
name: "홍길동",
email: "hong@example.com"
})
});
`
9. 실전 예시: 로그인 폼 처리
`javascript// 폼 요소 선택
const loginForm = document.querySelector("#login-form");
const emailInput = document.querySelector("#email");
const passwordInput = document.querySelector("#password");
const errorMessage = document.querySelector("#error-message");
// 폼 제출 이벤트
loginForm.addEventListener("submit", async (e) => {
e.preventDefault(); // 새로고침 방지
const email = emailInput.value;
const password = passwordInput.value;
// 입력값 검증
if (!email || !password) {
errorMessage.textContent = "이메일과 비밀번호를 입력하세요";
return;
}
try {
// API 호출
const response = await fetch("/api/auth/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, password })
});
const data = await response.json();
if (response.ok) {
// 로그인 성공 → 대시보드로 이동
window.location.href = "/dashboard";
} else {
// 로그인 실패
errorMessage.textContent = data.message;
}
} catch (error) {
errorMessage.textContent = "네트워크 오류가 발생했습니다";
}
});
`
10. ES6+ 문법
10-1. 구조 분해 할당
`javascript// 객체
const user = { name: "홍길동", age: 30 };
const { name, age } = user;
// 배열
const colors = ["red", "green", "blue"];
const [first, second] = colors;
`10-2. 스프레드 연산자
`javascript// 배열 복사/합치기
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
// 객체 복사/합치기
const user = { name: "홍길동" };
const updated = { ...user, age: 30 };
// { name: "홍길동", age: 30 }
`10-3. 옵셔널 체이닝
`javascript// 안전하게 중첩 속성 접근
const email = user?.profile?.email;
// 없으면 undefined 반환 (에러 X)
`
정리
JavaScript는 웹페이지에 동적 기능을 추가합니다.
핵심 포인트:
const/let으로 변수 선언- 화살표 함수
() => {}사용 - 배열 메서드 (
map,filter,find) - DOM 조작 (
querySelector,addEventListener) - 비동기 처리 (
async/await)
다음 편에서 TypeScript로 타입 안전성을 추가합니다.
작성일: 2025-12-21 / 작성자: Claude Code
2828편 | 심화 - TypeScript28편 | 심화 - TypeScript
27편에서 JavaScript를 다뤘습니다. 이번 편에서는 JavaScript에 타입 안전성을 추가한 TypeScript를 살펴봅니다.
1. TypeScript란
1-1. 정의
TypeScript는 JavaScript에 정적 타입을 추가한 언어입니다. Microsoft가 개발했고, JavaScript의 상위 집합(superset)입니다.
1-2. 왜 TypeScript인가
`javascript// JavaScript
function add(a, b) {
return a + b;
}
add(1, 2); // 3 (정상)
add("1", 2); // "12" (문자열 연결 - 버그!)
add(undefined); // NaN (에러!)
``typescript// TypeScript
function add(a: number, b: number): number {
return a + b;
}
add(1, 2); // 3 (정상)
add("1", 2); // ❌ 컴파일 에러! (실행 전에 발견)
add(undefined); // ❌ 컴파일 에러!
`장점:
- 버그를 실행 전에 발견
- IDE 자동완성 강화
- 코드 문서화 역할
- 대규모 프로젝트에 필수
1-3. 작동 원리
`TypeScript 코드 (.ts)
↓
컴파일러 (tsc)
↓
JavaScript 코드 (.js)
↓
브라우저 실행
`브라우저는 TypeScript를 직접 실행하지 못합니다. JavaScript로 변환 후 실행합니다.
2. 기본 타입
2-1. 원시 타입
`typescript// 문자열
const name: string = "홍길동";
// 숫자
const age: number = 30;
const price: number = 29.99;
// 불리언
const isActive: boolean = true;
// null과 undefined
const empty: null = null;
const notDefined: undefined = undefined;
`2-2. 배열
`typescript// 방법 1: 타입[]
const numbers: number[] = [1, 2, 3];
const names: string[] = ["홍길동", "김철수"];
// 방법 2: Array<타입>
const items: Array
= [1, 2, 3]; `2-3. 객체
`typescript// 인라인 타입
const user: { name: string; age: number } = {
name: "홍길동",
age: 30
};
// interface (권장)
interface User {
name: string;
age: number;
email?: string; // 선택적 속성 (optional)
}
const myUser: User = {
name: "홍길동",
age: 30
// email은 없어도 OK
};
`
3. 타입 정의
3-1. interface
`typescriptinterface User {
id: number;
name: string;
email: string;
createdAt: Date;
}
interface Post {
id: number;
title: string;
content: string;
author: User; // 다른 interface 참조
}
`3-2. type
`typescript// 타입 별칭
type ID = string | number;
type Status = "pending" | "active" | "completed";
// 객체 타입
type User = {
id: ID;
name: string;
status: Status;
};
`3-3. interface vs type
구분 interface type 확장 `extends` `&` (intersection) 선언 병합 가능 불가 유니온/교차 타입 불가 가능 권장 객체 정의 유니온, 기타 `typescript// interface 확장
interface Animal {
name: string;
}
interface Dog extends Animal {
breed: string;
}
// type 확장
type Animal = { name: string };
type Dog = Animal & { breed: string };
`
4. 함수 타입
4-1. 기본 형식
`typescript// 함수 선언식
function add(a: number, b: number): number {
return a + b;
}
// 화살표 함수
const addArrow = (a: number, b: number): number => a + b;
// 반환값 없음
function log(message: string): void {
console.log(message);
}
`4-2. 선택적 매개변수
`typescriptfunction greet(name: string, greeting?: string): string {
return
${greeting || "안녕하세요"}, ${name}님!;}
greet("홍길동"); // "안녕하세요, 홍길동님!"
greet("홍길동", "반갑습니다"); // "반갑습니다, 홍길동님!"
`4-3. 기본값
`typescriptfunction greet(name: string, greeting: string = "안녕하세요"): string {
return
${greeting}, ${name}님!;}
`
5. 유니온과 제네릭
5-1. 유니온 타입
`typescript// 여러 타입 중 하나
let id: string | number;
id = "abc123"; // OK
id = 123; // OK
// 함수에서 사용
function printId(id: string | number) {
if (typeof id === "string") {
console.log(id.toUpperCase());
} else {
console.log(id);
}
}
`5-2. 리터럴 타입
`typescripttype Direction = "up" | "down" | "left" | "right";
type Status = "pending" | "active" | "completed";
function move(direction: Direction) {
// ...
}
move("up"); // OK
move("front"); // ❌ 에러!
`5-3. 제네릭
`typescript// 타입을 매개변수처럼 받음
function first
(arr: T[]): T | undefined { return arr[0];
}
first
([1, 2, 3]); // 1 first
(["a", "b"]); // "a" first([1, 2, 3]); // 타입 추론 OK
// 제네릭 interface
interface ApiResponse
{ data: T;
status: number;
message: string;
}
const userResponse: ApiResponse
= { data: { id: 1, name: "홍길동", email: "hong@example.com", createdAt: new Date() },
status: 200,
message: "성공"
};
`
6. 타입 가드
6-1. typeof
`typescriptfunction process(value: string | number) {
if (typeof value === "string") {
// 여기서 value는 string
return value.toUpperCase();
} else {
// 여기서 value는 number
return value * 2;
}
}
`6-2. in 연산자
`typescriptinterface Dog {
bark: () => void;
}
interface Cat {
meow: () => void;
}
function speak(animal: Dog | Cat) {
if ("bark" in animal) {
animal.bark(); // Dog
} else {
animal.meow(); // Cat
}
}
`
7. 실전 예시: API 타입 정의
7-1. API 응답 타입
`typescript// 기본 응답 구조
interface ApiResponse
{ success: boolean;
data: T;
error?: string;
}
// 사용자 타입
interface User {
id: string;
email: string;
name: string;
plan: "free" | "pro" | "enterprise";
createdAt: string;
}
// 구독 타입
interface Subscription {
id: string;
userId: string;
plan: string;
status: "active" | "cancelled" | "expired";
expiresAt: string;
}
`7-2. API 함수
`typescriptasync function getUser(userId: string): Promise
> { const response = await fetch(
/api/users/${userId});return response.json();
}
async function updateSubscription(
subscriptionId: string,
data: Partial
): Promise
> { const response = await fetch(
/api/subscriptions/${subscriptionId}, {method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
});
return response.json();
}
`7-3. 사용 예시
`typescriptasync function displayUser() {
const result = await getUser("user_123");
if (result.success) {
console.log(result.data.name); // 자동완성 지원!
console.log(result.data.plan); // 타입 안전
} else {
console.error(result.error);
}
}
`
8. 유틸리티 타입
8-1. 자주 쓰는 유틸리티
`typescriptinterface User {
id: string;
name: string;
email: string;
age: number;
}
// Partial: 모든 속성을 선택적으로
type PartialUser = Partial
; // { id?: string; name?: string; ... }
// Pick: 특정 속성만 선택
type UserName = Pick
; // { name: string; email: string }
// Omit: 특정 속성 제외
type UserWithoutId = Omit
; // { name: string; email: string; age: number }
// Required: 모든 속성을 필수로
type RequiredUser = Required
; `8-2. 실전 활용
`typescript// 업데이트 시 일부 필드만 받기
async function updateUser(
userId: string,
data: Partial
> // id 제외, 나머지 선택적 ): Promise
{ // ...
}
// 사용
updateUser("user_123", { name: "새 이름" }); // OK
updateUser("user_123", { email: "new@email.com" }); // OK
updateUser("user_123", { id: "new_id" }); // ❌ 에러!
`
9. 설정 파일 (tsconfig.json)
`json{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/*/"],
"exclude": ["node_modules"]
}
`옵션 설명 `target` 출력 JavaScript 버전 `strict` 엄격한 타입 검사 (권장) `outDir` 컴파일 결과 출력 폴더 `rootDir` 소스 파일 폴더
정리
TypeScript는 JavaScript에 타입 안전성을 추가합니다.
핵심 포인트:
- 변수, 함수에 타입 명시 (
: type) interface로 객체 구조 정의- 유니온 타입으로 여러 타입 허용 (
|) - 제네릭으로 재사용 가능한 타입 (
) - 유틸리티 타입으로 타입 변환 (
Partial,Pick,Omit)
버그를 실행 전에 잡고, IDE 자동완성을 활용하세요.
작성일: 2025-12-21 / 작성자: Claude Code
2929편 | 심화 - SQL29편 | 심화 - SQL
18편에서 데이터베이스 영역을 다뤘습니다. 이번 편에서는 SQL(Structured Query Language)을 깊이 있게 살펴봅니다. 데이터를 다루는 핵심 언어입니다.
1. SQL이란
1-1. 정의
SQL은 데이터베이스와 대화하는 언어입니다. 데이터를 조회, 추가, 수정, 삭제하는 모든 작업에 사용합니다.
1-2. SQL 종류
분류 설명 명령어 DDL 구조 정의 CREATE, ALTER, DROP DML 데이터 조작 SELECT, INSERT, UPDATE, DELETE DCL 권한 제어 GRANT, REVOKE
2. 테이블 생성 (DDL)
2-1. CREATE TABLE
`sqlCREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) NOT NULL UNIQUE,
name VARCHAR(100) NOT NULL,
password_hash VARCHAR(255) NOT NULL,
plan VARCHAR(20) DEFAULT 'free',
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
`2-2. 주요 데이터 타입
타입 설명 예시 `VARCHAR(n)` 가변 문자열 이름, 이메일 `TEXT` 긴 문자열 본문 내용 `INTEGER` 정수 나이, 수량 `NUMERIC(p,s)` 소수점 숫자 금액 `BOOLEAN` 참/거짓 활성 상태 `TIMESTAMP` 날짜+시간 생성일 `UUID` 고유 식별자 ID `JSONB` JSON 데이터 설정 2-3. 제약 조건
`sql-- PRIMARY KEY: 고유 식별자
id UUID PRIMARY KEY
-- NOT NULL: 필수값
email VARCHAR(255) NOT NULL
-- UNIQUE: 중복 불가
email VARCHAR(255) UNIQUE
-- DEFAULT: 기본값
created_at TIMESTAMP DEFAULT NOW()
-- FOREIGN KEY: 외래 키
user_id UUID REFERENCES users(id)
-- CHECK: 조건 검사
plan VARCHAR(20) CHECK (plan IN ('free', 'pro', 'enterprise'))
`
3. 데이터 조회 (SELECT)
3-1. 기본 조회
`sql-- 모든 열 조회
SELECT * FROM users;
-- 특정 열만 조회
SELECT id, name, email FROM users;
-- 조건 조회
SELECT * FROM users WHERE plan = 'pro';
-- 정렬
SELECT * FROM users ORDER BY created_at DESC;
-- 개수 제한
SELECT * FROM users LIMIT 10;
SELECT * FROM users LIMIT 10 OFFSET 20; -- 21~30번째
`3-2. 조건 연산자
`sql-- 비교
WHERE age > 18
WHERE age >= 18
WHERE age < 30
WHERE age <= 30
WHERE age != 25
-- 논리
WHERE plan = 'pro' AND status = 'active'
WHERE plan = 'free' OR plan = 'pro'
WHERE NOT status = 'cancelled'
-- 범위
WHERE age BETWEEN 18 AND 30
-- 목록
WHERE plan IN ('pro', 'enterprise')
-- 패턴 (LIKE)
WHERE email LIKE '%@gmail.com' -- @gmail.com으로 끝나는
WHERE name LIKE '김%' -- 김으로 시작하는
-- NULL 체크
WHERE deleted_at IS NULL
WHERE deleted_at IS NOT NULL
`3-3. 집계 함수
`sql-- 개수
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM users WHERE plan = 'pro';
-- 합계/평균/최대/최소
SELECT SUM(amount) FROM payments;
SELECT AVG(amount) FROM payments;
SELECT MAX(amount) FROM payments;
SELECT MIN(amount) FROM payments;
-- 그룹별 집계
SELECT plan, COUNT(*) as count
FROM users
GROUP BY plan;
-- 그룹 조건
SELECT plan, COUNT(*) as count
FROM users
GROUP BY plan
HAVING COUNT(*) > 10;
`
4. 데이터 추가 (INSERT)
`sql-- 단일 행 추가
INSERT INTO users (email, name, password_hash)
VALUES ('hong@example.com', '홍길동', 'hashed_password');
-- 여러 행 추가
INSERT INTO users (email, name, password_hash)
VALUES
('kim@example.com', '김철수', 'hash1'),
('lee@example.com', '이영희', 'hash2');
-- 추가 후 결과 반환
INSERT INTO users (email, name, password_hash)
VALUES ('hong@example.com', '홍길동', 'hashed_password')
RETURNING id, email, created_at;
`
5. 데이터 수정 (UPDATE)
`sql-- 단일 조건
UPDATE users
SET plan = 'pro'
WHERE id = 'user_123';
-- 여러 열 수정
UPDATE users
SET
plan = 'enterprise',
updated_at = NOW()
WHERE id = 'user_123';
-- 수정 후 결과 반환
UPDATE users
SET plan = 'pro'
WHERE id = 'user_123'
RETURNING *;
`주의: WHERE 없이 UPDATE하면 모든 행이 수정됩니다!
6. 데이터 삭제 (DELETE)
`sql-- 조건부 삭제
DELETE FROM users WHERE id = 'user_123';
-- 삭제 후 결과 반환
DELETE FROM users WHERE id = 'user_123'
RETURNING *;
`주의: WHERE 없이 DELETE하면 모든 행이 삭제됩니다!
6-1. Soft Delete (권장)
실제 삭제 대신 삭제 표시:
`sql-- 테이블에 deleted_at 열 추가
ALTER TABLE users ADD COLUMN deleted_at TIMESTAMP;
-- 삭제 시 시간만 기록
UPDATE users
SET deleted_at = NOW()
WHERE id = 'user_123';
-- 조회 시 삭제된 항목 제외
SELECT * FROM users WHERE deleted_at IS NULL;
`
7. JOIN
7-1. JOIN 종류
`INNER JOIN: 양쪽 모두 있는 것만
LEFT JOIN: 왼쪽 테이블 기준 (오른쪽 없으면 NULL)
RIGHT JOIN: 오른쪽 테이블 기준
FULL JOIN: 양쪽 모두 포함
`7-2. 예시
`sql-- 사용자와 구독 정보 함께 조회
SELECT
u.id,
u.name,
u.email,
s.plan,
s.status
FROM users u
INNER JOIN subscriptions s ON u.id = s.user_id;
-- 구독이 없는 사용자도 포함
SELECT
u.id,
u.name,
s.plan
FROM users u
LEFT JOIN subscriptions s ON u.id = s.user_id;
`7-3. 다중 JOIN
`sqlSELECT
u.name,
s.plan,
p.amount,
p.created_at as payment_date
FROM users u
JOIN subscriptions s ON u.id = s.user_id
JOIN payments p ON s.id = p.subscription_id
WHERE p.status = 'completed'
ORDER BY p.created_at DESC;
`
8. 서브쿼리
8-1. WHERE 절에서
`sql-- 결제한 적 있는 사용자
SELECT * FROM users
WHERE id IN (
SELECT DISTINCT user_id FROM payments
);
-- 평균보다 많이 결제한 사용자
SELECT * FROM payments
WHERE amount > (
SELECT AVG(amount) FROM payments
);
`8-2. FROM 절에서
`sql-- 월별 결제 합계에서 최대값
SELECT MAX(monthly_total)
FROM (
SELECT
DATE_TRUNC('month', created_at) as month,
SUM(amount) as monthly_total
FROM payments
GROUP BY DATE_TRUNC('month', created_at)
) as monthly_payments;
`
9. 인덱스
9-1. 인덱스란
인덱스는 책의 색인과 같습니다. 전체를 읽지 않고 빠르게 찾습니다.
9-2. 인덱스 생성
`sql-- 단일 열 인덱스
CREATE INDEX idx_users_email ON users(email);
-- 복합 인덱스
CREATE INDEX idx_users_plan_status ON users(plan, status);
-- 고유 인덱스
CREATE UNIQUE INDEX idx_users_email_unique ON users(email);
`9-3. 인덱스 권장 대상
- WHERE 절에 자주 사용되는 열
- JOIN 조건에 사용되는 열
- ORDER BY 에 사용되는 열
- 고유해야 하는 열 (email 등)
10. 실전 예시
10-1. 사용자 + 구독 테이블
`sql-- 사용자 테이블
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) NOT NULL UNIQUE,
name VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
-- 구독 테이블
CREATE TABLE subscriptions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id),
plan VARCHAR(20) NOT NULL,
status VARCHAR(20) DEFAULT 'active',
started_at TIMESTAMP DEFAULT NOW(),
expires_at TIMESTAMP
);
-- 인덱스
CREATE INDEX idx_subscriptions_user_id ON subscriptions(user_id);
CREATE INDEX idx_subscriptions_status ON subscriptions(status);
`10-2. 자주 쓰는 쿼리
`sql-- 활성 구독 사용자 조회
SELECT u.*, s.plan, s.expires_at
FROM users u
JOIN subscriptions s ON u.id = s.user_id
WHERE s.status = 'active'
ORDER BY u.created_at DESC;
-- 구독 만료 예정 사용자 (7일 이내)
SELECT u.email, s.plan, s.expires_at
FROM users u
JOIN subscriptions s ON u.id = s.user_id
WHERE s.expires_at BETWEEN NOW() AND NOW() + INTERVAL '7 days';
-- 플랜별 사용자 수
SELECT
s.plan,
COUNT(*) as user_count
FROM subscriptions s
WHERE s.status = 'active'
GROUP BY s.plan
ORDER BY user_count DESC;
`
정리
SQL은 데이터베이스와 대화하는 언어입니다.
핵심 명령어:
SELECT: 조회INSERT: 추가UPDATE: 수정 (WHERE 필수!)DELETE: 삭제 (WHERE 필수!)JOIN: 테이블 연결
주의사항:
- UPDATE/DELETE는 반드시 WHERE 조건 확인
- 실제 삭제보다 Soft Delete 권장
- 자주 조회하는 열에 인덱스 추가
작성일: 2025-12-21 / 작성자: Claude Code
3030편 | 심화 - Supabase30편 | 심화 - Supabase
18편에서 데이터베이스 영역을 다루면서 Supabase를 소개했습니다. 이번 편에서는 Supabase를 실전에서 활용하는 방법을 깊이 다룹니다.
1. Supabase란
1-1. 정의
Supabase는 오픈소스 Firebase 대안입니다. PostgreSQL 데이터베이스를 기반으로 인증, 스토리지, 실시간 기능을 제공합니다.
1-2. 제공 기능
기능 설명 Database PostgreSQL 데이터베이스 Auth 이메일, OAuth 인증 Storage 파일 업로드/다운로드 Realtime 실시간 데이터 구독 Edge Functions 서버리스 함수 1-3. 왜 Supabase인가
- 무료 티어 제공 (개인 프로젝트에 충분)
- PostgreSQL 기반 (표준 SQL)
- RLS(Row Level Security)로 보안 강화
- SDK로 쉬운 연동
1-4. 무료 티어 제한 (2025년 기준)
항목 무료 제한 Database 500 MB 프로젝트 수 2개 파일 스토리지 1 GB 대역폭 10 GB/월 Edge Functions 500,000 호출/월
2. 프로젝트 설정
2-1. 프로젝트 생성
- https://supabase.com 접속 → GitHub 로그인
- New Project 클릭
- 정보 입력:
- Project name: my-project
- Database Password: (강력한 비밀번호)
- Region: Northeast Asia (Tokyo)
- Create new project
2-2. API 키 확인
Project Settings → API에서 확인:
키 용도 `anon` key 클라이언트에서 사용 (공개 가능) `service_role` key 서버에서만 사용 (비밀!) URL API 엔드포인트
3. 테이블 생성
3-1. SQL Editor 사용
`sql-- 사용자 테이블 (auth.users와 연동)
CREATE TABLE profiles (
id UUID PRIMARY KEY REFERENCES auth.users(id),
name VARCHAR(100),
avatar_url TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
-- 구독 테이블
CREATE TABLE subscriptions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id),
plan VARCHAR(20) NOT NULL DEFAULT 'free',
status VARCHAR(20) NOT NULL DEFAULT 'active',
created_at TIMESTAMP DEFAULT NOW(),
expires_at TIMESTAMP
);
`3-2. 인덱스 추가
`sqlCREATE INDEX idx_subscriptions_user_id ON subscriptions(user_id);
CREATE INDEX idx_subscriptions_status ON subscriptions(status);
`
4. Row Level Security (RLS)
4-1. RLS란
RLS는 행 단위 보안 정책입니다. 사용자가 자신의 데이터만 접근하도록 제한합니다.
4-2. RLS 활성화
`sql-- RLS 활성화 (필수!)
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
ALTER TABLE subscriptions ENABLE ROW LEVEL SECURITY;
`4-3. 정책 생성
`sql-- profiles: 본인 데이터만 조회/수정
CREATE POLICY "Users can view own profile"
ON profiles FOR SELECT
USING (auth.uid() = id);
CREATE POLICY "Users can update own profile"
ON profiles FOR UPDATE
USING (auth.uid() = id);
-- subscriptions: 본인 구독만 조회
CREATE POLICY "Users can view own subscriptions"
ON subscriptions FOR SELECT
USING (auth.uid() = user_id);
`4-4. 주요 함수
함수 설명 `auth.uid()` 현재 로그인한 사용자 ID `auth.jwt()` JWT 토큰 전체 `auth.role()` 사용자 역할
5. JavaScript SDK
5-1. 설치 및 초기화
`javascript// npm install @supabase/supabase-js
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(
'https://xxx.supabase.co',
'your-anon-key'
);
`5-2. 데이터 조회 (SELECT)
`javascript// 전체 조회
const { data, error } = await supabase
.from('profiles')
.select('*');
// 조건 조회
const { data, error } = await supabase
.from('subscriptions')
.select('*')
.eq('status', 'active');
// 관계 데이터 함께 조회
const { data, error } = await supabase
.from('subscriptions')
.select(`
*,
profiles (name, avatar_url)
`)
.eq('user_id', userId);
// 정렬 및 제한
const { data, error } = await supabase
.from('profiles')
.select('*')
.order('created_at', { ascending: false })
.limit(10);
`5-3. 데이터 추가 (INSERT)
`javascriptconst { data, error } = await supabase
.from('profiles')
.insert({
id: userId,
name: '홍길동',
avatar_url: null
})
.select(); // 추가된 데이터 반환
`5-4. 데이터 수정 (UPDATE)
`javascriptconst { data, error } = await supabase
.from('profiles')
.update({ name: '새 이름' })
.eq('id', userId)
.select();
`5-5. 데이터 삭제 (DELETE)
`javascriptconst { error } = await supabase
.from('profiles')
.delete()
.eq('id', userId);
`
6. 인증 (Auth)
6-1. 이메일 회원가입
`javascriptconst { data, error } = await supabase.auth.signUp({
email: 'user@example.com',
password: 'securepassword123'
});
`6-2. 이메일 로그인
`javascriptconst { data, error } = await supabase.auth.signInWithPassword({
email: 'user@example.com',
password: 'securepassword123'
});
`6-3. OAuth 로그인 (Google)
`javascriptconst { data, error } = await supabase.auth.signInWithOAuth({
provider: 'google',
options: {
redirectTo: 'https://yoursite.com/callback'
}
});
`6-4. 현재 사용자 확인
`javascript// 현재 세션
const { data: { session } } = await supabase.auth.getSession();
// 현재 사용자
const { data: { user } } = await supabase.auth.getUser();
`6-5. 로그아웃
`javascriptconst { error } = await supabase.auth.signOut();
`
7. 스토리지 (Storage)
7-1. 버킷 생성 (Dashboard)
- Storage → New bucket
- 이름 입력 (예:
avatars)- Public/Private 선택
7-2. 파일 업로드
`javascriptconst { data, error } = await supabase.storage
.from('avatars')
.upload(
${userId}/avatar.png, file, {cacheControl: '3600',
upsert: true
});
`7-3. 파일 URL 가져오기
`javascript// 공개 URL
const { data } = supabase.storage
.from('avatars')
.getPublicUrl(
${userId}/avatar.png);console.log(data.publicUrl);
`7-4. 파일 삭제
`javascriptconst { error } = await supabase.storage
.from('avatars')
.remove([
${userId}/avatar.png]);`
8. 실시간 구독 (Realtime)
`javascript// 실시간 구독
const subscription = supabase
.channel('subscriptions-changes')
.on(
'postgres_changes',
{
event: '*',
schema: 'public',
table: 'subscriptions',
filter:
user_id=eq.${userId}},
(payload) => {
console.log('변경 감지:', payload);
}
)
.subscribe();
// 구독 해제
subscription.unsubscribe();
`
9. 실전 예시: 사용자 프로필
9-1. 테이블 생성
`sql-- profiles 테이블
CREATE TABLE profiles (
id UUID PRIMARY KEY REFERENCES auth.users(id),
name VARCHAR(100),
avatar_url TEXT,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- RLS 활성화
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
-- 정책
CREATE POLICY "Public profiles are viewable"
ON profiles FOR SELECT
USING (true);
CREATE POLICY "Users can update own profile"
ON profiles FOR UPDATE
USING (auth.uid() = id);
-- 회원가입 시 자동 생성 트리거
CREATE OR REPLACE FUNCTION handle_new_user()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO public.profiles (id, name)
VALUES (NEW.id, NEW.raw_user_meta_data->>'name');
RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
CREATE TRIGGER on_auth_user_created
AFTER INSERT ON auth.users
FOR EACH ROW
EXECUTE FUNCTION handle_new_user();
`9-2. 프로필 조회/수정
`javascript// 프로필 조회
async function getProfile(userId) {
const { data, error } = await supabase
.from('profiles')
.select('*')
.eq('id', userId)
.single();
return { data, error };
}
// 프로필 수정
async function updateProfile(userId, updates) {
const { data, error } = await supabase
.from('profiles')
.update({
...updates,
updated_at: new Date().toISOString()
})
.eq('id', userId)
.select()
.single();
return { data, error };
}
`
10. 환경 변수 설정
10-1. 로컬 개발
`javascript// .env.local
SUPABASE_URL=https://xxx.supabase.co
SUPABASE_ANON_KEY=eyJxxx...
`10-2. Vercel 배포
- Vercel → Project → Settings → Environment Variables
- 추가:
SUPABASE_URLSUPABASE_ANON_KEY
정리
Supabase는 PostgreSQL 기반 백엔드 서비스입니다.
핵심 기능:
- Database: PostgreSQL + RLS
- Auth: 이메일, OAuth 인증
- Storage: 파일 업로드
- Realtime: 실시간 구독
RLS 필수:
- 테이블마다 RLS 활성화
- 정책으로 접근 권한 설정
auth.uid()로 현재 사용자 확인
작성일: 2025-12-21 / 작성자: Claude Code
3131편 | 심화 - 도메인과 호스팅31편 | 심화 - 도메인과 호스팅
21편에서 DevOps 영역을 살펴보면서 배포와 Vercel에 대해 간략히 다뤘습니다. 이번 편에서는 도메인과 호스팅에 대해 더 깊이 파고들어 봅니다. 웹사이트를 인터넷에 공개하려면 반드시 알아야 할 핵심 지식입니다.
1. 도메인의 이해
1-1. 도메인이란
도메인은 웹사이트의 주소입니다. IP 주소(192.168.0.1 같은 숫자)를 사람이 기억하기 쉬운 문자로 표현한 것입니다.
google.com의 실제 IP 주소는 142.250.196.110입니다. 숫자를 외우는 것보다 google.com이 훨씬 기억하기 쉽습니다.
1-2. 도메인 구조
도메인은 계층 구조로 되어 있습니다.
`www.example.com
│ │ │
│ │ └── TLD (최상위 도메인)
│ └──────── 2차 도메인 (우리가 구매하는 것)
└─────────────── 서브도메인
`최상위 도메인(TLD) 종류:
- 일반: .com, .org, .net, .edu
- 국가: .kr, .jp, .us
- 신규: .app, .dev, .io, .ai
1-3. 서브도메인
서브도메인은 메인 도메인 앞에 붙여서 서비스를 구분합니다.
네이버 예시:
- naver.com → 메인
- mail.naver.com → 메일
- blog.naver.com → 블로그
- map.naver.com → 지도
하나의 도메인으로 여러 서브도메인을 무제한 생성할 수 있습니다.
1-4. DNS 작동 원리
DNS(Domain Name System)는 도메인을 IP 주소로 변환해주는 시스템입니다.
`브라우저에 google.com 입력
↓
DNS 서버에 IP 주소 요청
↓
DNS 서버가 142.250.196.110 응답
↓
브라우저가 해당 IP로 접속
↓
구글 서버가 웹페이지 전송
`이 과정은 몇 초 안에 완료됩니다.
2. 호스팅의 이해
2-1. 호스팅이란
호스팅은 웹사이트 파일을 저장하고 인터넷에 공개하는 서비스입니다. 웹사이트가 살 집을 임대하는 것과 같습니다.
우리가 만든 HTML, CSS, JavaScript 파일은 내 컴퓨터에만 있으면 다른 사람이 볼 수 없습니다. 24시간 켜져 있는 서버에 올려야 전 세계에서 접속할 수 있습니다.
2-2. 호스팅 종류 비교
종류 비유 특징 적합한 경우 공유 호스팅 셰어하우스 저렴, 느림 개인 블로그 VPS 호스팅 오피스텔 독립 자원 중소 비즈니스 전용 서버 단독 주택 최고 성능 대규모 서비스 클라우드 유연한 자원 확장성 AWS, GCP 2-3. 정적 호스팅 서비스
최근에는 정적 웹사이트 전문 호스팅이 인기입니다.
서비스 무료 제한 특징 GitHub Pages 1GB GitHub 연동 Netlify 100GB/월 폼 처리, 서버리스 Vercel 100GB/월 빠른 속도, Next.js 최적화
3. Vercel 배포 실전 가이드
3-1. Vercel 프로젝트 생성
- https://vercel.com 접속 → GitHub 로그인
- Add New... → Project
- GitHub 저장소 선택
- 설정 입력:
항목 입력 Project Name ssal-works (소문자, 하이픈만) Framework Preset Other Root Directory Production/Frontend Build Command (비워두기) - Deploy 클릭
3-2. 환경변수 설정
- Vercel → Project → Settings → Environment Variables
- 환경변수 추가:
Key Value SUPABASE_URL https://xxx.supabase.co SUPABASE_ANON_KEY eyJxxx... SUPABASE_SERVICE_ROLE_KEY eyJxxx... RESEND_API_KEY re_xxx... - Environment: All 선택
3-3. vercel.json 설정
`json{
"version": 2,
"name": "ssalworks-v1",
"buildCommand": null,
"outputDirectory": ".",
"framework": null,
"rewrites": [
{
"source": "/api/:path*",
"destination": "/api/:path*"
}
],
"headers": [
{
"source": "/api/(.*)",
"headers": [
{ "key": "Access-Control-Allow-Origin", "value": "*" },
{ "key": "Access-Control-Allow-Methods", "value": "GET,POST,PUT,DELETE,OPTIONS" }
]
}
],
"functions": {
"api/*/.js": {
"maxDuration": 30,
"memory": 1024
}
}
}
`
4. 도메인 연결 실전
4-1. Vercel에 도메인 추가
- Vercel → Project → Settings → Domains
- 도메인 입력:
www.ssalworks.ai.kr- Add 클릭
- 아래 정보 복사:
Type Name Value A www 76.76.21.21 TXT _vercel vc-domain-verify=... 4-2. DNS 설정 (Whois 예시)
- https://whois.co.kr 로그인
- 도메인 관리 → 해당 도메인 선택
- 부가서비스 → 네임서버 고급설정
A 레코드 추가:
호스트명 IP 주소 www 76.76.21.21 TXT 레코드 추가:
호스트명 값 _vercel vc-domain-verify=... (Vercel에서 복사) 4-3. DNS 전파 확인
명령어로 확인:
`bashnslookup www.ssalworks.ai.kr 8.8.8.8
`Vercel Dashboard 상태:
- ⚠️ Verification Needed → 전파 대기
- ✅ Valid Configuration → 성공
주의: DNS 전파는 최대 48시간 소요될 수 있습니다.
5. 주요 DNS 레코드 타입
타입 용도 예시 A 도메인 → IPv4 주소 example.com → 76.76.21.21 AAAA 도메인 → IPv6 주소 거의 안 씀 CNAME 도메인 → 다른 도메인 www → example.com MX 이메일 서버 지정 메일 수신용 TXT 도메인 소유권 확인 Vercel, Google 인증
6. 트러블슈팅
문제 1: Project Name 에러
증상:
The name contains invalid characters해결: 소문자, 숫자, 하이픈만 사용
- ❌
SSALWorks - ✅
ssal-works
문제 2: 함수 패턴 에러
증상:
The pattern doesn't match any Serverless Functions해결: vercel.json에서 존재하지 않는 패턴 제거
문제 3: 도메인 소유권 확인
증상:
This domain is linked to another Vercel account해결:
- TXT 레코드 추가 (_vercel)
- DNS 전파 대기
- Vercel에서 "Refresh" 클릭
문제 4: DNS_PROBE_FINISHED_NXDOMAIN
해결: DNS 전파 완료까지 대기 (최대 48시간)
문제 5: 특수문자 입력 불가
해결: 일반 DNS 관리가 아닌 네임서버 고급설정 사용
7. 권장 설정
항목 권장 값 네임서버 Whois 기본값 (ns1.whoisdomain.kr) DNS 관리 Whois 네임서버 고급설정 도메인 www.example.com (www 포함 권장) A 레코드 76.76.21.21 (Vercel 기본)
8. 배포 체크리스트
Vercel 설정:
- [ ] Vercel 프로젝트 생성 완료
- [ ] Root Directory 설정 (Production/Frontend)
- [ ] 환경변수 설정 완료
- [ ] 첫 배포 성공
도메인 연결:
- [ ] Vercel에 도메인 추가 완료
- [ ] A 레코드 설정 완료
- [ ] TXT 레코드 설정 완료
- [ ] DNS 전파 확인 완료
최종 확인:
- [ ] https://www.example.com 접속 성공
- [ ] SSL 인증서 자동 적용 확인 (자물쇠 아이콘)
정리
도메인과 호스팅은 웹사이트를 세상에 공개하는 필수 요소입니다.
핵심 개념:
- 도메인 = 주소 (사람이 기억하기 쉬운 이름)
- 호스팅 = 집 (파일이 저장되는 서버)
- DNS = 전화번호부 (도메인 → IP 변환)
실전 팁:
- Vercel은 정적 사이트 + Serverless 함수에 최적
- 도메인 연결 시 TXT 레코드로 소유권 확인 필요
- DNS 전파는 최대 48시간, 인내심 필요
처음에는 무료 호스팅(Vercel, Netlify)으로 시작하고, 트래픽이 늘어나면 유료 플랜으로 업그레이드하는 전략이 좋습니다.
작성일: 2025-12-21 / 작성자: Claude Code
3232편 | 심화 - Vercel32편 | 심화 - Vercel
21편에서 DevOps 영역을 다루면서 Vercel을 소개했고, 31편에서 도메인 연결을 다뤘습니다. 이번 편에서는 Vercel의 상세 기능과 활용법을 깊이 다룹니다.
1. Vercel이란
1-1. 정의
Vercel은 프론트엔드 배포 플랫폼입니다. Next.js를 만든 회사로, 정적 사이트와 서버리스 함수를 손쉽게 배포합니다.
1-2. 주요 특징
특징 설명 자동 배포 Git push만 하면 자동 배포 엣지 네트워크 전 세계 CDN으로 빠른 속도 프리뷰 배포 PR마다 미리보기 URL 생성 서버리스 함수 API 엔드포인트 제공 자동 HTTPS SSL 인증서 자동 발급 1-3. 무료 티어 제한
항목 무료 제한 대역폭 100GB/월 빌드 시간 6,000분/월 서버리스 함수 실행 100GB-Hours/월 팀원 수 1명 (개인)
2. 프로젝트 설정
2-1. 프로젝트 연결
- https://vercel.com → GitHub 로그인
- Add New... → Project
- GitHub 저장소 선택
- 설정:
항목 설명 Project Name 프로젝트 이름 (소문자, 하이픈) Framework Preset Other (정적), Next.js 등 Root Directory 빌드할 폴더 경로 Build Command 빌드 명령어 (필요시) 2-2. 자동 배포 설정
Git 연결 후 자동 동작:
main브랜치 push → 프로덕션 배포- PR 생성 → 프리뷰 URL 생성
- PR 업데이트 → 프리뷰 자동 갱신
3. 서버리스 함수 (Serverless Functions)
3-1. 파일 구조
`프로젝트/
├── api/ ← 서버리스 함수 폴더
│ ├── hello.js ← /api/hello
│ ├── users/
│ │ └── [id].js ← /api/users/:id
│ └── auth/
│ └── login.js ← /api/auth/login
└── index.html
`3-2. 기본 함수 작성
`javascript// api/hello.js
export default function handler(req, res) {
res.status(200).json({ message: 'Hello, World!' });
}
`3-3. HTTP 메서드 처리
`javascript// api/users.js
export default async function handler(req, res) {
if (req.method === 'GET') {
// 사용자 목록 조회
res.status(200).json({ users: [] });
} else if (req.method === 'POST') {
// 사용자 생성
const { name, email } = req.body;
res.status(201).json({ id: 1, name, email });
} else {
res.setHeader('Allow', ['GET', 'POST']);
res.status(405).end(
Method ${req.method} Not Allowed);}
}
`3-4. 동적 라우트
`javascript// api/users/[id].js
export default async function handler(req, res) {
const { id } = req.query; // URL 파라미터
if (req.method === 'GET') {
res.status(200).json({ id, name: '홍길동' });
} else if (req.method === 'DELETE') {
res.status(200).json({ deleted: id });
}
}
`3-5. 환경변수 사용
`javascript// api/supabase-client.js
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(
process.env.SUPABASE_URL,
process.env.SUPABASE_SERVICE_ROLE_KEY
);
export default supabase;
`
4. 환경변수 설정
4-1. Dashboard에서 설정
- Project → Settings → Environment Variables
- 변수 추가:
Key Value Environment SUPABASE_URL https://xxx.supabase.co All SUPABASE_ANON_KEY eyJxxx... All SUPABASE_SERVICE_ROLE_KEY eyJxxx... All 4-2. 환경 구분
환경 용도 Production main 브랜치 배포 Preview PR 프리뷰 배포 Development 로컬 개발 4-3. 로컬에서 환경변수 사용
`bashvercel CLI 설치
npm i -g vercel
환경변수 가져오기
vercel env pull .env.local
`
5. vercel.json 설정
5-1. 기본 설정
`json{
"version": 2,
"name": "my-project",
"buildCommand": null,
"outputDirectory": ".",
"framework": null
}
`5-2. 리다이렉트/리라이트
`json{
"rewrites": [
{
"source": "/api/:path*",
"destination": "/api/:path*"
}
],
"redirects": [
{
"source": "/old-page",
"destination": "/new-page",
"permanent": true
}
]
}
`5-3. CORS 헤더
`json{
"headers": [
{
"source": "/api/(.*)",
"headers": [
{ "key": "Access-Control-Allow-Credentials", "value": "true" },
{ "key": "Access-Control-Allow-Origin", "value": "*" },
{ "key": "Access-Control-Allow-Methods", "value": "GET,POST,PUT,DELETE,OPTIONS" },
{ "key": "Access-Control-Allow-Headers", "value": "Content-Type, Authorization" }
]
}
]
}
`5-4. 함수 설정
`json{
"functions": {
"api/*/.js": {
"maxDuration": 30,
"memory": 1024
}
}
}
`옵션 설명 무료 제한 maxDuration 최대 실행 시간 (초) 10초 memory 메모리 (MB) 1024MB
6. 도메인 연결
6-1. 도메인 추가
- Project → Settings → Domains
- 도메인 입력:
www.example.com- Add
6-2. DNS 설정
Vercel이 제공하는 값을 DNS에 추가:
Type Name Value A www 76.76.21.21 TXT _vercel vc-domain-verify=... 6-3. www vs apex 도메인
`www.example.com ← 권장 (A 레코드)
example.com ← apex 도메인 (CNAME 불가)
`팁: www를 기본으로 하고, apex에서 www로 리다이렉트
7. 배포 전략
7-1. 브랜치별 배포
브랜치 배포 대상 URL main Production example.com develop Preview develop-xxx.vercel.app feature/* Preview feature-xxx.vercel.app 7-2. 롤백
- Project → Deployments
- 이전 배포 선택
- ... → Promote to Production
7-3. 배포 보호
Settings → General → Production Branch Protection
- 특정 브랜치만 프로덕션 배포 허용
8. 로그 및 모니터링
8-1. 함수 로그
- Project → Logs
- 필터:
- Production / Preview
- Success / Error
- 함수 이름
8-2. 로그 작성
`javascript// 콘솔 출력이 로그에 기록됨
export default function handler(req, res) {
console.log('요청 받음:', req.method, req.url);
console.log('Body:', req.body);
res.status(200).json({ success: true });
}
`8-3. 에러 추적
`javascriptexport default async function handler(req, res) {
try {
// 비즈니스 로직
const result = await doSomething();
res.status(200).json(result);
} catch (error) {
console.error('에러 발생:', error);
res.status(500).json({ error: error.message });
}
}
`
9. 실전 팁
9-1. Cold Start 대응
서버리스 함수는 첫 실행 시 느릴 수 있음 (Cold Start).
완화 방법:
- 함수 크기 줄이기 (불필요한 import 제거)
- Edge Functions 사용 (무료 플랜에서도 사용 가능)
9-2. 정적 파일 캐싱
`json{
"headers": [
{
"source": "/assets/(.*)",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
]
}
]
}
`9-3. SPA 라우팅
`json{
"rewrites": [
{ "source": "/(.*)", "destination": "/index.html" }
]
}
`
10. 문제 해결
문제 1: 함수 타임아웃
증상: 10초 초과로 함수 종료
해결:
- 함수 최적화 (DB 쿼리 개선)
- Pro 플랜으로 maxDuration 증가
- 비동기 처리 (큐 사용)
문제 2: 404 에러
증상: 페이지/API 찾을 수 없음
해결:
- Root Directory 확인
- 파일 경로 대소문자 확인 (Linux는 대소문자 구분)
- vercel.json rewrites 확인
문제 3: CORS 에러
증상: 브라우저에서 API 호출 실패
해결:
- vercel.json에 CORS 헤더 추가
- OPTIONS 요청 처리 추가
정리
Vercel은 프론트엔드 + 서버리스 배포 플랫폼입니다.
핵심 기능:
- Git push → 자동 배포
/api폴더 → 서버리스 함수- 환경변수 → Dashboard에서 설정
- 도메인 → DNS A/TXT 레코드
무료 티어로 충분:
- 개인 프로젝트/사이드 프로젝트
- 상업용은 Pro 플랜 필요 (2025년부터 엄격)
작성일: 2025-12-21 / 작성자: Claude Code
3333편 | 심화 - Resend33편 | 심화 - Resend
14편에서 외부 서비스로 Resend를 소개했습니다. 이번 편에서는 Resend를 사용해 이메일을 발송하는 실전 방법을 다룹니다.
1. Resend란
1-1. 정의
Resend는 개발자를 위한 이메일 API 서비스입니다. 회원가입 인증, 비밀번호 재설정, 알림 등 트랜잭셔널 이메일을 쉽게 발송합니다.
1-2. 왜 Resend인가
장점 설명 간단한 API 몇 줄의 코드로 이메일 발송 높은 전달률 스팸함에 안 가도록 최적화 React Email React로 이메일 템플릿 작성 무료 티어 월 3,000통 무료 1-3. 무료 티어 제한
항목 무료 제한 월 발송량 3,000통 일 발송량 100통 도메인 1개 API 키 무제한
2. 설정하기
2-1. 계정 생성
- https://resend.com 접속
- GitHub 또는 Google로 가입
- Dashboard 접속
2-2. API 키 생성
- API Keys → Create API Key
- 이름 입력 (예:
production)- Permission: Full access 또는 Sending access
- 키 복사 (한 번만 표시!)
`re_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
`2-3. 도메인 인증 (선택)
기본은
onboarding@resend.dev로 발송됩니다.자체 도메인 사용 시:
- Domains → Add Domain
- 도메인 입력 (예:
mail.example.com)- DNS 레코드 추가:
Type Name Value MX mail feedback-smtp.resend.com TXT mail v=spf1 include:resend.com ~all TXT resend._domainkey.mail 제공된 값
3. 기본 사용법
3-1. 설치
`bashnpm install resend
`3-2. 기본 발송
`javascriptimport { Resend } from 'resend';
const resend = new Resend('re_xxxxx...');
async function sendEmail() {
const { data, error } = await resend.emails.send({
from: 'onboarding@resend.dev', // 또는 자체 도메인
to: 'user@example.com',
subject: '안녕하세요!',
html: '
이메일 본문입니다.
'});
if (error) {
console.error('발송 실패:', error);
return;
}
console.log('발송 성공:', data.id);
}
`3-3. 여러 수신자
`javascriptawait resend.emails.send({
from: 'noreply@example.com',
to: ['user1@example.com', 'user2@example.com'],
subject: '공지사항',
html: '
중요 공지입니다.
'});
`3-4. CC/BCC
`javascriptawait resend.emails.send({
from: 'noreply@example.com',
to: 'user@example.com',
cc: ['manager@example.com'],
bcc: ['admin@example.com'],
subject: '보고서',
html: '
첨부 보고서입니다.
'});
`
4. HTML 이메일 템플릿
4-1. 간단한 템플릿
`javascriptfunction welcomeEmailTemplate(name) {
return `
body { font-family: Arial, sans-serif; line-height: 1.6; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { background: #3b82f6; color: white; padding: 20px; text-align: center; }
.content { padding: 20px; }
.button { display: inline-block; background: #3b82f6; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; }
환영합니다!
`;
}
// 사용
await resend.emails.send({
from: 'SSALWorks
', to: 'user@example.com',
subject: 'SSALWorks에 오신 것을 환영합니다!',
html: welcomeEmailTemplate('홍길동')
});
`4-2. 이메일 인증 템플릿
`javascriptfunction verificationEmailTemplate(code) {
return `
.code { font-size: 32px; font-weight: bold; letter-spacing: 4px; color: #3b82f6; }
이메일 인증
아래 인증 코드를 입력해주세요:
${code}
이 코드는 10분간 유효합니다.
본인이 요청하지 않았다면 이 이메일을 무시하세요.
`;
}
`4-3. 비밀번호 재설정 템플릿
`javascriptfunction passwordResetTemplate(resetLink) {
return `
비밀번호 재설정
비밀번호 재설정을 요청하셨습니다.
아래 버튼을 클릭하여 새 비밀번호를 설정하세요:
이 링크는 1시간 후 만료됩니다.
본인이 요청하지 않았다면 이 이메일을 무시하세요.
`;
}
`
5. Vercel 서버리스 함수에서 사용
5-1. 환경변수 설정
Vercel Dashboard → Settings → Environment Variables:
Key Value RESEND_API_KEY re_xxxxx... 5-2. API 함수 작성
`javascript// api/email/send-welcome.js
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
export default async function handler(req, res) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
const { email, name } = req.body;
if (!email || !name) {
return res.status(400).json({ error: 'email과 name이 필요합니다' });
}
try {
const { data, error } = await resend.emails.send({
from: 'SSALWorks
', to: email,
subject: 'SSALWorks에 오신 것을 환영합니다!',
html:
안녕하세요, ${name}님! 가입을 환영합니다.
});
if (error) {
console.error('Resend 에러:', error);
return res.status(500).json({ error: error.message });
}
return res.status(200).json({ success: true, id: data.id });
} catch (error) {
console.error('발송 실패:', error);
return res.status(500).json({ error: '이메일 발송 실패' });
}
}
`5-3. 프론트엔드에서 호출
`javascriptasync function sendWelcomeEmail(email, name) {
const response = await fetch('/api/email/send-welcome', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, name })
});
const result = await response.json();
if (result.success) {
console.log('이메일 발송 완료');
} else {
console.error('발송 실패:', result.error);
}
}
`
6. 실전 예시: 이메일 인증 시스템
6-1. 인증 코드 생성
`javascriptfunction generateVerificationCode() {
return Math.floor(100000 + Math.random() * 900000).toString();
}
`6-2. 인증 코드 발송 API
`javascript// api/email/send-verification.js
import { Resend } from 'resend';
import { createClient } from '@supabase/supabase-js';
const resend = new Resend(process.env.RESEND_API_KEY);
const supabase = createClient(
process.env.SUPABASE_URL,
process.env.SUPABASE_SERVICE_ROLE_KEY
);
export default async function handler(req, res) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
const { email } = req.body;
// 인증 코드 생성
const code = Math.floor(100000 + Math.random() * 900000).toString();
const expiresAt = new Date(Date.now() + 10 60 1000); // 10분 후
// DB에 저장
const { error: dbError } = await supabase
.from('verification_codes')
.upsert({
email,
code,
expires_at: expiresAt.toISOString()
});
if (dbError) {
return res.status(500).json({ error: 'DB 저장 실패' });
}
// 이메일 발송
const { error: emailError } = await resend.emails.send({
from: 'SSALWorks
', to: email,
subject: '[SSALWorks] 이메일 인증 코드',
html: `
이메일 인증
아래 인증 코드를 입력해주세요:
${code}
이 코드는 10분간 유효합니다.
`
});
if (emailError) {
return res.status(500).json({ error: '이메일 발송 실패' });
}
return res.status(200).json({ success: true });
}
`6-3. 인증 코드 확인 API
`javascript// api/email/verify-code.js
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(
process.env.SUPABASE_URL,
process.env.SUPABASE_SERVICE_ROLE_KEY
);
export default async function handler(req, res) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
const { email, code } = req.body;
// DB에서 코드 확인
const { data, error } = await supabase
.from('verification_codes')
.select('*')
.eq('email', email)
.eq('code', code)
.gt('expires_at', new Date().toISOString())
.single();
if (error || !data) {
return res.status(400).json({ error: '잘못된 인증 코드입니다' });
}
// 사용된 코드 삭제
await supabase
.from('verification_codes')
.delete()
.eq('email', email);
return res.status(200).json({ success: true, verified: true });
}
`
7. 이메일 작성 팁
7-1. 스팸 방지
- From 주소: 인증된 도메인 사용
- 제목: 스팸 키워드 피하기 (무료, 긴급 등)
- 본문: HTML/텍스트 비율 적절히
- 구독 취소: 링크 포함 (마케팅 이메일)
7-2. 이메일 클라이언트 호환성
`html내용 font-family: Arial, Helvetica, sans-serif;
`7-3. 테스트
- 실제 이메일로 발송 테스트
- Gmail, Outlook, 네이버 등 여러 클라이언트 확인
- 모바일에서도 확인
8. 문제 해결
문제 1: 스팸함으로 분류
해결:
- 도메인 인증 (SPF, DKIM)
- From 주소 일관성 유지
- 구독 취소 링크 추가
문제 2: 발송 한도 초과
해결:
- 일일 100통 제한 확인
- 유료 플랜 업그레이드
- 발송 큐 구현
문제 3: 이미지가 안 보임
해결:
- 절대 URL 사용
- alt 텍스트 추가
- 이미지 호스팅 서비스 사용
정리
Resend는 개발자 친화적인 이메일 API입니다.
핵심 사용법:
resend.emails.send()로 발송- HTML 템플릿으로 디자인
- 환경변수로 API 키 관리
무료 티어로 충분:
- 월 3,000통, 일 100통
- 개인 프로젝트에 적합
도메인 인증하면 전달률이 높아집니다.
작성일: 2025-12-21 / 작성자: Claude Code
34부록 | 용어 사전부록 | 용어 사전
2권에서 다룬 핵심 용어들을 정리한 사전입니다. 알파벳 순으로 정렬되어 있습니다.
A
API (Application Programming Interface)
프로그램 간 통신을 위한 인터페이스입니다. REST API, GraphQL 등이 있습니다.
async/await
JavaScript의 비동기 처리 문법입니다. Promise를 더 읽기 쉽게 작성할 수 있습니다.
Authentication (인증)
"누구인가?"를 확인하는 과정입니다. 로그인이 대표적인 예입니다.
Authorization (인가)
"무엇을 할 수 있는가?"를 확인하는 과정입니다. 권한 확인입니다.
ARIA (Accessible Rich Internet Applications)
웹 접근성을 높이기 위한 HTML 속성입니다. 스크린 리더가 이해할 수 있도록 정보를 제공합니다.
B
BaaS (Backend as a Service)
백엔드 기능을 서비스로 제공하는 형태입니다. Supabase, Firebase가 대표적입니다.
Bash
유닉스 쉘 스크립트 언어입니다. 서버 자동화에 사용됩니다.
Brotli
Google이 개발한 압축 알고리즘입니다. Gzip보다 높은 압축률을 제공합니다.
Bundle
여러 JavaScript 파일을 하나로 합친 것입니다. Webpack, Vite가 생성합니다.
C
CDN (Content Delivery Network)
전 세계에 분산된 서버 네트워크입니다. 사용자와 가까운 서버에서 콘텐츠를 제공합니다.
CI/CD
Continuous Integration / Continuous Deployment의 약자입니다. 자동 빌드/배포 파이프라인입니다.
CLI (Command Line Interface)
텍스트 명령어로 컴퓨터를 조작하는 인터페이스입니다. 터미널에서 사용합니다.
CLS (Cumulative Layout Shift)
레이아웃 밀림 정도를 측정하는 지표입니다. 0.1 미만이 좋습니다.
Component
UI의 재사용 가능한 조각입니다. React의 핵심 개념입니다.
CSS (Cascading Style Sheets)
웹 페이지의 스타일을 정의하는 언어입니다.
D
DOM (Document Object Model)
HTML 문서를 트리 구조로 표현한 것입니다. JavaScript로 조작합니다.
defer
스크립트를 DOM 파싱 후에 실행하는 속성입니다. 순서가 보장됩니다.
E
Edge Runtime
CDN 엣지에서 실행되는 경량 런타임입니다. 빠른 응답이 특징입니다.
E2E Test (End-to-End Test)
실제 사용자 시나리오를 테스트하는 방법입니다. Playwright가 대표적입니다.
ESLint
JavaScript 코드 품질 검사 도구입니다. 문법 오류와 스타일을 체크합니다.
External Service (외부 서비스)
외부에서 API로 제공받는 서비스입니다. Supabase, Vercel, Resend 등이 있습니다.
F
FCP (First Contentful Paint)
첫 콘텐츠가 화면에 그려지는 시점입니다.
FID (First Input Delay)
첫 상호작용에 대한 응답 시간입니다. 100ms 미만이 좋습니다.
Framework (프레임워크)
애플리케이션 구조를 제공하는 도구입니다. Next.js가 대표적입니다.
G
Git
분산 버전 관리 시스템입니다. 코드 변경 이력을 관리합니다.
GitHub
Git 저장소 호스팅 서비스입니다. 코드 협업 플랫폼입니다.
GitHub Actions
GitHub의 CI/CD 서비스입니다. 자동화 워크플로우를 실행합니다.
H
Hook
React의 상태 관리 함수입니다. useState, useEffect 등이 있습니다.
HTML (HyperText Markup Language)
웹 페이지의 구조를 정의하는 마크업 언어입니다.
HTTPS
HTTP + TLS 암호화입니다. 보안 연결을 제공합니다.
I
ISR (Incremental Static Regeneration)
정적 페이지를 점진적으로 재생성하는 기술입니다. Next.js의 기능입니다.
J
JavaScript
웹의 동적 기능을 담당하는 프로그래밍 언어입니다.
Jest
JavaScript 테스트 프레임워크입니다. 단위 테스트에 사용됩니다.
JSON (JavaScript Object Notation)
데이터 교환 형식입니다. API 응답에 주로 사용됩니다.
JSX
JavaScript + XML 문법입니다. React 컴포넌트를 작성합니다.
JWT (JSON Web Token)
토큰 기반 인증 방식입니다. 세션 관리에 사용됩니다.
L
Language (언어)
코드를 작성하는 프로그래밍 언어입니다. HTML, CSS, JavaScript, TypeScript, SQL 등이 있습니다.
LCP (Largest Contentful Paint)
가장 큰 콘텐츠가 로딩되는 시점입니다. 2.5초 미만이 좋습니다.
Library (라이브러리)
특정 기능을 제공하는 코드 모음입니다. 개발자가 호출합니다.
Lighthouse
Chrome의 웹 품질 측정 도구입니다. 성능, 접근성 등을 점수화합니다.
Lint
코드 품질 검사입니다. ESLint가 대표적입니다.
M
Middleware
요청과 응답 사이에서 실행되는 코드입니다. 인증 확인 등에 사용됩니다.
Mock
테스트용 가짜 객체입니다. 외부 의존성을 대체합니다.
N
Next.js
React 기반 풀스택 프레임워크입니다. SSR, SSG, ISR을 지원합니다.
Node.js
JavaScript 서버 런타임입니다. Chrome V8 엔진 기반입니다.
npm (Node Package Manager)
Node.js 패키지 관리자입니다. 라이브러리 설치에 사용됩니다.
O
OAuth
타사 서비스로 로그인하는 표준 프로토콜입니다. Google, Kakao 로그인에 사용됩니다.
ORM (Object-Relational Mapping)
객체와 데이터베이스 테이블을 매핑하는 기술입니다.
P
PaaS (Platform as a Service)
플랫폼을 서비스로 제공하는 형태입니다. Vercel이 대표적입니다.
Package Manager (패키지 관리자)
라이브러리를 설치하고 관리하는 도구입니다. npm, yarn, pnpm이 있습니다.
Playwright
E2E 테스트 도구입니다. 브라우저 자동화를 지원합니다.
PostgreSQL
오픈소스 관계형 데이터베이스입니다. Supabase가 사용합니다.
Prettier
코드 포맷팅 도구입니다. 일관된 코드 스타일을 유지합니다.
Promise
JavaScript의 비동기 처리 객체입니다. async/await의 기반입니다.
R
React
UI 라이브러리입니다. 컴포넌트 기반 개발을 지원합니다.
Resend
이메일 발송 외부 서비스입니다. API로 트랜잭션 이메일을 전송합니다.
REST (Representational State Transfer)
API 설계 스타일입니다. HTTP 메서드(GET, POST 등)를 사용합니다.
RLS (Row Level Security)
행 단위 보안 정책입니다. Supabase/PostgreSQL에서 지원합니다.
Runtime (런타임)
코드가 실행되는 환경입니다. Node.js, Browser, Edge가 있습니다.
S
SaaS (Software as a Service)
소프트웨어를 서비스로 제공하는 형태입니다.
Socket.io
실시간 양방향 통신 라이브러리입니다. WebSocket 기반입니다.
SEO (Search Engine Optimization)
검색 엔진 최적화입니다. 검색 순위를 높이는 기술입니다.
SQL (Structured Query Language)
데이터베이스 쿼리 언어입니다. SELECT, INSERT 등의 명령어가 있습니다.
SSG (Static Site Generation)
빌드 시 HTML을 미리 생성하는 방식입니다. 가장 빠릅니다.
SSR (Server-Side Rendering)
서버에서 HTML을 생성하는 방식입니다. SEO에 유리합니다.
State
컴포넌트의 상태 데이터입니다. 변경 시 UI가 업데이트됩니다.
Supabase
오픈소스 BaaS(Backend as a Service) 외부 서비스입니다. PostgreSQL, Auth, Storage를 제공합니다.
T
Tailwind CSS
유틸리티 기반 CSS 프레임워크입니다. 클래스명으로 스타일링합니다.
Thunder Client
VS Code 확장 프로그램입니다. API 테스트에 사용됩니다.
TDD (Test-Driven Development)
테스트를 먼저 작성하는 개발 방법론입니다.
Tools (도구)
개발을 도와주는 프로그램입니다. ESLint, Prettier, Vite 등이 있습니다.
Tree Shaking
사용하지 않는 코드를 제거하는 최적화 기술입니다.
TTI (Time to Interactive)
페이지가 상호작용 가능해지는 시점입니다.
TypeScript
JavaScript + 정적 타입입니다. 컴파일 시 타입 오류를 잡습니다.
U
Unit Test
함수나 컴포넌트 단위의 테스트입니다. Jest가 대표적입니다.
UUID
고유 식별자입니다. 데이터베이스 기본키에 사용됩니다.
V
Vercel
Next.js를 만든 회사의 호스팅 외부 서비스입니다. 자동 배포, CDN을 제공합니다.
Vite
빠른 개발 서버와 빌드 도구입니다. Webpack보다 빠릅니다.
VS Code (Visual Studio Code)
Microsoft가 만든 코드 에디터입니다. 확장 기능이 풍부합니다.
W
WCAG (Web Content Accessibility Guidelines)
웹 접근성 지침입니다. 4대 원칙(인식, 운용, 이해, 견고)을 정의합니다.
Webpack
모듈 번들러입니다. JavaScript 파일을 하나로 합칩니다.
WebSocket
양방향 실시간 통신 프로토콜입니다. 채팅, 알림에 사용됩니다.
X
XaaS (X as a Service)
서비스로 제공되는 것들의 총칭입니다. IaaS, PaaS, BaaS, SaaS 등이 있습니다.
Y
YAML
설정 파일 형식입니다. GitHub Actions 워크플로우에 사용됩니다.
Z
Zod
TypeScript 스키마 검증 라이브러리입니다. 런타임 타입 검증을 제공합니다.
Zustand
React 상태 관리 라이브러리입니다. Redux보다 간단합니다.
SSALWorks 기술 스택 요약
7가지 기술 스택
기술 스택 설명 SSALWorks 선택 Language 프로그래밍 언어 HTML, CSS, JavaScript, **TypeScript**, SQL Runtime 실행 환경 **Browser**, **Node.js**, Edge Runtime Package Manager 패키지 관리자 **npm** Tools 개발 도구 **ESLint**, **Prettier**, **Vite** Library 라이브러리 **React**, Zustand, Zod, Jest Framework 프레임워크 **Next.js**, **Tailwind CSS** External Service 외부 서비스 **Supabase**, **Vercel**, Resend 7가지 개발 영역
개발 영역 설명 핵심 기술 Frontend 사용자 인터페이스 Next.js, React, Tailwind CSS Backend Infra 백엔드 기반 시설 Node.js, Resend Backend API API 개발 Next.js API Routes, Zod Database 데이터베이스 PostgreSQL, Supabase Security 보안/인증 Supabase Auth, OAuth Testing 테스트 Jest, Playwright DevOps 배포/운영 Vercel, GitHub Actions
작성일: 2025-12-21 / 글자수: 약 6,200자 / 작성자: Claude / 프롬프터: 써니
- ,