1. VOIM 익스텐션 소개

VOIM 익스텐션한국대학생IT학회 8팀에서 개발한, 약시 사용자들의 웹 접근성을 개선하기 위한 크롬 확장 프로그램입니다.
사용자는 웹페이지 위에 VOIM을 플로팅 형태로 띄워, 글자 확대나 고대비 테마 설정을 통해 콘텐츠를 보다 쉽게 읽을 수 있습니다.
현재 VOIM은 다음과 같은 주요 기능을 제공합니다:
  • 글자 크기 및 굵기 조정
  • 웹사이트의 고대비 테마 설정
  • 포커스 트랩 및 키보드 탐색 등 접근성 강화 기능
  • 쿠팡 상세 정보 및 장바구니 요약 제공
이 확장 프로그램은 실제 약시 사용자들과의 인터뷰를 바탕으로 개발되었으며,
특히 쿠팡 쇼핑 환경에 최적화되어 주요 정보를 선명하게 전달하는 데 중점을 두었습니다.
🔧 사용 기술: TypeScript, React, Chrome Extension API, TailwindCSS, Webpack
사용자 설정은 실시간 반영되며, 심플하고 직관적인 UI를 통해 누구나 손쉽게 사용할 수 있도록 설계되었습니다.
VOIM 웹스토어

2. 리팩토링을 하게 된 배경

VOIM 익스텐션은 빠른 MVP 개발과 실제 사용자 피드백 반영에 집중하며 빠르게 개발해온 프로젝트입니다.
초기에는 기능을 빠르게 만들고 직접 써보자는 목표 아래, 구조보다는 사용자 니즈에 빠르게 대응하는 것에 초점을 맞췄습니다.
이러한 전략은 실제 약시 사용자들과의 인터뷰 및 반복 개선 과정에서 큰 효과를 발휘했지만,
점차 코드베이스가 커지고 사용자 요구가 다양해지면서 구조적 한계가 드러나기 시작했습니다.

구조적 리스크 발견

  • UI와 상태 관리, 저장 로직이 혼재되어 테스트/재사용 어려움
  • 페이지 단위로만 나뉜 폴더 구조 → 역할 파악이 어렵고 신규 개발자 온보딩에 시간 소요
  • 포커스 트랩 등 접근성 기능의 일관성 부족 → 일부 설정이 UI에 반영되지 않음
  • 테스트 코드/문서화 부족 → 기능 추가 시 리스크 증가

리팩토링이 꼭 필요한 이유

저는 VOIM을 개발할때, 단순한 기능 제공이 아니라, 정보 접근성이 제한된 사용자에게 실질적인 도움을 주는 도구로서의 사회적 역할을 목표로 개발하였습니다.
장기적으로 더 많은 사용자에게 안정적이고 확장 가능한 서비스를 제공하려면,
이제는 기능 속도보다 코드의 품질과 구조적 안정성 확보가 더 중요한 시점입니다.

따라서 이번 리팩토링은 기술적 부채 해소를 넘어서,
사회적 정보 격차 해소라는 목표를 지속적으로 실현하기 위한 기반 마련 작업이라 할 수 있습니다.

3. 기술적 문제와 리팩토링 방향

VOIM 익스텐션은 빠른 MVP 개발을 기반으로 성장해 왔지만,
사용자 요구가 다양해지고 기능이 확장됨에 따라 구조적인 문제들이 드러나기 시작했습니다.
기능 중심의 구조는 단기적인 속도는 보장해줬지만,
장기적으로는 유지보수성, 확장성, 그리고 협업 효율성 측면에서 큰 제약이 되었습니다.

❌ 현재 구조의 기술적 한계

1) 역할과 관심사의 혼재

  • UI 컴포넌트 내부에 상태 관리, 저장소 연동, 스타일링 로직이 모두 혼합
  • 가독성과 재사용성 저하, 사이드 이펙트 발생 가능성 증가

2) 비효율적인 디렉토리 구조

  • components, content 등 위치 기반 폴더 분류
  • 기능/역할 단위가 아닌 구성으로 코드 파악 및 재사용 어려움
VOIM 현재 폴더 구조

3) 전역 상태 관리의 부재

  • chrome.storage각 컴포넌트가 직접 호출 → 비동기/불안정 상태 발생
  • 설정 변경이 UI에 즉시 반영되지 않거나, 일부 컴포넌트만 반영됨

4) 테스트 및 문서화 부족

  • 주요 기능에 대한 테스트 코드 없음, 수동 테스트에 의존
  • 유지보수 시 오류 가능성 높고, 신규 개발자 온보딩 어려움

✅ 리팩토링 방향 및 해결 목표

이러한 문제들을 해결하고, 장기적인 유지보수성과 협업 효율을 높이기 위해
아래와 같은 방향으로 구조 리팩토링을 추진하였습니다.

1) 관심사 분리 및 역할 기반 구조 재설계

  • UI, 상태 관리, 로직, 스타일링을 모듈화하고 책임을 분리
  • containerpresenter 계층 구분으로 컴포넌트 재사용성 강화

2) 역할 기반 디렉토리 구조로 재편

  • 전체 코드를 content, background, iframe, service 영역으로 구분
  • FSD(Feature-Sliced Design) 패턴 적용 → 명확한 기능 책임 분배

