Vue.js 시니어 코딩 면접

Vue.js 시니어 (7년+) 코딩 · 알고리즘 5문항 조회수 46 · 2026-07-20 (월) 11:11:06
1 Vue 3 Reactivity
Hard

Q. Vue 3에서 대규모 폼 처리 시스템을 구축할 때, 수백 개의 입력 필드가 있는 복잡한 폼의 성능을 최적화하는 방법을 설명해주세요. 특히 shallowRef, shallowReactive, triggerRef를 활용한 최적화 전략과 각 API를 선택하는 기준을 제시하고, 부분 업데이트와 전체 검증을 효율적으로 처리하는 코드 설계 방안을 설명해주세요.

A. 모범답안

대규모 폼에서는 shallowReactive를 사용하여 최상위 폼 객체만 반응형으로 만들고 중첩된 필드는 일반 객체로 유지합니다. 개별 필드 변경 시 Object.assign으로 새 객체를 생성하고 triggerRef로 수동 업데이트를 트리거합니다. 검증 로직은 computed가 아닌 watchEffect와 debounce를 조합하여 필요한 필드만 재검증하도록 구현합니다. 필드 그룹별로 shallowRef를 분리하여 관련 없는 필드의 리렌더링을 방지하고, markRaw를 사용해 검증 규칙이나 메타데이터는 반응형 추적에서 제외합니다.

핵심 포인트
  • • shallowReactive로 깊은 반응성 추적 비용 절감
  • • triggerRef를 통한 수동 업데이트 제어로 불필요한 렌더링 방지
  • • 필드 그룹별 상태 분리와 markRaw를 활용한 선택적 반응성
  • • debounce와 watchEffect 조합으로 검증 로직 최적화
Follow-up 질문

만약 폼 데이터를 Vuex나 Pinia 같은 전역 상태에서 관리한다면, 이러한 최적화 전략을 어떻게 적용하시겠습니까?

2 Vue Component Architecture
Hard

Q. Vue.js에서 Renderless Component 패턴을 사용하여 재사용 가능한 비즈니스 로직을 추상화하는 방법을 설명해주세요. Scoped Slot을 활용한 구현 방식과 Composition API의 Composable 함수와의 차이점, 그리고 각각을 선택하는 기준을 제시해주세요. 특히 드래그앤드롭, 무한 스크롤, 데이터 페이징 같은 복잡한 UI 인터랙션을 추상화할 때의 설계 원칙을 설명해주세요.

A. 모범답안

Renderless Component는 template에서 slot만 렌더링하고 모든 로직을 scoped slot props로 전달하는 패턴입니다. 드래그앤드롭의 경우 onDragStart, onDrop 같은 이벤트 핸들러와 isDragging 상태를 slot props로 제공하며, 실제 UI는 부모 컴포넌트가 결정합니다. Composable은 단순 로직 재사용에 적합하지만, Renderless Component는 여러 자식 요소 간 조율이 필요하거나 provide/inject로 하위 컴포넌트에 컨텍스트를 전달해야 할 때 유리합니다. 선택 기준은 UI 구조의 복잡도와 컴포넌트 트리 깊이이며, 단일 요소 인터랙션은 Composable, 복합 UI 패턴은 Renderless Component를 사용합니다.

핵심 포인트
  • • Scoped slot을 통한 로직과 프레젠테이션의 완전한 분리
  • • provide/inject 기반 컨텍스트 전달이 필요한 경우 Renderless Component 선택
  • • Composable은 단순 로직, Renderless는 복합 UI 패턴에 적합
  • • 이벤트 핸들러와 상태를 slot props로 노출하는 설계
Follow-up 질문

Renderless Component를 TypeScript와 함께 사용할 때 slot props의 타입 안정성을 보장하는 방법은 무엇인가요?

3 Vue Performance Optimization
Hard

Q. Vue 3 애플리케이션에서 코드 스플리팅과 동적 임포트를 활용한 번들 최적화 전략을 설명해주세요. defineAsyncComponent와 라우터의 lazy loading을 조합할 때 프리페칭 전략, 로딩 상태 처리, 에러 바운더리 구현 방법을 포함하여 설명하고, Webpack의 Magic Comment나 Vite의 dynamic import를 활용한 청크 분할 최적화 방안을 제시해주세요.

A. 모범답안

defineAsyncComponent에서 loadingComponent와 errorComponent 옵션으로 로딩/에러 상태를 선언적으로 처리하며, delay와 timeout 설정으로 UX를 개선합니다. 라우터 레벨에서는 route meta에 preload 플래그를 두고, router.beforeEach에서 다음 라우트의 컴포넌트를 미리 로드합니다. Webpack에서는 webpackChunkName과 webpackPrefetch 매직 코멘트로 청크 이름과 프리페칭을 제어하고, Vite에서는 import.meta.glob으로 패턴 기반 동적 임포트를 구현합니다. 컴포넌트 그룹별로 청크를 분리하되, 너무 작은 청크는 HTTP 요청 오버헤드를 고려하여 병합하고, 중요도에 따라 preload와 prefetch를 차별화합니다.

