포스트

[이제와서 시작하는 Claude AI 마스터하기 #13] 멀티파일 편집과 대규모 변경

[이제와서 시작하는 Claude AI 마스터하기 #13] 멀티파일 편집과 대규모 변경

프로젝트 전체를 한 번에

Claude Code의 멀티파일 편집 기능은 대규모 코드베이스에서 일관된 변경을 빠르고 정확하게 수행할 수 있게 해줍니다. 수백 개의 파일도 동시에 편집하며, 변경 사항의 일관성을 보장합니다.

멀티파일 편집 기본

Claude Code 멀티파일 편집 능력 비교

작업 유형 파일 수 처리 시간 정확도 사용 예시
이름 변경 100-500개 5-10초 99% 함수/변수명 변경
구조 변경 50-200개 10-20초 95% import 경로 수정
패턴 교체 200-1000개 15-30초 98% API 버전 업그레이드
타입 변환 100-300개 20-40초 97% JS → TS 마이그레이션
리팩토링 50-150개 30-60초 96% 아키텍처 변경

1. 동시 편집 워크플로우

graph TD
    A[변경 계획] --> B[영향 범위 분석]
    B --> C[파일 그룹화]
    C --> D[동시 편집]
    
    D --> E[구문 검증]
    D --> F[의존성 확인]
    D --> G[충돌 해결]
    
    E --> H[변경 적용]
    F --> H
    G --> H
    
    H --> I[테스트 실행]

2. 기본 멀티파일 작업

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// Claude 명령: "모든 컴포넌트에서 PropTypes를 TypeScript로 변환"

// 변경 전: Button.js
import React from 'react';
import PropTypes from 'prop-types';

const Button = ({onClick, children, disabled}) => (
  <button onClick={onClick} disabled={disabled}>
    {children}
  </button>
);

Button.propTypes = {
  onClick: PropTypes.func.isRequired,
  children: PropTypes.node.isRequired,
  disabled: PropTypes.bool
};

// 변경 후: Button.tsx
import React from 'react';

interface ButtonProps {
  onClick: () => void;
  children: React.ReactNode;
  disabled?: boolean;
}

const Button: React.FC<ButtonProps> = ({onClick, children, disabled = false}) => (
  <button onClick={onClick} disabled={disabled}>
    {children}
  </button>
);

// Claude 실행 결과
/*
변경된 파일: 45개
- components/*.js → *.tsx
- PropTypes 제거: 45개 파일
- TypeScript 인터페이스 추가: 45개
- import 문 정리: 45개
실행 시간: 3.2초
*/

3. 패턴 기반 변경

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# Claude에게 요청: "모든 클래스 기반 컴포넌트를 함수형으로 변환"

# 변경 전
class UserList extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            users: [],
            loading: true
        };
    }
    
    componentDidMount() {
        this.fetchUsers();
    }
    
    fetchUsers = async () => {
        const users = await api.getUsers();
        this.setState({users, loading: false});
    }
    
    render() {
        const {users, loading} = this.state;
        if (loading) return <Loading />;
        return <div>{users.map(user => <User key={user.id} {...user} />)}</div>;
    }
}

# 변경 후
const UserList: React.FC = () => {
    const [users, setUsers] = useState<User[]>([]);
    const [loading, setLoading] = useState(true);
    
    useEffect(() => {
        fetchUsers();
    }, []);
    
    const fetchUsers = async () => {
        const users = await api.getUsers();
        setUsers(users);
        setLoading(false);
    };
    
    if (loading) return <Loading />;
    return <div>{users.map(user => <User key={user.id} {...user} />)}</div>;
};

고급 멀티파일 작업

1. 프로젝트 구조 재편성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# Claude 명령: "기능별 폴더 구조로 재편성"

# 현재 구조
src/
├── components/
│   ├── Button.tsx
│   ├── UserList.tsx
│   └── ProductCard.tsx
├── services/
│   ├── api.ts
│   └── auth.ts
└── utils/

# 변경 후 구조
src/
├── features/
│   ├── auth/
│   │   ├── components/
│   │   ├── services/
│   │   └── hooks/
│   ├── users/
│   │   ├── components/
│   │   │   └── UserList.tsx
│   │   ├── services/
│   │   └── types/
│   └── products/
│       ├── components/
│       │   └── ProductCard.tsx
│       └── services/
└── shared/
    ├── components/
    │   └── Button.tsx
    └── utils/

2. import 경로 자동 업데이트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Claude가 자동으로 모든 import 경로 수정
// 변경 전
import Button from '../../../components/Button';
import {api} from '../../services/api';
import UserList from '../components/UserList';

// 변경 후
import Button from '@/shared/components/Button';
import {userApi} from '@/features/users/services/api';
import UserList from '@/features/users/components/UserList';

// tsconfig.json 자동 업데이트
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "@/features/*": ["src/features/*"],
      "@/shared/*": ["src/shared/*"]
    }
  }
}

