728x90

**MCP(Model Context Protocol)**는 AI Agent가 외부 도구나 리소스(API, 데이터베이스, 크롤러 등)와 표준화된 방식으로 연결되도록 돕는 프로토콜이에요.
쉽게 말해, USB-C 포트처럼 LLM을 다양한 시스템과 연결하는 통로라고 볼 수 있죠.

이번에는 MCP 스타일로 JSON-RPC 통신을 흉내 내는 간단한 Node.js 예시 코드를 작성해봤습니다.
MCP가 어떻게 Host ↔ Client 간에 메시지를 주고받는지 이해하는 데 도움이 될 거예요.


✅ MCP 스타일 JSON-RPC 예제

예제 시나리오

  • 사용자가 “2 + 3 계산해줘” 요청
  • Host가 MathClient에게 계산 요청
  • MathClient가 계산 후 결과 반환
  • Host가 사용자에게 결과 전달

1. Math Client(Server 역할)

실제로는 MCP Client이지만, 네트워크 상에서 JSON-RPC Server로 동작하는 구조

// mathClient.js
import express from "express";
import bodyParser from "body-parser";

const app = express();
app.use(bodyParser.json());

app.post("/rpc", (req, res) => {
  const { method, params, id } = req.body;

  console.log("요청 받음:", method, params);

  if (method === "add") {
    const result = params.a + params.b;
    res.json({
      jsonrpc: "2.0",
      result,
      id,
    });
  } else {
    res.json({
      jsonrpc: "2.0",
      error: {
        code: -32601,
        message: "Method not found",
      },
      id,
    });
  }
});

app.listen(4000, () => {
  console.log("Math Client (Server) running on http://localhost:4000/rpc");
});

2. Host 역할

실제 MCP Host처럼 Client에게 JSON-RPC 메시지를 보내는 코드

// host.js
import axios from "axios";

async function callMathClient() {
  const payload = {
    jsonrpc: "2.0",
    method: "add",
    params: {
      a: 2,
      b: 3,
    },
    id: 1,
  };

  const response = await axios.post(
    "http://localhost:4000/rpc",
    payload,
    { headers: { "Content-Type": "application/json" } }
  );

  console.log("Math Client 응답:", response.data);
}

callMathClient();

실행 순서

1. Math Client 실행

node mathClient.js

2. Host 실행

node host.js

3. 출력 결과

Math Client 응답: { jsonrpc: '2.0', result: 5, id: 1 }

✅ MCP 스타일로 이해하기

이 예제는 MCP의 작동 방식을 아주 단순화한 것이지만, 개념적으로는 똑같아요:

  • 사용자 → “2+3 계산해줘”
  • Host → 어떤 Client가 처리할지 판단 (Planner 역할)
  • Math Client → 계산 수행
  • Host → 사용자에게 결과 반환

MCP의 실제 동작

실제 MCP 환경에서는:

✅ JSON-RPC 규격 메시지 사용
✅ Tool마다 Client로 분리 → 재사용 가능
✅ Host가 Plan → Execute → Observe 루프 제어
✅ 멀티 Agent, 멀티 Tool 관리 가능

예)

  • Weather API Client
  • DB Query Client
  • Web Browser Client
  • Code Executor Client

이처럼 MCP는 LLM Agent 개발의 USB-C 포트 같은 표준 역할을 하며, AI가 더 넓은 세상과 연결될 수 있도록 돕고 있습니다. 🚀

728x90
728x90

MCP란 무엇인가? LLM Agent 동작 흐름으로 이해하는 Model Context Protocol

최근 AI 개발 분야에서 가장 많이 회자되는 키워드 중 하나가 LLM Agent입니다.
ChatGPT, Claude 같은 LLM(Large Language Model)이 단발성 질의응답에 주로 쓰였다면, 이제는 도구를 스스로 호출하고 복잡한 작업을 계획-실행-관찰 루프(Plan-Execute-Observe Loop)로 수행하는 LLM Agent가 새로운 트렌드로 떠오르고 있죠.

그런데 이렇게 복잡해진 에이전트 개발 생태계에 새로운 표준을 제안한 것이 바로 **MCP (Model Context Protocol)**입니다.

오늘은 LLM과 LLM Agent의 차이를 간단히 비교하고, MCP가 어떤 구조와 동작 원리로 작동하는지 살펴보겠습니다.


✅ LLM vs LLM Agent — 무엇이 다를까?

먼저 아래 표를 보면서 간단히 정리해 볼게요.

항목LLMLLM Agent
주요 역할 단발성 언어 작업 (요약, 번역) 계획-실행-관찰 루프로 복잡한 태스크 수행
Memory 없음 있음 (대화 기록, 작업 히스토리 기억)
Tool 사용 불가능 가능 (API, 계산, DB, 웹검색 등)
Planner 없음 있음 (도구를 언제, 어떻게 쓸지 판단)
실행 방식 정적 응답 (입력 → 출력) 동적 행동 (입력 → 툴 호출 → 결과 해석 → 반복)
유연성 낮음 높음 (실시간 검색, 계산, API 활용)
지속적 작업 어려움 가능 (장기 과제, 다단계 플로우)
 

