---
layout: post
title: '자잘한 도움말 #2 WSL 환경에 Expo 설정 중 일어나는 문제'
description: React Native, Expo, WSL, WSLHostPatcher
date: 2021-12-19 10:00:00 +0900
categories: [Micro]
---

## TL;DR
 - WSL 환경에서 React Native 개발을 위한 Expo 프레임워크 초기 설정 시,
   - WSL에서 열린 포트를 외부에서 접속할 수 있도록 해야한다.
   - Host IP Address 설정을 Windows의 IP Address로 바꾸는 것이 좋다.
   - `~/wsl` 폴더에 [WSLHostPatcher](https://github.com/CzBiX/WSLHostPatcher)를 다운받고 `~/.bashrc`에 다음 스크립트를 추가한다.

```shell
~/wsl/WSLHostPatcher.exe > /dev/null
export REACT_NATIVE_PACKAGER_HOSTNAME=$(netsh.exe interface ip show address "Wi-Fi" | grep 'IP Address' | sed -r 's/^.*IP Address:\W*//')
```

## 이하 그리 중요하진 않은 내용들

### 긴 서론

![리액트-네이티브](https://i.postimg.cc/vZ3jNP2F/reactnative.png)
{: .center}  

어느덧 2021년 연말, 꼼짝없이 백수 신세인 나는 심심함을 이기지 못하고 개인 프로젝트를 준비하게 되었다. 구상 중인 프로젝트는, 개인 혹은 토이라는 접두사를 달 수는 있어도 미니 라고는 못할 규모로, 모바일 클라이언트 어플리케이션을 필요로 하는 풀스택 개발을 요한다. 하지만 내가 주로 다루는 기술 스택은 자바스크립트, 그것도 사실상 Node에 한정. 심지어 자꾸 내 마음은 백엔드보다 프론트 개발에 더 집중하려한다.

그리하야 **리액트-네이티브(React Native, RN)**에 들이박았습니다.
{: .middle-big}

### 개발 환경 설정하기

지금 적고 있는 것도 블로그이긴 한데, 사실 나는 어떤 시스템이든 개발 환경을 설정하는데 있어 가장 좋은 방법은 블로그 포스팅 보다는 [공식 문서](https://reactnative.dev/docs/environment-setup)를 확인하는 거라고 생각한다.

![Setting up the blahblah](https://i.postimg.cc/FsTTxYnD/rn-setup.png)
{: .center}  

> 개발 환경 설정하기
>> 만약 모바일 개발에 처음이라면, Expo CLI를 통해 시작하는 것이 쉽습니다.  
>> Expo는 React Native 어플리케이션을 몇 분 만에 작성할 수 있도록 하는 기능을 제공합니다.  
>>  ...  
>> 만약 모바일 개발에 대해 이미 익숙하다면, React Native CLI를 사용하는 것 또한 좋습니다.  
>> ...

정리해보자면,  
 - Expo는 미리 구현된 도구들로 이루어진 프레임워크로, 초심자가 쉽게 RN 개발 환경을 설정할 수 있도록 해준다.
 - React Native CLI는 개발자가 좀 더 자기 입맞에 맞춰 RN 개발 환경을 설정할 수 있는 방법이다.

나는 모바일 개발은 사실상 처음이기도 하고, 쉬운 길로 가고싶어서 **expo**를 선택했다.

```shell
$ npm install -g expo-cli
$ expo init AwesomeProject
$ cd AwesomeProject
$ npm start
```

이렇게 명령어 입력 4번으로 빈 RN 프로젝트를 생성하고 실행할 수 있다.  

![expo init](https://i.postimg.cc/KvdRC2jB/expo.png)  
성숙한 도구는 CLI가 이쁘다.
{: .center}  

`npm start` 혹은 `expo start`를 입력하면 어플리케이션이 올라갈 Expo의 CLI가 실행된다.

![expo cli](https://i.postimg.cc/fygc54Pw/expo-cli.png)  
성숙한 도구는 CLI가 정말 이쁘다.
{: .center}

CLI에서 `w`를 입력하면 웹 서버가 실행되고(실행 시 그냥 `npm run web` 입력해도 웹 서버가 바로 시작된다), 우리는 http://localhost:19006 으로 접근해 어플리케이션의 모습을 확인할 수 있다.

![expo web](https://i.postimg.cc/QtzgJGwj/expo-web.png)  
황량함 그 자체...
{: .center}

이제 이걸 우리의 모바일 디바이스에서도 확인해야지. CLI를 보면 눈에 띄는 부분이 있는데, 바로 **QR 코드**. Expo는 [Expo Go](https://expo.dev/client)라는 모바일 어플리케이션을 제공한다. 우리는 Expo Go를 통해 QR코드를 찍어 Expo에 빌드된 어플리케이션을 실행할 수 있다.

![expo go](https://i.postimg.cc/fTvc8r3n/image.png)  
이참에 한 번 해본 윈도우에서 폰 화면 보기  
{: .center}  

그래서 저 어플로 QR코드 찍고, 모바일 디바이스에서 작동 확인해가며 개발하면 된다. **당신이 Mac 유저라면 여기서 끝.**

### Trouble...

![맥북](https://i.postimg.cc/J0tjKxzj/image.png)  
[장삐쭈 - 노트북](https://youtu.be/Wq6NiXskxus) 中 발췌
{: .center}

내가 이 글을 쓰고있는 이유이자, 내면의 반골 기질의 결과물, 나는 맥북을 쓰지 않는다. 개발 환경은 WSL에 모두 몰아넣었고, 그 점에서 문제가 발생한다.  

![LAN]({{site.baseurl}}/assets/pictures/tip02-01.png)  
{: .center}  

기초지식을 다시 되새겨보자. Expo Go가 QR코드를 통해 마법의 문을 열어준 덕분에 우리가 빌드된 어플리케이션을 확인할 수 있는게 아니다. 서버의 주소(개발 PC에서는 localhost로 접근했던 그 주소)로 서버에 접근해 정보를 받아왔기 때문에 모바일 기기에서 어플리케이션이 실행될 수 있는 것이다.

사실 개발 PC의 OS 바로 위에 Expo를 설치했다면, 그게 뭐? 라고 할 법한 이야기이다. 하지만 WSL에 Expo를 설치했다면 다음과 같은 문제를 직면해야 한다.

![ㅁㄹ]({{site.baseurl}}/assets/pictures/tip02-02.png)  
VM의 벽을 물리적으로 격파하기.JPG
{: .center}

WSL은 Windows PC를 개발용으로 쓸만하게끔 만드는데 큰 기여를 했지만, 우리는 그 특성을 항상 명심해둬야 한다.  

- WSL은 VM
{: .middle-big}  

우리의 PC 환경과 격리되어있다. WSL의 리눅스 콘솔에 출력된 QR 코드를 우리의 휴대폰으로 촬영하는 것은 WSL의 논리적인 벽을 물리적으로 깨뜨리는 행동이라고 볼 수 있다.

![tomstoms](https://i.postimg.cc/RVrb72ML/tomstoms.png)  
{: .center}

Expo CLI는 WSL 머신의 주소를 통해 QR 코드를 만들었기 때문에 그 QR을 통해 접근하려해도 이렇게 타임아웃 에러가 발생할 것이다.  

![ㅁㄹ2]({{site.baseurl}}/assets/pictures/tip02-03.png)  
{: .center}

그렇다면 모바일 브라우저를 열고 직접 개발 PC의 주소를 입력해서 접근할 수는 없을까? 이 또한 역시 에러를 뱉는데, Expo의 포트는 WSL에서 열린 포트이기 때문. WSL에 열린 포트는 로컬 호스트에서만 접근할 수 있다.

### Shooting #1

 - 참고자료 1. [Running Expo in Windows Subsystem for Linux](https://blog.expo.dev/running-expo-in-windows-subsystem-for-linux-wsl2-425f6fd7838e)  
 - 참고자료 2. [How can i connect my phone to expo when using WSL2 to run it](https://stackoverflow.com/questions/58777404/how-can-i-connect-my-phone-to-expo-when-using-wsl2-to-run-it)  
{: .middle-small}

![beforeports](https://i.postimg.cc/sfnQTxn3/ports.png)  
{: .center}  

![after](https://i.postimg.cc/YSnNYRmw/0000port.png)  
before vs after, 차이가 느껴지십니까?
{: .center}

WSL에 열린 포트는 `wslhost.exe` 프로세스에 의해 윈도우의 포트와 포워딩된다. 하지만 첫 번째 사진 처럼 `127.0.0.1` 주소, 즉 로컬 호스트에서만 접근할 수 있도록 설정된다.  

[WSLHostPatcher](https://github.com/CzBiX/WSLHostPatcher)는 간단히 말하자면 `wslhost.exe`가 `127.0.0.1`이 아닌 `0.0.0.0`로 주소를 설정하도록 만드는 프로그램이다. README에 따르면 윈도우에 설치해서 WSL 실행시 마다 실행해줘야 한다는데, 일단 WSL에 설치해서 실행해도 잘 작동하더라.

```shell
~/wsl$ wget https://github.com/CzBiX/WSLHostPatcher/releases/download/v0.1.2/WSLHostPatcher.zip
~/wsl$ unzip WSLHostPatcher.zip
~/wsl$ chmod 755 WSLHostPatcher.exe
```

---

**(2024년 2월 14일 추가)**  
2023년 3월 31일에 있었던 WSL 업데이트에서 [`wslhost.exe`의 일부 기능을 `wslrelay.exe` 라는 새로운 프로세스가 담당하도록 구조가 변경되었다](https://github.com/microsoft/WSL/discussions/9874#discussion-5024039). 따라서 기존 글에서 다운로드 했던 WSLHostPathcer 0.1.0 버전에선 기능이 제대로 동작하지 않을 것이다. 일단 0.1.2 버전을 다운로드 하도록 글을 업데이트 해두었으나 위 명령어를 그냥 따라하지 말고, [`wget`으로 다운로드 받을 URL이 최신 버전인지 꼭 확인하자](https://github.com/CzBiX/WSLHostPatcher/releases).

---

![요로코롬](https://i.postimg.cc/bwyfv0ch/image.png)  
요로코롬. 실행 권한 주는것도 까먹지 말자.  
{: .center}

그리고 `~/.bashrc` 파일에 다음 라인을 추가해 WSL 실행 시 마다 프로그램이 실행되도록 설정한다.

```shell
~/wsl/WSLHostPatcher.exe > /dev/null
```

### Shooting #2
이제 Expo가 만들어낸 QR 코드가 WSL 머신의 주소가 아닌 개발 PC가 네트워크에서 가지는 주소를 가리키도록 바꿔야한다.

`REACT_NATIVE_PACKAGER_HOSTNAME`

Expo는 위의 환경변수를 통해 Hostname을 결정한다. 사실 저게 어떻게 결정되는지 좀 더 정보를 찾고싶었는데, 잘 안나오더라. 아무튼 저걸 바꿔주면 된다.

```shell
export REACT_NATIVE_PACKAGER_HOSTNAME=$(netsh.exe interface ip show address "Wi-Fi" | grep 'IP Address' | sed -r 's/^.*IP Address:\W*//')
```

명령어가 조금 길다. WSL 머신의 내부 네트워크 주소, 그리고 내 개발 PC의 네트워크 주소가 항상 고정이라면 짧게 설정할 수 있을텐데, 이렇게 설정해줌으로써 이제 우리는 카페에 가서 새로운 와이파이를 잡아도 당황하지 않을 수 있다.

이 명령어도 `.bashrc`에 추가하고 WSL을 재부팅하자.

----

### 그 결과

![끝](https://i.postimg.cc/g09hb0L1/image.png)  
이걸로 성실하게 개발... 해야겠지...
{: .center}

사실 이건 RN이나 Expo를 잘 다루는 법에 대한 문제라기 보단, 네트워크에 대한 기본 지식을 다시 되새기게되는 경험이 아니었나싶다.

## 내가 배운 것
 - React Native 개발에 도움을 주는 도구 Expo.
 - **기본적으로, WSL에 실행된 서버는 로컬 머신에서만 접근 가능하다.**
 - 글 쓰는 것은 역시 쉽지 않다.