[이마고웍스] 도메인 매핑에서의 리액트 개발 환경 이슈 해결 경험

Ji-Heon Park·2023년 12월 22일
0

Imagoworks

목록 보기
10/10

이마고웍스에서는 SwitchHosts 도구를 사용하여 로컬 개발 서버를 특정 도메인에 매핑하는 방식으로 개발 환경을 구축하고 있습니다. 이 방법은 개발 서버의 localhost 주소를 실제 도메인처럼 사용할 수 있게 해주어, 실제 운영 환경과 유사한 조건에서 개발과 테스트를 진행할 수 있도록 합니다.

e.g. localhost:3000 -> www.servicename-dev.com

이러한 설정은 특히 도메인 기반 기능(예: 쿠키, CORS, 인증 메커니즘)의 로컬 테스트를 용이하게 합니다. 이는 실제 운영 환경에서 발생할 수 있는 문제들을 사전에 파악하고 해결할 수 있는 기회를 제공합니다.

이러한 개발 환경에서 몇가지 문제 상황이 있었습니다.

문제 1: 리액트 HMR(Hot Module Replacement) 미지원

Hot Module Replacement (HMR)은 웹팩(Webpack)과 같은 모듈 번들러를 사용하는 개발 환경에서 중요한 기능입니다. HMR의 역할은 개발 중에 소스 코드가 변경되었을 때, 전체 페이지를 새로고침하지 않고도 변경된 모듈만을 실시간으로 교체하는 것입니다. 이로 인해 개발자는 변경 사항을 빠르게 볼 수 있으며, 애플리케이션의 상태를 유지하면서 개발을 진행할 수 있습니다.

하지만 도메인 매핑으로 인해 HMR이 제대로 작동하지 않는 문제가 발생했습니다. 이는 개발 효율성을 저하시키는 중요한 이슈였습니다.

해결과정

이미 리액트에서 HMR을 작동시키는 방법에 대하여 여러 시도를 하였지만 모두 효과가 없었습니다. 하지만 프로젝트는 모두 CRA 기반이라 별 다른 설정없이도 HMR이 작동해야 합니다. 좀 더 근본적인 원인 파악을 위해 HMR의 작동원리를 파악하였습니다.

HMR이 작동하는 방식은 다음과 같습니다:

  1. 개발 서버 실행: 웹팩 개발 서버(webpack-dev-server)가 실행되며, HMR 플러그인이 활성화됩니다.
  2. 웹소켓 연결: 개발 서버는 클라이언트(브라우저)와 웹소켓을 통한 연결을 설정합니다. 이 연결을 통해 서버는 코드 변경 사항을 클라이언트에 실시간으로 전달할 수 있습니다.
  3. 코드 변경 감지: 개발자가 소스 코드를 변경하면, 웹팩은 이를 감지하고 변경된 모듈을 새로 빌드합니다.
  4. HMR 업데이트 전송: 변경된 모듈 정보가 웹소켓을 통해 클라이언트에 전송됩니다.
  5. 클라이언트에서의 모듈 교체: 클라이언트는 받은 정보를 바탕으로 변경된 모듈만을 교체하고, 애플리케이션이 해당 변경 사항을 반영합니다.

작동 방식을 통해 파악한 문제의 근본 원인은 웹소켓 연결 설정의 불일치였습니다. 웹소켓 서버가 기대하는 호스트 주소(localhost)와 실제 매핑된 도메인 주소 간의 불일치로 인해 웹소켓 연결이 실패하였습니다.

이를 해결하기 위해 WDS_SOCKET_HOST='localhost' 환경 변수를 설정함으로써, 웹팩 개발 서버의 웹소켓 호스트 주소를 명시적으로 지정하고, 클라이언트와 서버 간의 웹소켓 연결이 정상적으로 이루어지도록 조정했습니다. 이를 통해 HMR이 정상적으로 작동하게 되었습니다:

문제 2: 개발 서버 접근성 문제

개발 서버가 로컬 호스트(localhost)가 아닌, 매핑된 도메인(예: www.servicename-dev.com)에서만 접근 가능하게 설정되어 있었습니다. 이로 인해 개발자들은 개발 서버를 실행할 때마다 직접 매핑된 도메인 주소로 접속해야 하는 불편함이 있었습니다. 로컬 호스트 대신 특정 도메인에만 서비스를 제공하는 방식이 개발 과정에서의 접근성을 제한했습니다.

해결책 1

가장 간단한 해결책으로는 웹팩 설정을 통해 지정한 URL을 오픈하는 것입니다. (관련 웹팩 문서)

  1. 환경변수 BROWSER=none을 통해 기존 로컬호스트의 열림을 막기
  2. 웹펙 설정에 아래와 같이 추가하기
devServer: {
    open: {
      target: 'https://cloud-bo.dev-dentbird.com',
    },
    ...

해결책 2

위 같은 방법으로 대부분 해결 가능 하지만 사내 프로젝트 중 모노레포로 이루어진 경우, 각각 다른 URL을 가지고 있어 다른 방법이 필요했습니다.

이를 위해 세가지 라이브러리를 사용했습니다.

  • open-cli: 특정 URL을 사용자의 기본 웹 브라우저에서 열기 위해 사용합니다.
  • wait-on: 특정 포트, 파일, HTTP 요청이 사용 가능해질 때까지 기다리는 데 사용합니다.
  • concurrently: 여러 명령어를 동시에 실행하고 관리하기 위한 도구입니다. 기존 실행 코드 와 샌드박스 url open 을 동시 실행하기 위해 필요합니다. React 앱이 시작하는 프로세스가 백그라운드에서 계속 실행되기 때문에 이를 통해 병렬적으로 실행해줍니다.
  1. 환경변수 BROWSER=none을 통해 기존 로컬호스트의 열림을 막기
  2. npm 명령어 스크립트 변경
"scripts": {
    "start:desktop-sandbox": "concurrently --kill-others-on-fail \"{기존 실행 명령어}" \"wait-on http://localhost:3000 && open-cli https://cloud.dev-dentbird.com\"",
    "start:mobile-sandbox": "concurrently --kill-others-on-fail \"{기존 실행 명령어}" \"wait-on http://localhost:3001 && open-cli https://m.cloud.dev-dentbird.com\"",
...

}

위 두가지 방법을 사용하여 개발 서버가 실행될 때 자동으로 매핑된 도메인으로 리다이렉트되는 스크립트를 구현하여, 개발자가 수동으로 URL을 입력하는 불편함을 해소했습니다. 이러한 해결책들은 개발 환경의 효율성과 편의성을 크게 향상시켰으며, 특히 복잡한 도메인 매핑 구조에서 리액트 애플리케이션을 더욱 원활하게 개발할 수 있게 도왔습니다:

결론

리액트 HMR의 정상 작동은 개발자 경험 향상, 개발 서버의 접근성 문제 해결로 개발 과정의 효율성이 높아졌습니다. 전체적으로 개발 속도와 편의성을 증진시키는 결과를 가져왔습니다. 이 경험으로 문제가 발생했을 때, 표면적인 증상에만 집중하는 것이 아니라, 근본적인 원인을 찾아 해결하는 것이 중요하다는 것을 알았습니다.

profile
Frontend Developer | 기록되지 않은 것은 기억되지 않는다

0개의 댓글

관련 채용 정보