핵심 포인트
  • • defineAsyncComponent의 loading/error 컴포넌트로 선언적 상태 관리
  • • 라우터 메타데이터 기반 프리페칭 전략 구현
  • • 번들러별 매직 코멘트와 동적 임포트 API 활용
  • • 청크 크기와 HTTP 요청 수의 트레이드오프 고려
Follow-up 질문

사용자의 네트워크 상태나 디바이스 성능에 따라 프리페칭 전략을 동적으로 조정하는 방법은 무엇인가요?

4 Vue Testing Strategy
Hard

Q. Vue 3 Composition API로 작성된 복잡한 비즈니스 로직을 테스트하는 전략을 설명해주세요. Composable 함수의 단위 테스트 작성 방법, 반응성 시스템을 모킹하는 기법, 그리고 비동기 로직과 타이머를 포함한 테스트 시나리오 작성 방법을 제시해주세요. 특히 Vue Test Utils 없이 순수 Composable 로직을 테스트하는 방법과 통합 테스트에서의 접근 방식의 차이를 설명해주세요.

A. 모범답안

Composable 함수는 Vue 인스턴스 없이 테스트하기 위해 @vue/reactivity-api만 import하여 독립적으로 테스트합니다. 반응성 테스트는 effect나 watchEffect로 변경 감지를 검증하고, nextTick을 사용해 비동기 업데이트를 기다립니다. 비동기 로직은 vi.useFakeTimers로 타이머를 모킹하고, Promise는 flushPromises 유틸리티로 해결을 기다립니다. API 호출은 MSW나 vi.mock으로 모킹하되, Composable 내부에서 inject를 사용한다면 테스트용 provide 컨텍스트를 setup 함수로 감싸서 제공합니다. 통합 테스트에서는 Vue Test Utils의 mount를 사용해 실제 컴포넌트 렌더링과 함께 테스트하며, 이때는 DOM 인터랙션과 이벤트 처리까지 검증합니다.

핵심 포인트
  • • @vue/reactivity-api를 활용한 독립적인 Composable 테스트
  • • vi.useFakeTimers와 flushPromises로 비동기 로직 제어
  • • provide/inject는 테스트용 컨텍스트 래퍼로 처리
  • • 단위 테스트는 로직 검증, 통합 테스트는 DOM 인터랙션 포함
Follow-up 질문

Composable 함수가 다른 Composable을 의존할 때, 의존성 주입을 테스트 가능하게 설계하는 패턴은 무엇인가요?

5 Vue Build Optimization
Hard

Q. Vue 3 프로젝트에서 Tree Shaking을 최대화하고 번들 크기를 최소화하기 위한 코드 작성 패턴과 빌드 설정 전략을 설명해주세요. 특히 Vue의 런타임 기능 중 사용하지 않는 부분을 제거하는 방법, 써드파티 라이브러리의 Tree Shaking 최적화, 그리고 Vite의 build.rollupOptions를 활용한 번들 분석 및 최적화 방안을 제시해주세요.

A. 모범답안

Vue 3는 Tree Shaking을 위해 __VUE_OPTIONS_API__, __VUE_PROD_DEVTOOLS__ 같은 feature flag를 제공하며, define 옵션으로 false 설정 시 해당 코드가 번들에서 제거됩니다. Composition API만 사용한다면 Options API 관련 코드를 제거하여 약 20% 번들 크기를 줄일 수 있습니다. 써드파티 라이브러리는 package.json의 sideEffects 필드를 확인하고, ESM 버전을 import하며, lodash 대신 lodash-es를 사용합니다. Vite에서는 build.rollupOptions.output.manualChunks로 vendor와 app 코드를 분리하고, rollup-plugin-visualizer로 번들을 분석하여 중복 의존성을 찾아냅니다. import 문에서 default export 대신 named export를 사용하고, 동적 import는 반드시 정적 문자열 경로를 사용해야 Tree Shaking이 동작합니다.

핵심 포인트
  • • Vue feature flag로 불필요한 런타임 기능 제거
  • • ESM 버전 라이브러리와 named export 사용
  • • manualChunks와 visualizer로 번들 분석 및 최적화
  • • 동적 import는 정적 경로로 작성하여 Tree Shaking 보장
Follow-up 질문

Monorepo 환경에서 여러 Vue 애플리케이션이 공통 컴포넌트 라이브러리를 공유할 때, Tree Shaking을 유지하면서 빌드 성능을 최적화하는 방법은 무엇인가요?

댓글 0

로그인 후 댓글을 작성할 수 있습니다.

아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!