본문 바로가기

카테고리 없음

Cursor + Figma MCP 가이드 - 생성된 코드를 실제 프로젝트에 적용하기

🎯 이번 편에서 배울 내용

  • 순수 HTML 프로젝트에 통합하기
  • React 프로젝트에 적용하기
  • 기존 프로젝트와 연동하기
  • 실전 배포 준비하기

시작하기 전에

8편에서 생성한 로그인 화면 코드를 실제 프로젝트에 통합하는 다양한 방법을 배웁니다. 여러분의 프로젝트 유형에 맞는 섹션을 선택해서 따라하세요.

Option 1: 순수 HTML 프로젝트에 통합

Step 1-1: 프로젝트 구조 만들기

1) 새 프로젝트 폴더 생성

my-website/
├── index.html
├── login.html          ← 새로 추가
├── css/
│   ├── main.css
│   └── login.css       ← 새로 추가
├── js/
│   ├── main.js
│   └── login.js        ← 새로 추가
└── images/

2) Cursor에서 작업

  1. File > Open Folder
  2. "my-website" 폴더 선택
  3. Explorer에서 login.html 파일 생성

Step 1-2: 코드 통합

1) login.html 작성

html
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>로그인 - My Website</title>
    
    <!-- 공통 스타일 -->
    <link rel="stylesheet" href="css/main.css">
    <!-- 로그인 페이지 전용 스타일 -->
    <link rel="stylesheet" href="css/login.css">
    
    <!-- Google Fonts -->
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
</head>
<body>
    <!-- 헤더 (공통) -->
    <header>
        <nav>
            <a href="index.html">홈</a>
            <a href="about.html">소개</a>
            <a href="login.html">로그인</a>
        </nav>
    </header>
    
    <!-- 로그인 화면 (8편에서 생성한 코드) -->
    <main>
        <div class="container">
            <div class="login-screen">
                <!-- 8편 코드 붙여넣기 -->
            </div>
        </div>
    </main>
    
    <!-- 푸터 (공통) -->
    <footer>
        <p>&copy; 2025 My Website</p>
    </footer>
    
    <script src="js/login.js"></script>
</body>
</html>

2) CSS 분리

css/login.css:

css
/* 로그인 페이지 전용 스타일 */
.container {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: calc(100vh - 120px); /* 헤더/푸터 높이 제외 */
}

.login-screen {
    /* 8편에서 생성한 CSS */
}

Step 1-3: 네비게이션 연결

1) 메인 페이지에서 로그인으로 링크

html
<!-- index.html -->
<a href="login.html" class="login-button">로그인</a>

2) 로그인 후 리다이렉트

javascript
// js/login.js
form.addEventListener('submit', function(e) {
    e.preventDefault();
    
    // 실제로는 서버 인증 로직
    // 여기서는 간단히 메인 페이지로 이동
    
    window.location.href = 'index.html';
});

Option 2: React 프로젝트에 적용

Step 2-1: React 프로젝트 생성 (신규)

1) Vite로 React 프로젝트 생성 Cursor 터미널에서:

bash
npm create vite@latest my-react-app -- --template react
cd my-react-app
npm install

2) 프로젝트 구조

my-react-app/
├── src/
│   ├── components/
│   │   ├── Login/
│   │   │   ├── LoginScreen.jsx
│   │   │   ├── LoginForm.jsx
│   │   │   ├── Input.jsx
│   │   │   └── Button.jsx
│   │   └── ...
│   ├── styles/
│   │   └── login.css
│   ├── App.jsx
│   └── main.jsx
└── package.json

Step 2-2: 컴포넌트로 변환

1) Cursor Composer에 요청

8편에서 만든 로그인 화면 HTML을
React 컴포넌트로 변환해줘.

요구사항:
- 함수형 컴포넌트 사용
- useState로 입력 값 관리
- 재사용 가능한 Input, Button 컴포넌트 분리
- PropTypes 또는 TypeScript 타입 정의
- 이벤트 핸들러 구현

2) 생성된 컴포넌트 예시

src/components/Login/LoginScreen.jsx:

jsx
import React, { useState } from 'react';
import LoginForm from './LoginForm';
import './login.css';