예를 들어 사용자가 “오늘 서울 날씨 알려줘”라고 물었을 때,

  • LLM은 기존에 학습한 지식으로 “오늘 서울은 맑고 기온은 26도”라고 대답하지만,
  • LLM Agent는 실제 날씨 API를 호출해 최신 데이터를 가져와서 답변합니다.

✅ MCP란 무엇인가?

**MCP (Model Context Protocol)**는 LLM Agent 개발을 위한 표준 프로토콜입니다.

  • Claude LLM을 제공하는 Anthropic이 주도적으로 제안
  • AI 앱 개발 생태계의 USB-C 포트 역할
    • USB-C가 여러 장치를 표준 방식으로 연결하듯,
    • MCP는 다양한 데이터 소스, 도구, 외부 리소스를 LLM과 연결하는 표준화된 방법을 제공

기존 Agent 프레임워크들이 제각각이던 방식을 통합하고자 등장한 것이 바로 MCP예요.


✅ MCP의 기본 구조

MCP는 크게 Host, Client, Server 세 가지로 이루어져 있습니다.

  • Host
    • 전체 Agent를 실행하고 관리
    • 여러 Client와 연결되어, 작업을 분배하거나 통제
  • Client
    • 실제 LLM 모델 또는 특정 기능(API 호출, DB 쿼리 등)을 실행
    • Host의 요청을 받아 실행 후 결과 반환
  • Server
    • MCP 메시지를 송수신하는 실제 서버
    • JSON-RPC 기반으로 통신

이렇게 역할을 나누어 MCP는 다음과 같은 흐름으로 작동합니다:

  1. 사용자가 “서울 날씨 알려줘”라고 Host에 요청
  2. Host는 해당 요청을 “WeatherAPI Client”에 전달
  3. Client가 실제 API 호출 → 결과를 JSON 형태로 응답
  4. Host가 응답을 정리해 사용자에게 전달

✅ MCP의 장점과 한계

장점

  • 여러 Agent 프레임워크를 하나의 표준으로 통합 가능
  • 개발자들이 공통 규격으로 플러그인 개발 가능
  • Tool 호출, Context 관리 등을 효율적으로 처리

한계

  • 아직 초기 표준 → 생태계가 완전히 자리잡지 않음
  • 벤더별 커스텀 규격이 여전히 존재
  • 속도 및 비용 이슈 (API 호출 많아질수록 비용 증가)

하지만 LLM Agent 시대가 본격화되면서, MCP가 “AI의 USB-C”로 자리 잡을 가능성은 충분히 큽니다.


✅ MCP SDK

MCP를 직접 다뤄보려면 Anthropic이나 오픈소스 커뮤니티에서 제공하는 MCP SDK를 활용할 수 있습니다.

  • JSON-RPC 기반으로 MCP 메시지를 주고받음
  • Node.js, Python 등 여러 언어 SDK가 준비 중
  • 커스텀 Client 개발 가능 (예: 크롤러, DB 쿼리, 특정 API 호출 등)

추후 더 많은 예제 코드와 함께 MCP SDK 활용법도 다뤄보겠습니다!


LLM Agent 시대에는 단순히 대답만 하는 모델로는 부족합니다.
여러 도구를 호출하고, 데이터를 가공하며, 더 유연하게 동작할 수 있어야 하죠.

MCP는 이 흐름을 뒷받침할 중요한 표준 프로토콜입니다.
AI와 개발이 더욱 긴밀하게 연결될 미래를 기대해 봅니다. 🚀

혹시 MCP나 LLM Agent 관련해 더 다뤄보고 싶은 주제가 있다면 댓글로 알려 주세요!

728x90
728x90

AI 증강 개발(AI-Augmented Development)이란 무엇인가요?

최근 개발 트렌드에서 빼놓을 수 없는 키워드가 바로 AI 증강 개발입니다.
이는 개발자와 AI가 협업하여 생산성과 코드 품질을 높이는 방식을 의미합니다.
즉, AI가 개발자를 대체하는 것이 아니라, 개발자가 더 창의적이고 고차원적인 문제 해결에 집중할 수 있도록 개발 과정을 보조해 주는 것이 핵심이에요.


AI 증강 개발의 주요 기능

1. 코드 생성 및 완성

  • AI가 문맥을 이해해 적절한 코드를 제안
  • 보일러플레이트 코드 자동 생성

2. 코드 리뷰 및 품질 향상

  • 버그, 보안 취약점, 코드 스타일 검사
  • 성능 개선 포인트 제안