3. API 엔드포인트 일괄 변경

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Claude 명령: "모든 API 엔드포인트를 v1에서 v2로 업그레이드"

// 변경 대상 파일들
const affectedFiles = [
  'services/api.ts',
  'services/auth.ts',
  'features/*/services/*.ts',
  'tests/**/*.test.ts'
];

// 변경 패턴
const changes = {
  '/api/v1/users': '/api/v2/users',
  '/api/v1/products': '/api/v2/products',
  '/api/v1/auth': '/api/v2/auth',
  
  // 응답 구조 변경도 함께 처리
  'response.data': 'response.body.data',
  'response.error': 'response.body.error',
  
  // 헤더 변경
  'X-API-Version: 1': 'X-API-Version: 2'
};

// 실행 결과
/*
총 변경 사항: 234개
영향받은 파일: 67개
변경된 테스트: 45개
경고: 3개 파일에서 수동 검토 필요
*/

대규모 리네이밍

변경 작업 복잡도 매트릭스

변경 범위 단순 교체 패턴 기반 문맥 인식 구조 변경
단일 파일 ⭐⭐ ⭐⭐ ⭐⭐⭐
동일 폴더 ⭐⭐ ⭐⭐ ⭐⭐⭐ ⭐⭐⭐
전체 프로젝트 ⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
의존성 포함 ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐

1. 변수/함수명 일괄 변경

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Claude 명령: "getUserData를 fetchUserProfile로 전체 변경"

# 지능적 변경 - 문맥 고려
"""
변경 전:
- getUserData() 함수: 89개 파일
- getUserDataAsync() 함수: 12개 파일  
- getUserDataFromCache() 함수: 5개 파일
- GET_USER_DATA 상수: 23개 파일

변경 후:
- fetchUserProfile() 
- fetchUserProfileAsync()
- fetchUserProfileFromCache()
- FETCH_USER_PROFILE
"""

# 연관 변경도 자동 수행
- 테스트 파일의 describe/it 문구
- 주석의 함수명 참조
- 문서 파일 (.md) API 설명

2. 컴포넌트 이름 변경

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Claude가 처리하는 작업
// 1. 컴포넌트 정의 변경
// 2. import/export 문 변경  
// 3. JSX 사용 부분 변경
// 4. 테스트 파일 변경
// 5. 스토리북 파일 변경
// 6. 문서 업데이트

// 예: UserCard → UserProfile 변경

// 1. 컴포넌트 파일
// UserCard.tsx → UserProfile.tsx
export const UserProfile = () => {...}

// 2. 사용하는 파일들
import {UserProfile} from '@/components/UserProfile';
<UserProfile user={user} />

// 3. 테스트 파일
// UserCard.test.tsx → UserProfile.test.tsx
describe('UserProfile', () => {...})

// 4. 스토리북
// UserCard.stories.tsx → UserProfile.stories.tsx
export default {
  title: 'Components/UserProfile',
  component: UserProfile
}

코드 마이그레이션

1. 프레임워크 업그레이드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// React Router v5 → v6 마이그레이션
// Claude가 자동으로 처리하는 변경사항

// 1. Switch → Routes
// 변경 전
import {Switch, Route} from 'react-router-dom';
<Switch>
  <Route path="/users" component={Users} />
  <Route path="/profile/:id" component={Profile} />
</Switch>

// 변경 후
import {Routes, Route} from 'react-router-dom';
<Routes>
  <Route path="/users" element={<Users />} />
  <Route path="/profile/:id" element={<Profile />} />
</Routes>

// 2. useHistory → useNavigate
// 변경 전
const history = useHistory();
history.push('/users');

// 변경 후
const navigate = useNavigate();
navigate('/users');

// 3. Route props → hooks
// 변경 전
const Profile = ({match}) => {
  const {id} = match.params;
}

// 변경 후
const Profile = () => {
  const {id} = useParams();
}

2. 라이브러리 교체

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Moment.js → Day.js 마이그레이션
// Claude의 지능적 변환

// 분석 단계
/*
Moment.js 사용 발견:
- 날짜 포맷팅: 156개 위치
- 날짜 계산: 89개 위치  
- 시간대 변환: 34개 위치
*/

// 변환 예시
// 변경 전
import moment from 'moment';
const date = moment('2025-07-28');
const formatted = date.format('YYYY년 MM월 DD일');
const nextWeek = date.add(7, 'days');
const isAfter = date.isAfter(moment());

// 변경 후
import dayjs from 'dayjs';
import 'dayjs/locale/ko';
dayjs.locale('ko');

const date = dayjs('2025-07-28');
const formatted = date.format('YYYY년 MM월 DD일');
const nextWeek = date.add(7, 'day');
const isAfter = date.isAfter(dayjs());

// package.json 자동 업데이트
// dependencies에서 moment 제거, dayjs 추가

안전한 대규모 변경