function LoginScreen() {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    
    const handleSubmit = (e) => {
        e.preventDefault();
        // 로그인 로직
        console.log('Login:', { email, password });
    };
    
    return (
        <div className="container">
            <div className="login-screen">
                {/* 로고 */}
                <div className="logo">
                    <div className="logo-circle">
                        <span>LOGO</span>
                    </div>
                </div>
                
                {/* 로그인 폼 */}
                <LoginForm
                    email={email}
                    password={password}
                    onEmailChange={(e) => setEmail(e.target.value)}
                    onPasswordChange={(e) => setPassword(e.target.value)}
                    onSubmit={handleSubmit}
                />
                
                {/* 링크 */}
                <a href="#" className="forgot-password">
                    비밀번호를 잊으셨나요?
                </a>
                
                <div className="divider"></div>
                
                <div className="signup-section">
                    <span>계정이 없으신가요?</span>
                    <a href="#">회원가입</a>
                </div>
            </div>
        </div>
    );
}

export default LoginScreen;

src/components/Login/Input.jsx:

jsx
import React from 'react';

function Input({ type, placeholder, value, onChange, required }) {
    return (
        <div className="input-group">
            <input
                type={type}
                placeholder={placeholder}
                value={value}
                onChange={onChange}
                required={required}
            />
        </div>
    );
}

export default Input;

Step 2-3: React Router 통합

1) React Router 설치

bash
npm install react-router-dom

2) 라우팅 설정

src/App.jsx:

jsx
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import LoginScreen from './components/Login/LoginScreen';

function App() {
    return (
        <BrowserRouter>
            <Routes>
                <Route path="/" element={<Home />} />
                <Route path="/login" element={<LoginScreen />} />
            </Routes>
        </BrowserRouter>
    );
}

export default App;

Step 2-4: 상태 관리 추가 (선택사항)

Context API 사용:

jsx
// src/context/AuthContext.jsx
import React, { createContext, useState } from 'react';

export const AuthContext = createContext();

export function AuthProvider({ children }) {
    const [user, setUser] = useState(null);
    
    const login = async (email, password) => {
        // API 호출
        const userData = await api.login(email, password);
        setUser(userData);
    };
    
    const logout = () => {
        setUser(null);
    };
    
    return (
        <AuthContext.Provider value={{ user, login, logout }}>
            {children}
        </AuthContext.Provider>
    );
}

Option 3: 기존 프로젝트에 통합

Step 3-1: 프로젝트 분석

1) Cursor에게 프로젝트 구조 파악 요청

현재 프로젝트의 구조를 분석해줘:
- 사용 중인 프레임워크/라이브러리
- 스타일링 방법 (CSS, Sass, styled-components 등)
- 컴포넌트 패턴
- 라우팅 방식

2) 통합 계획 수립

8편에서 만든 로그인 화면을
현재 프로젝트에 통합하는 계획을 세워줘:
1. 파일을 어디에 배치할지
2. 기존 스타일과 충돌 방지 방법
3. 라우팅 설정
4. 상태 관리 연동

Step 3-2: 스타일 충돌 방지

1) CSS Modules 사용

css
/* LoginScreen.module.css */
.container {
    /* 스타일 */
}

.loginScreen {
    /* 스타일 */
}

 

 
jsx
import styles from './LoginScreen.module.css';

function LoginScreen() {
    return (
        <div className={styles.container}>
            <div className={styles.loginScreen}>
                {/* ... */}
            </div>
        </div>
    );
}

2) BEM 명명 규칙

css
.login-screen { }
.login-screen__logo { }
.login-screen__form { }
.login-screen__input { }
.login-screen__button { }

3) CSS-in-JS (styled-components)

jsx
import styled from 'styled-components';

const Container = styled.div`
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
`;

const LoginScreen = styled.div`
    width: 100%;
    max-width: 393px;
    padding: 20px;
`;

Step 3-3: API 연동

1) API 서비스 파일 생성

src/services/auth.js:

 
 
javascript
const API_URL = 'https://api.example.com';

export async function login(email, password) {
    try {
        const response = await fetch(`${API_URL}/login`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ email, password }),
        });
        
        if (!response.ok) {
            throw new Error('로그인 실패');
        }
        
        const data = await response.json();
        return data;
    } catch (error) {
        console.error('Login error:', error);
        throw error;
    }
}

2) 로그인 컴포넌트에서 사용

jsx
import { login } from '../../services/auth';

function LoginScreen() {
    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState(null);
    
    const handleSubmit = async (e) => {
        e.preventDefault();
        setIsLoading(true);
        setError(null);
        
        try {
            const userData = await login(email, password);
            // 로그인 성공 처리
            localStorage.setItem('token', userData.token);
            navigate('/dashboard');
        } catch (err) {
            setError(err.message);
        } finally {
            setIsLoading(false);
        }
    };
    
    return (
        // JSX...
        {error && <div className="error">{error}</div>}
        <button disabled={isLoading}>
            {isLoading ? '로그인 중...' : '로그인'}
        </button>
    );
}