3. 문서화 지원

  • 주석 생성, API 문서 작성, 기술 문서 초안 작성

4. 디버깅 지원

  • 에러 원인 분석, 해결책 제시, 로그 분석

5. 지식 관리

  • 코드베이스 이해 돕기
  • 관련 문서 및 자료 추천
  • 팀 내 지식 공유 촉진

Cursor AI Notepad로 AI 증강 개발 가속화하기

Cursor AI가 제공하는 Notepad는 AI 증강 개발을 한층 효율적으로 만드는 도구예요.
Notepad는 Composer와 채팅 사이에서 컨텍스트를 공유하는 메모장 같은 존재입니다.

특히 개발자들이 자주 참조하는 규칙, 코드 템플릿, 문서 등을 한 곳에 정리해 두고 @ 멘션으로 불러올 수 있는 점이 매우 강력합니다.


Notepad의 활용 사례

동적 보일러플레이트 생성
→ API 핸들러, 컴포넌트 템플릿, 서비스 생성 규칙 등을 저장

아키텍처 문서화
→ 프론트/백엔드 구조, 데이터 모델 설계, 시스템 아키텍처 가이드라인 정리

코딩 가이드라인
→ 코딩 컨벤션, 네이밍 규칙, 커밋 메시지 규칙 등 공유

팀 규칙 관리
→ 코드 리뷰 절차, 배포 프로세스, 릴리즈 노트 규칙 정리


역할 기반 개발 프로세스

AI 증강 개발의 효과를 극대화하려면 역할 정의가 중요합니다.
아래는 Cursor AI Notepad의 문서 구조와 함께 정리된 대표 역할들입니다.

📝 기획자 (planner.md)

  • 사용자 중심 기획
  • 정보 구조, 기능 명세, 사용자 시나리오 설계
  • PRD(제품 요구사항 정의서), 사용자 여정도, MVP Scope 작성

🖥️ 프론트엔드 개발자 (frontend-ui.md)

  • UX/UI 중심 개발
  • 반응형, 애니메이션, 디자인 시스템 구현
  • 성능 최적화, 컴포넌트 재사용성 극대화

🛠️ 풀스택 개발자 (fullstack.md)

  • Next.js, TypeScript, Notion API 기반 개발
  • AI 도구를 활용한 개발 최적화
  • 코드 품질 관리, 생산성 향상

🌐 번역가

  • 공식 문서 번역
  • 신속한 지식 습득 지원

각 역할별로 마크다운 문서로 정리해두면, 팀 내 지식 공유와 커뮤니케이션이 훨씬 원활해집니다.


PRD와 SRS, 그리고 MVP

AI 증강 개발은 문서화도 매우 중요합니다.

  • PRD (Product Requirements Document)
    → 제품이 무엇인지, 누구를 위한 것인지, 왜 필요한지를 비즈니스 관점에서 설명
  • SRS (Software Requirements Specification)
    → 제품을 어떻게 만들 것인지, 아키텍처와 기술 명세를 기술 관점에서 설명
  • MVP (Minimum Viable Product)
    → 최소한의 기능만 담은 초기 제품으로, 핵심 가치를 검증하는 것이 목표

이러한 문서들이 Cursor AI Notepad에 정리되어 있으면 팀 전체의 이해도와 속도가 크게 높아집니다.


AI가 개발을 대체하는 시대는 아닙니다.
다만, AI는 개발자의 가장 든든한 비서이자 동료가 될 수 있습니다.

앞으로 AI와 함께 더 똑똑하고 빠르게 개발해보세요! 🚀

혹시 이 내용 중 더 자세히 알고 싶은 주제 있으신가요? 댓글로 알려주세요!

728x90
728x90

비동기, Promise, async/await 확실히 이해하기 — 택배 배달로 비유해 보자!

자바스크립트를 공부하다 보면 꼭 마주치는 말:

비동기(Asynchronous)

그런데 도대체 “비동기”가 뭐길래 개발자들을 이토록 괴롭힐까요?
오늘은 택배 비유로 풀어보겠습니다.


동기(Synchronous)란?

택배 아저씨 올 때까지 문 앞에서 꼼짝 않고 기다리는 것

  • 작업이 순서대로 하나하나 끝나야 다음으로 넘어갑니다.
  • 택배가 늦으면 다른 일은 못 하고 계속 기다림.

코드 예시

 
console.log("주문하기");
console.log("배송 도착");
console.log("택배 개봉");
 

출력:

 
주문하기
배송 도착
택배 개봉

비동기(Asynchronous)란?

택배 시키고 다른 일 먼저 하다가, 택배 오면 다시 처리하는 것

  • 택배가 오는 동안 다른 일을 할 수 있어요.
  • 웹 개발에서 가장 흔한 비동기 작업: API 요청, 파일 읽기, 타이머 등

코드 예시