3) 안정적이고 일관된 상태 관리 도입

  • 전역 상태를 상태 관리 라이브러리 or Context API로 통합 관리
  • chrome.storage와의 동기화를 추상화하여 일관성 확보

4) 테스트 기반 개발 환경 구축

  • 주요 로직 및 UI 컴포넌트에 대해 유닛 테스트, 스냅샷 테스트 도입
  • CI 환경에서 자동 검증 가능하도록 설정하여 안정적인 코드 배포 가능

이번 리팩토링은 단순한 기능 추가가 아닌,
VOIM이 '정보 접근성을 높이는 도구'로서 장기적으로 신뢰받을 수 있도록 하는 기술적 기반 마련입니다.

4. 해결계획

이번 리팩토링에서 적용될 주요 변경 사항은 다음과 같습니다.

1) 디렉토리 구조 개편

  • 전체 코드를 크게 컨텐츠(Content), 백그라운드(Background), 아이프레임(Iframe), 서비스(Service) 4개 영역으로 분리
  • 컨텐츠: 웹페이지에 주입되는 컨텐츠 스크립트들을 담당
  • 백그라운드: 크롬 익스텐션 백그라운드 스크립트 코드 관리
  • 아이프레임: 컨텐츠 스크립트에서 삽입하는 아이프레임 루트를 기준으로 한 React 앱 구성
    • FSD(Feature-Sliced Design) 패턴 적용, containerpresenter 계층으로 명확한 역할 분리
  • 서비스: 백그라운드와 컨텐츠 양쪽에서 공통으로 사용하는 기능들을 싱글톤 패턴 기반의 서비스 클래스로 통합 관리
/src
│
├── background/         # 크롬 백그라운드 스크립트
│   └── index.ts
│
├── content/            # 웹페이지에 삽입되는 스크립트
│   └── observer.ts
│
├── iframe/             # 실제 사용자 UI가 들어가는 React 앱 (아이프레임 기반)
│   ├── app/            # 앱 전역 설정 (라우팅, 테마 등)
│   ├── entities/       # 상태 + 도메인 로직 (예: Setting, User)
│   ├── features/       # 사용자 기능 단위 (예: FontControl, ContrastMode)
│   ├── shared/         # 공통 UI 컴포넌트, util 함수, hooks
│   ├── widgets/        # 조합된 UI 덩어리 (예: ControlPanel, Toolbar)
│   └── pages/          # 루트 페이지 (예: IframeRoot.tsx)
│
├── service/            # content/background에서 공통 사용하는 기능 (Storage, Messaging 등)
│   ├── storageService.ts
│   ├── messagingService.ts
│   └── accessibilityService.ts
│
├── styles/             # 전역 스타일 및 Tailwind 설정
│
├── types/              # 글로벌 타입 정의
│
└── manifest.json       # 크롬 익스텐션 설정 파일

iframe/
├── app/
│   ├── App.tsx
│   └── router.ts
│
├── entities/
│   └── setting/
│       ├── model/        # Zustand/Context 등 상태
│       ├── service/      # setting 관련 추상화된 동작
│       └── types.ts
│
├── features/
│   └── font-control/
│       ├── ui/           # <FontSizeSelector />
│       └── model/        # 관련 로직
│
├── widgets/
│   └── ControlPanel/
│       ├── index.tsx
│       └── style.css
│
├── shared/
│   ├── ui/               # Button, Slider 등
│   ├── lib/              # chromeAPI wrapper 등
│   └── hooks/

2) 상태 관리 및 서비스 통합

  • 공통 기능(데이터 저장, 메시지 전달 등)을 서비스 클래스로 캡슐화하여 중복 코드 제거 및 유지보수 편의성 증대
  • React 상태 관리는 컨테이너 컴포넌트 내에서 관리하며, 프레젠터 컴포넌트는 UI 렌더링에 집중하도록 역할 분리

3) UI 컴포넌트 구조 개선

  • FSD 패턴을 활용해 계층별 책임과 관심사를 명확히 분리
  • 재사용 가능한 UI 컴포넌트와 상태 관리 로직을 분리하여 확장성 강화

4) 개발 환경 및 코드 품질 향상

  • TypeScript 적용 및 ESLint, Prettier 설정 강화로 일관된 코드 스타일 유지
  • 테스트 커버리지 확대로 주요 컴포넌트 및 서비스 기능에 대한 안정성 확보

세부 계획

  1. 기존 구조 및 코드 문제점 목록화
  2. 역할 기반 디렉토리 구조 초안 작성
  3. 공통 기능을 서비스 클래스로 추출
  4. 상태 관리 체계 수립 (예: Context or 상태 라이브러리)
  5. 각 영역(content, background, iframe)별 리팩토링 착수
  6. 테스트 및 문서화 범위 정의 및 도입
  7. 빌드, 배포, 모니터링 체계 정비

5. 마무리

이리팩토링은 단순히 코드를 예쁘게 정리하려는 시도가 아닙니다.
VOIM이라는 프로젝트가 가진 접근성 기술로서의 사회적 의미를 더 많은 사용자에게 안정적으로 전달하기 위한 기술적 기반 마련 작업입니다.
아직은 진행 중인 단계이며, 앞으로 리팩토링이 실제로 어떤 효과를 가져왔는지도 글로 정리해 보겠습니다.

💬 같이 보면 좋은 글