Step 4: 실전 배포 준비

4-1: 환경 변수 설정

1) .env 파일 생성

 
 
VITE_API_URL=https://api.example.com
VITE_APP_TITLE=My App

2) 코드에서 사용

javascript
const apiUrl = import.meta.env.VITE_API_URL;

3) .gitignore에 추가

.env
.env.local
.env.production

4-2: 빌드 최적화

1) 이미지 최적화

이미지 파일을 WebP 형식으로 변환하고
lazy loading을 적용해줘.

2) CSS 최적화

사용하지 않는 CSS를 제거하고
중요한 CSS를 인라인으로 넣어줘.

3) JavaScript 번들 최적화

코드 스플리팅을 적용해서
초기 로드 속도를 개선해줘.

4-3: 보안 강화

1) XSS 방지

jsx
// 사용자 입력을 항상 이스케이프
function Input({ value, onChange }) {
    return (
        <input
            value={value}
            onChange={(e) => onChange(e.target.value)}
            // XSS 방지: React가 자동으로 이스케이프
        />
    );
}

2) CSRF 토큰

javascript
// API 요청 시 CSRF 토큰 포함
fetch(url, {
    headers: {
        'X-CSRF-Token': getCsrfToken(),
    },
});

3) HTTPS 사용

  • 배포 시 반드시 HTTPS 사용
  • Let's Encrypt로 무료 SSL 인증서 발급

4-4: 접근성 검사

1) Lighthouse 실행

  1. Chrome DevTools 열기 (F12)
  2. Lighthouse 탭 선택
  3. "Generate report" 클릭
  4. 점수 확인:
    • Performance: 90+ 목표
    • Accessibility: 90+ 목표
    • Best Practices: 90+ 목표
    • SEO: 90+ 목표

2) 접근성 개선

Lighthouse 보고서를 바탕으로
접근성 이슈를 수정해줘:
- 색상 대비 개선
- alt 텍스트 추가
- 키보드 네비게이션 지원
- 스크린 리더 지원

Step 5: 배포

5-1: Vercel 배포 (추천)

1) Vercel CLI 설치

bash
npm install -g vercel

2) 배포 실행

bash
vercel

3) 질문에 답변

? Set up and deploy "~/my-project"? [Y/n] y
? Which scope do you want to deploy to? Your Name
? Link to existing project? [y/N] n
? What's your project's name? my-login-app
? In which directory is your code located? ./
? Want to override the settings? [y/N] n

4) 배포 완료

✅ Production: https://my-login-app.vercel.app

5-2: Netlify 배포

1) Netlify CLI 설치

bash
npm install -g netlify-cli

2) 배포

bash
netlify deploy --prod

5-3: GitHub Pages 배포

1) package.json에 homepage 추가

json
{
    "homepage": "https://yourusername.github.io/my-app"
}

2) gh-pages 설치

bash
npm install --save-dev gh-pages

3) 배포 스크립트 추가

json
{
    "scripts": {
        "predeploy": "npm run build",
        "deploy": "gh-pages -d dist"
    }
}

4) 배포 실행

bash
npm run deploy

Step 6: 모니터링 및 유지보수

6-1: 에러 모니터링

Sentry 설정:

bash
npm install @sentry/react
 
javascript
import * as Sentry from "@sentry/react";

Sentry.init({
    dsn: "your-sentry-dsn",
    environment: "production",
});

6-2: 분석 도구

Google Analytics:

html
<!-- index.html -->
<script async src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'GA_MEASUREMENT_ID');
</script>

실전 체크리스트

배포 전 최종 확인

  • 모든 기능이 정상 작동함
  • 다양한 브라우저에서 테스트 완료
  • 모바일에서 테스트 완료
  • 접근성 점수 90+ 달성
  • 성능 점수 90+ 달성
  • 환경 변수가 올바르게 설정됨
  • API 엔드포인트가 프로덕션 URL로 설정됨
  • 에러 핸들링이 구현됨
  • 로딩 상태가 표시됨
  • SEO 메타 태그가 설정됨

다음 편 예고

10편에서는 자주 발생하는 문제들의 해결 방법과 고급 활용 팁을 다룹니다. 지금까지 배운 모든 내용을 정리하고, 실전에서 마주칠 수 있는 다양한 상황에 대처하는 방법을 배워보겠습니다!

반응형