console.log("주문하기");
setTimeout(() => {
  console.log("배송 도착");
}, 3000);
console.log("다른 일 하기");

출력:

주문하기
다른 일 하기
(3초 후) 배송 도착

비동기 처리 방법 ① — 콜백(callback)

택배기사님이 도착하면 “전화 주시라고” 부탁하는 것

  • 콜백 지옥(callback hell) 문제가 생길 수 있음.
  • 코드가 중첩되어 점점 읽기 어려워짐.

예:

setTimeout(() => {
  console.log("택배 도착!");
  setTimeout(() => {
    console.log("택배 개봉!");
  }, 1000);
}, 2000);

비동기 처리 방법 ② — Promise

택배사에서 ‘배송 추적 번호’를 주는 것

  • “언젠간 올 거”라는 약속을 반환.
  • 성공(fulfilled) 또는 실패(rejected)를 알려줌.

비유

택배사가 “이 송장 번호로 배송 상황 확인하세요.”

코드:

let delivery = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("택배 도착!");
  }, 2000);
});

delivery.then((msg) => {
  console.log(msg);
});

출력:

(2초 후) 택배 도착!

비동기 처리 방법 ③ — async / await

택배를 기다리긴 하되, 기다리는 동안 다른 일도 가능하고, 코드는 동기처럼 깔끔

  • async 함수는 항상 Promise를 반환.
  • await은 Promise가 끝날 때까지 기다려줌.
  • 코드가 동기처럼 읽히니 가독성이 좋음!

비유

택배기사님이 오기 전까지 다른 일하다가,
문 두드리면 바로 문 열러 가는 것

코드:

async function getDelivery() {
  console.log("주문하기");
  let result = await new Promise((resolve) => {
    setTimeout(() => {
      resolve("택배 도착!");
    }, 2000);
  });
  console.log(result);
  console.log("택배 개봉");
}

getDelivery();

출력:

주문하기
(2초 후) 택배 도착!
택배 개봉

정리

  • 동기(Sync) → 택배 올 때까지 아무것도 못함
  • 비동기(Async) → 택배 기다리면서 다른 일 가능
  • 콜백 → 택배기사님 전화
  • Promise → 송장 번호로 배송 추적
  • async/await → 깔끔하게 기다렸다 이어서 진행

자바스크립트에서 비동기 처리는 무조건 마주치게 되는 개념이에요.
헷갈릴 때는 “택배” 비유를 꼭 떠올려 보세요.
이해가 훨씬 수월해질 거예요!

혹시 더 깊이 다루고 싶은 부분이나, 다른 비유로 설명해보고 싶으신가요?

728x90
728x90

Next.js 렌더링 이해하기: CSR, SPA, SSR, SSG, ISR을 카페 배달로 비유해보자!

Next.js는 프론트엔드 개발자 사이에서 정말 핫한 프레임워크예요.
이유는 단순해요. 여러 가지 렌더링 방식을 상황에 맞게 섞어 쓸 수 있기 때문이죠.

그런데 개발 공부를 하다 보면 CSR, SSR, SSG, ISR… 이런 약어들이 정말 헷갈리잖아요?
그래서 오늘은 카페 배달 서비스로 비유해보려고 해요.

혹시 커피 좋아하시나요? 좋아하신다면 이 비유가 더욱 쏙쏙 들어올 거예요. ☕


SPA (Single Page Application)

내가 직접 카페 가서 커피 사오는 것

  • 한 번 카페에 입장(페이지 로딩)하면, 그 안에서 메뉴만 바꿔가며 커피를 고릅니다.
  • 화면 전환은 정말 빠르지만, 처음 입장할 때 시간이 조금 걸릴 수 있어요.
  • 웹사이트의 메뉴가 자주 바뀌지 않거나, SEO가 크게 중요하지 않을 때 좋습니다.

예시: React, Vue, Angular 앱


CSR (Client Side Rendering)

카페 앱으로 주문 → 바리스타가 커피 제조 → 완성되면 배달

  • 처음엔 “앱만” 다운로드하고, 커피(화면)는 내 브라우저에서 직접 만들어냅니다.
  • 장점: 페이지 간 전환 속도가 빠르고, 사용자 경험이 부드러움
  • 단점: 처음 앱을 실행할 때 로딩이 느릴 수 있고, 검색 엔진이 내용을 못 볼 수 있음

비유
→ 앱으로 메뉴부터 결제까지 다 해결. 하지만 커피가 오기 전까진 손에 아무것도 없어 불안할 수 있음.


SSR (Server Side Rendering)

카페에서 커피를 미리 만들어서 배달해 주는 것

  • 사용자가 방문하면 서버가 HTML 페이지를 완성해서 보내줍니다.
  • 덕분에 브라우저가 바로 보여줄 수 있고, 초기 로딩이 빠름.
  • SEO에도 아주 유리!