1. 변경 미리보기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Claude의 변경 계획 미리보기
{
  "operation": "Rename function getUserById to findUserById",
  "impact": {
    "files": 45,
    "changes": 178,
    "tests": 23
  },
  "preview": [
    {
      "file": "src/services/userService.ts",
      "changes": [
        {
          "line": 15,
          "before": "export async function getUserById(id: string) {",
          "after": "export async function findUserById(id: string) {"
        }
      ]
    }
  ],
  "risks": [
    "3 파일에서 동적 함수 호출 감지",
    "외부 패키지가 이 함수를 사용할 가능성"
  ]
}

2. 단계별 실행

graph LR
    A[변경 계획] --> B[백업 생성]
    B --> C[테스트 실행]
    C --> D{성공?}
    D -->|Yes| E[1차 변경<br>핵심 파일]
    D -->|No| F[중단]
    
    E --> G[부분 테스트]
    G --> H{성공?}
    H -->|Yes| I[2차 변경<br>나머지 파일]
    H -->|No| J[롤백]
    
    I --> K[전체 테스트]
    K --> L[커밋]

3. 롤백 전략

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Claude의 자동 백업 시스템
claude edit --massive --backup

# 생성되는 백업
.claude-backup/
├── 2025-07-28-153042/
│   ├── manifest.json
│   ├── original/
│   └── changed/
└── restore.sh

# 롤백 명령
claude restore --backup 2025-07-28-153042

# 부분 롤백
claude restore --backup 2025-07-28-153042 --files "src/services/*"

실전 활용 예제

1. 모놀리스 → 마이크로서비스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Claude에게 요청: "인증 모듈을 별도 서비스로 분리"

// Claude 실행 단계:
// 1. 인증 관련 코드 식별
// 2. 의존성 분석
// 3. 인터페이스 정의
// 4. 서비스 분리
// 5. 통신 레이어 구현

// 결과 구조
services/
├── auth-service/
   ├── src/
   ├── package.json
   └── Dockerfile
├── user-service/
   └── src/
└── shared/
    └── interfaces/

2. 다국어 지원 추가

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Claude 명령: "모든 하드코딩된 텍스트를 i18n으로 변환"

// 변경 전
<button>Submit</button>
<p>Welcome to our application!</p>
alert('Error occurred');

// 변경 후
<button>{t('common.submit')}</button>
<p>{t('home.welcome')}</p>
alert(t('errors.generic'));

// 자동 생성된 언어 파일
// locales/en.json
{
  "common": {
    "submit": "Submit"
  },
  "home": {
    "welcome": "Welcome to our application!"
  },
  "errors": {
    "generic": "Error occurred"
  }
}

2025년 멀티파일 편집 최신 기능

Claude Code 고급 기능 비교

기능 설명 활용도 2025년 신기능
AST 기반 분석 구문 트리 분석으로 정확한 변경 높음 ✅ 향상됨
의존성 그래프 파일 간 관계 자동 파악 높음 ✅ 신규
병렬 처리 다중 파일 동시 처리 필수 ✅ 최적화
미리보기 변경 전 시뮬레이션 높음 ✅ 향상됨
롤백 지원 자동 백업 및 복원 필수 ✅ 신규

멀티파일 작업 플로우 다이어그램

graph TB
    A[변경 요청] --> B{분석 단계}
    B --> C[파일 스캔]
    B --> D[의존성 분석]
    B --> E[영향 범위 평가]
    
    C --> F[변경 계획]
    D --> F
    E --> F
    
    F --> G{미리보기}
    G -->|승인| H[백업 생성]
    G -->|수정| B
    
    H --> I[병렬 처리]
    I --> J[파일 그룹 1]
    I --> K[파일 그룹 2]
    I --> L[파일 그룹 3]
    
    J --> M[검증]
    K --> M
    L --> M
    
    M --> N{성공?}
    N -->|Yes| O[커밋]
    N -->|No| P[롤백]
    
    P --> Q[에러 리포트]
    O --> R[완료 리포트]

성능 고려사항

대규모 변경 최적화

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Claude의 성능 최적화 전략
{
  "strategies": {
    "parallelProcessing": {
      "enabled": true,
      "workers": 8,
      "benefit": "4x faster for 1000+ files"
    },
    "incrementalUpdate": {
      "enabled": true,
      "benefit": "Only changed files reprocessed"
    },
    "smartCaching": {
      "enabled": true,
      "benefit": "60% faster on repeated operations"
    }
  },
  "benchmarks": {
    "1000files": "12 seconds",
    "5000files": "45 seconds",
    "10000files": "2 minutes"
  }
}

다음 편 예고

다음 편에서는 “CI/CD 파이프라인 구축”을 다룰 예정입니다. Claude Code를 활용한 자동화된 빌드 및 배포 시스템 구축 방법을 알아보겠습니다.


💡 오늘의 과제: 프로젝트에서 일관성이 없는 네이밍을 찾아 Claude Code로 일괄 변경해보세요. 변경 전후를 비교하고 영향 범위를 분석해보세요!

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.