비유
→ 커피 주문하자마자 “짠!” 하고 완성된 커피가 도착.
→ 하지만 매번 새로 만들어야 하니 서버가 조금 바쁨.


SSG (Static Site Generation)

카페가 아침마다 인기 커피를 미리 잔뜩 만들어 진열해 두는 것

  • 서버가 HTML 파일을 “빌드 시점”에 미리 생성해둡니다.
  • 주문이 들어오면 즉시 가져다 주니 엄청 빠르고 가벼움.
  • 단, 콘텐츠가 자주 변하지 않을 때 가장 적합.

비유
→ 인기 메뉴(블로그 글 등)는 미리 진열.
→ 손님이 오면 바로 꺼내 주면 끝!
→ 하지만 신메뉴가 나오면 다시 만들어야 함.


ISR (Incremental Static Regeneration)

카페가 인기 메뉴는 미리 만들어 두되, 일정 주기로 신선하게 교체

  • SSG의 장점(빠름)을 살리면서도, 데이터를 일정 시간마다 새로 가져와서 페이지를 갱신.
  • 즉, 정적 페이지 + 업데이트라는 개념.

비유
→ 인기 메뉴는 미리 진열해두고, 일정 시간 지나면 새로 커피를 만들어 교체.
→ 손님은 언제 와도 신선한 커피를 받을 수 있음.


정리

  • SPA: 한 번 입장 후 내부에서 메뉴만 바꿈
  • CSR: 내 브라우저에서 화면 완성
  • SSR: 서버가 화면 만들어 전송
  • SSG: 서버가 정적 페이지를 미리 만들어 둠
  • ISR: 정적 페이지 + 일정 주기로 새로 갱신

결국 Next.js가 인기인 이유는, 프로젝트 성격에 맞춰 렌더링 방식을 자유롭게 섞어 쓸 수 있다는 점이에요.

👉 정적 블로그엔 SSG,
👉 검색이 중요한 사이트엔 SSR,
👉 페이지가 자주 바뀌는 곳엔 CSR/ISR!

헷갈릴 때는 꼭 카페 배달 비유를 떠올려보세요.
이해가 훨씬 쉬워질 거예요. ☕

혹시 더 궁금한 점이 있거나, 다른 주제로도 비유해볼까요?

728x90
728x90

✅ nvm (Node Version Manager) 설치


nvm 이란?

  • 여러 버전의 Node.js를 손쉽게 설치·전환할 수 있는 도구
  • Node.js 프로젝트마다 다른 버전 쓰는 경우 필수
  • macOS, Linux, Windows 모두 사용 가능

✅ macOS / Linux 설치

터미널에서 아래 명령어 실행:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

설치 후 쉘 설정파일 추가:

  • . bashrc
  • . zshrc
  • . profile
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

터미널 재시작 후 버전 확인:

nvm --version

✅ Windows 설치

Windows는 nvm-windows라는 별도 프로젝트를 사용

  1. 아래 사이트 접속
    nvm-windows Releases
  2. nvm-setup.zip 파일 다운로드
  3. 설치 마법사 실행

설치 후:

nvm list available

원하는 버전 설치:

nvm install 18.17.0
nvm use 18.17.0

✅ 비유

  • nvm = “여러 버전의 Node.js 신발장”
  • 프로젝트마다 딱 맞는 버전의 신발(노드 버전) 꺼내 신으면 된다!

✅ 얕은 복사 vs 깊은 복사


✅ 얕은 복사 (Shallow Copy)

  • 객체나 배열을 복사할 때 주소(reference)만 복사
  • 내부 값은 여전히 같은 메모리를 가리킴
  • 복사본 수정 → 원본도 영향받음

예시

const original = { name: "Alice" };
const copy = original;

copy.name = "Bob";

console.log(original.name); // Bob

 


✅ 깊은 복사 (Deep Copy)

  • 객체 내부 값까지 모두 새로 복사
  • 복사본과 원본이 완전히 분리됨

깊은 복사 방법

JSON 방법 (간단하지만 한계 존재)

const original = { name: "Alice" };
const copy = JSON.parse(JSON.stringify(original));

copy.name = "Bob";

console.log(original.name); // Alice
  • 단점:
    • 함수, undefined, Symbol은 복사 안됨

structuredClone (ES2021)

const original = { name: "Alice" };
const copy = structuredClone(original);

copy.name = "Bob";

console.log(original.name); // Alice

lodash cloneDeep

import cloneDeep from "lodash/cloneDeep";

const original = { name: "Alice" };
const copy = cloneDeep(original);

copy.name = "Bob";

console.log(original.name); // Alice

✅ 비유

  • 얕은 복사 → “복사본도 같은 집 주소에 살고 있음”
  • 깊은 복사 → “복사본은 새 집에 이사 간 것”

✅ 정리

  • nvm은 Node.js 버전 관리 필수 도구
  • Windows는 nvm-windows 설치 필요
  • 얕은 복사(shallow copy)는 reference만 복사 → 원본과 연결
  • 깊은 복사(deep copy)는 새로운 객체 생성 → 완전히 분리
728x90
728x90

웹 애플리케이션 배포의 흐름

  • 웹 애플리케이션 개발 → 웹 서버에 배포 → 브라우저가 접속
  • 현대 웹 앱은 수십~수백 개의 자바스크립트 모듈로 나뉨
  • 개발할 땐 쪼개서 관리하기 쉽도록 분리
  • 하지만 배포할 땐:
    • 파일 수가 많으면 → HTTP 요청 많아져서 느려짐
    • 파일 관계 관리가 복잡해짐

→ 그래서 모듈 번들러가 등장!


✅ 모듈 번들링이란?


번들링이란?

여러 개로 나눠놓은 JS 파일들을 → 하나(또는 소수)로 합치는 것


✅ 왜 번들링할까?

  • 네트워크 요청 최소화 → 성능 개선
  • 의존 관계를 자동으로 해결
  • ES Module, CommonJS 등 모듈 시스템을 브라우저가 이해할 수 있도록 변환

비유

  • 개발 중 → 각자 A4 용지에 코드를 적음
  • 배포 → A4 수백 장을 복사해서 배포하면 너무 비효율적
  • → “모든 내용을 한 권의 책으로 묶어 배포”하는 게 번들링!

✅ Webpack (웹팩)


웹팩이란?

  • 자바스크립트, CSS, 이미지 등 모든 리소스를 모듈처럼 관리
  • 번들링뿐 아니라:
    • 압축(minify)
    • 코드 분할(code splitting)
    • 트리 쉐이킹(tree shaking)
    • 로더(loader)로 다른 파일 처리

네트워크에서 번들링 확인하기

  • 개발자 도구 → Network 탭
  • 각각의 JS 파일이 별도로 로드되는지, 혹은 하나로 합쳐졌는지 확인 가능
    • 번들링 전: /utils.js, /api.js 등 각각 요청
    • 번들링 후: /bundle.js 하나만 요청

✅ 웹팩 설치하기


설치 명령어

npm install --save-dev webpack webpack-cli

웹팩 실행 방법


1) 기본 실행 (npx)

npx webpack --entry ./src/index.js --output-path ./dist
  • --entry: 진입 파일
  • --output-path: 결과물 경로

2) webpack.config.js 사용

보통 설정 파일을 따로 둔다.

webpack.config.js 예:

const path = require('path');

module.exports = {
  mode: 'development', // or 'production'
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  }
};

실행:

npx webpack

✅ production vs development

mode 특징
development 빠른 빌드 속도, 압축 안함, 디버깅 용이
production 코드 압축, 최적화, 배포 용

production 예

webpack.config.js

module.exports = {
  mode: 'production',
  entry: './src/index.js',
  output: {
    filename: 'bundle.js'
  }
};

빌드 실행:

npx webpack

결과:

  • 코드가 minify(압축)
  • 주석 제거
  • 파일 용량 작아짐

✅ 번들링 없으면 어떻게 될까?

  • 수많은 JS 파일 각각 서버 요청
  • 네트워크 비용 ↑
  • 성능 저하
  • 의존관계 꼬일 위험

→ 그래서 반드시 번들러 필요!


✅ 한 줄 정리

“개발할 땐 쪼개고, 배포할 땐 합친다.
그것이 번들링!”

728x90
728x90

Node.js 란?

  • Node.js = 구글 V8 자바스크립트 엔진으로 빌드된 자바스크립트 런타임 환경
  • 브라우저 밖에서도 자바스크립트를 실행할 수 있게 만들어줌
  • 서버 개발, CLI 툴, 빌드 도구 등 범용적으로 활용 가능

NPM 이란?

  • Node Package Manager의 약자
  • Node.js 생태계의 패키지 관리 도구
  • 필요한 라이브러리를 검색, 설치, 관리할 수 있음
  • npm 공식 사이트 → https://www.npmjs.com/

✅ NPM 기본 사용법


1. 라이브러리 설치

프로젝트 로컬 설치

npm install 라이브러리이름
  • 예:
npm install express

→ 설치된 라이브러리는 node_modules/ 폴더에 들어감


2. 특정 버전 설치

 
npm install 패키지명@버전
  • 예:
  •  
npm install express@4.18.1

3. 전역 설치

npm install -g 패키지명
  • CLI 툴(ex: nodemon, eslint)을 설치할 때 주로 사용
  • 전역 설치된 패키지들은 시스템 어디서든 명령어로 실행 가능
  • 관지라 권한(root 권한) 필요할 때도 있음 (특히 macOS, Linux)

4. nodemon 이란?

  • Node.js 애플리케이션 개발 중 자동으로 서버 재시작해주는 툴
  • 코드 변경 → 자동 감지 → 앱 재시작
  • 개발자 필수템

nodemon 설치

로컬 설치:

npm install nodemon --save-dev

전역 설치:

npm install -g nodemon

nodemon 실행

nodemon index.js

✅ npm init

  • 프로젝트의 package.json 파일을 생성
  • 아래 명령어로 시작:
npm init
  • 빠르게 생성하고 싶으면:
npm init -y

package.json 주요 요소

예:

json
{
  "name": "my-app",
  "version": "1.0.0",
  "description": "테스트 프로젝트",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "express": "^4.18.1"
  },
  "devDependencies": {
    "nodemon": "^3.0.0"
  }
}
  • name: 프로젝트 이름
  • version: 버전 (시맨틱 버저닝)
  • description: 설명
  • main: 진입 파일
  • scripts:
    • 커맨드 단축어 등록
    • 예: 
npm run start
    • 또는 단축형:
npm start
  • dependencies:
    • 실제 서비스에 필요한 패키지
  • devDependencies:
    • 개발용 도구 (ex. nodemon, eslint)

package-lock.json

  • 의존성 트리를 정확히 기록
  • 설치된 패키지들의 버전 고정 역할
  • 팀 프로젝트에서 동일한 환경 유지할 때 중요

✅ node_modules 관리

  • node_modules는 설치된 라이브러리들의 모음
  • 용량 큼 → 보통 Git에 올리지 않음
  • . gitignore에 꼭 추가:
     

node_modules 재설치

  • 다른 컴퓨터에서 프로젝트 복사했을 때:→ package.json 기반으로 다시 설치
npm install

버전 꼬임, 오류 해결

  • 아래 두 폴더 삭제 후 다시 설치:
rm -rf node_modules
rm package-lock.json
npm install

✅ 시맨틱 버저닝 (Semantic Versioning)

패키지 버전은 보통 세 자리로 구성됨:

  • major → 호환 깨질 정도의 큰 변화
  • minor → 새로운 기능 추가 (기존과 호환)
  • patch → 버그 수정

✅ 비유

구분 설명
major 2.0.0 큰 변화 (기존과 호환 안 됨)
minor 1.2.0 기능 추가 (호환됨)
patch 1.2.3 버그 수정
 

^, ~ 기호 의미

  • ^1.2.3 → major는 고정, minor/patch는 업그레이드 가능
  • ~1.2.3 → major/minor 고정, patch만 업그레이드 가능

✅ 정리

  • Node.js는 자바스크립트를 어디서든 돌릴 수 있게 해주는 환경
  • NPM은 라이브러리 설치, 관리의 표준 도구
  • package.json은 프로젝트의 설명서 + 설치 목록
  • node_modules는 버전 꼬이면 지우고 재설치
  • CLI 툴은 전역 설치, 라이브러리는 로컬 설치
  • 시맨틱 버저닝은 버전 관리의 필수 규칙!
728x90
728x90

자바스크립트 모듈이 뭐야?

  • 모듈(Module) = 코드를 여러 파일로 나눠서 관리하기 위한 기능
  • 큰 프로젝트일수록 파일 분리가 필수
  • ES6 이전 → 자바스크립트엔 공식 모듈 시스템이 없었음
  • 지금은 대표적으로 CommonJSES Module 두 가지가 많이 쓰임

✅ CommonJS

특징

  • Node. js에서 사용하기 위해 만들어짐
  • 동기적으로 동작 (require 시점에 파일 읽음)
  • 파일마다 scope가 분리됨
  • .js 확장자 생략 가능

CommonJS 코드 예제

math.js

const perfectSore = 100;

function sum(a, b) {
  return a + b;
}

function subtract(a, b) {
  return a - b;
}

module.exports = {
  perfectSore,
  sum,
  subtract,
};

index.js

const math = require('./math.js');

console.log('perfectSore', math.perfectSore);
console.log('sum', math.sum(10, 20));
console.log('subtract', math.subtract(10, 20));

실행 방법

  • Node.js 환경에서 바로 실행 가능
  • package.json 없어도 OK
  • 예:
node commonjs/index.js

✅ ES Module (ESM)

특징

  • ES6(ECMAScript 2015)에서 공식 표준으로 도입
  • 비동기적으로 동작 가능
  • 파일 간 의존 관계가 명확해짐
  • 브라우저Node.js 둘 다 사용 가능 (Node.js에서는 설정 필요)
  • Node.js에서는 package.json에 설정해야 함:
{
  "type": "module"
}

ES Module 코드 예제

math.js

export const perfectSore = 100;

export function sum(a, b) {
  return a + b;
}

export function avege(a, b) {
  return (a + b) / 2;
}

export default {
  subtract(a, b) {
    return a - b;
  }
};

index.js

import { perfectSore, sum, avege } from './math.js';
import math from './math.js';

console.log('perfectSore', perfectSore);
console.log('sum', sum(10, 20));
console.log('avg', avege(10, 20));
console.log('subtract', math.subtract(10, 20));

import 문법 종류

  • 개별 import
import { sum } from './math.js';
  • default import
import math from './math.js';
  • 모든 export 한 번에 가져오기
import * as math from './math.js';
console.log(math.sum(10, 20));

실행 방법

Node.js에서 ES Module 사용하려면:

  • package.json 추가
{
  "type": "module"
}
  • 실행:
node module/index.js

✅ CommonJS vs ES Module 비교

구분 CommonJS ES Module
도입 시기 예전부터 (Node.js 초창기) ES6 (ECMAScript 2015)
문법 require / module.exports import / export
동기/비동기 동기 비동기 가능
브라우저 사용 X (변환 필요) O (모던 브라우저 지원)
Node.js 기본 지원 package.json 설정 필요
 

✅ 비유로 이해하기

  • CommonJS → 즉석 전화: “전화해 보고 바로 대답 듣기” (동기적)
  • ES Module → 메일: “보내놓고, 답 오면 처리” (비동기 가능)

✅ 정리

  • 작은 파일로 나누고 import/export 하는 습관은 유지보수 필수
  • Node.js에서는 CommonJS도 여전히 많이 쓰지만, 최신 프로젝트는 ES Module로 점점 이동
  • 브라우저에서 모듈 쓸 땐 <script type="module"> 꼭 확인!
728x90
728x90

1. 이벤트 전파: 버블링 vs 캡처링


✅ DOM 중첩 구조 예시

네가 올린 이미지처럼 DOM은 아래처럼 중첩된 박스처럼 되어 있어:

body
└─ main
    └─ div
        └─ p
            └─ span

이벤트는 이렇게 안쪽 ↔ 바깥쪽으로 흘러간다.


캡처링 (Capturing Phase)

  • 이벤트가 가장 바깥쪽 → 가장 안쪽으로 전파
  • 예: body → main → div → p → span
  • 흔히 캡처 단계라고 부름

타깃 단계 (Target Phase)

  • 이벤트가 실제로 발생한 요소에서 실행
  • 예: span에서 클릭 발생

버블링 (Bubbling Phase)

  • 이벤트가 안쪽 → 바깥쪽으로 전파
  • 예: span → p → div → main → body
  • 디폴트 동작은 대부분 버블링

✅ event.eventPhase 값

event.eventPhase로 현재 단계 알 수 있음

eventPhase 값 의미
1 Capturing Phase
2 Target Phase
3 Bubbling Phase
 

✅ 버블링/캡처링 코드 예시

HTML

 
<div id="outer">
  <div id="inner">클릭해보세요!</div>
</div>
js
 
document.getElementById("outer").addEventListener(
  "click",
  (e) => {
    console.log("outer div 캡처링 단계", e.eventPhase);
  },
  true // 캡처링
);

document.getElementById("inner").addEventListener(
  "click",
  (e) => {
    console.log("inner div 버블링 단계", e.eventPhase);
  },
  false // 버블링
);

2. JS 모듈 import/export


✅ ES6 모듈 기본 문법

1) export

파일 math.js

export const add = (a, b) => a + b;
export const multiply = (a, b) => a * b;

2) import

파일 main.js

import { add, multiply } from "./math.js";

console.log(add(2, 3)); // 5
console.log(multiply(2, 3)); // 6

default export

math.js

export default function subtract(a, b) {
  return a - b;
}

main.js

import subtract from "./math.js";
console.log(subtract(5, 2)); // 3

✅ 모듈 사용 시 주의

  • import/export는 브라우저에서 type="module" 필요
  • html
     
<script type="module" src="main.js"></script>

3. Array API


✅ map

  • 배열의 각 요소를 변환 → 새로운 배열 반환
const nums = [1, 2, 3];
const doubled = nums.map(n => n * 2);
console.log(doubled); // [2, 4, 6]

✅ some

  • 배열 중 하나라도 조건 만족하면 true
const nums = [1, 2, 3];
console.log(nums.some(n => n > 2)); // true

✅ reduce

  • 배열 요소를 하나의 값으로 누적
const nums = [1, 2, 3, 4];
const sum = nums.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 10

✅ filter

  • 조건에 맞는 요소만 추출 → 새로운 배열
const nums = [1, 2, 3, 4];
const even = nums.filter(n => n % 2 === 0);
console.log(even); // [2, 4]

✅ 마무리

오늘은 프런트엔드 개발자가 꼭 알아야 할

  • 이벤트 전파 (버블링/캡처링)
  • ES6 모듈 시스템
  • Array API (map, some, reduce, filter)
    를 정리했어.

작은 차이를 이해하면 코드가 더 깔끔하고 효율적해질 수 있으니 꼭 익혀두자!

728x90

+ Recent posts