프론트엔드 개발/Next.js

Next.js + React Native 크로스 플랫폼 개발을 위한 Solito, NativeWind 소개

snowman95 2023. 10. 3. 17:48
728x90
반응형

최근에 회사에서 Next.js 로 개발한 웹 서비스를 앱으로도 서비스 해야할 수도 있는 가능성이 생겼습니다.

간단하게는 React Native 껍데기에 Webview 로 웹 서비스를 띄울 생각이었으나,

찾아보니 이쪽 분야가 예전보다 꽤 많이 발전하고 있는 것 같아서 시험삼아 찍먹 해볼까? 그런 생각이 들 정도더군요.

 

예전에 프로젝트를 하면서 모노레포로 웹/앱 간 코드를 공유하여 크로스 플랫폼을 개발할 수 있으면 참 좋겠다 싶었는데 최근에는 그런 방식으로 개발을 할 수 있게 생태계가 정말 많이 성장 했습니다.

 

제 경험상 웹 개발에서 ReactNative 개발을 찍먹 할때 어려웠던 부분은 라우팅/내비게이션, View 등을 새로 배워야 한다는 것과 css 스타일 적용 방식이 달라서 그 부분을 다시 배워야 하고, 다시 개발해야 해야한다는 점이었습니다. 

이를 해결하려 노력한 몇 가지 라이브러리를 소개합니다.

 

Solito : cross-platform navigation

fernando rojo 씨가 개발한 크로스 플랫폼간 내비게이션 코드를 공유할 수 있게 해주는 라이브러리 입니다.

https://solito.dev/

 

Soltio 의 API는 next/link, next/router, next/image 등의 기능을 완벽히 반영합니다.

Solito 를 사용하면 Native 에서 Next.js 의 useRouter, Link 등을 거의 그대로 쓰기 때문에 이런 문제가 해결됩니다.

 

Solito는 플랫폼 간에 격리되어 실행되도록 의도적으로 구축되었습니다.

Solito의 API 를 사용하면 Next.js 와 React Native 에서 동일하게 작동하는데 내부적으로는 플랫폼별로 다른 코드를 사용합니다. 두 소스가 충돌되지 않습니다.

 

Solito는 새로운 접근 방식을 취합니다. 즉, 각 플랫폼이 가장 잘하는 일을 하도록 놔두는 것입니다. 

Solito는 Native에서는 React Navigation을, 웹에서는 Next.js Router를 사용합니다.

 

 

 

NativeWind

모든 플랫폼에서 일관된 스타일 경험을 제공하고 개발자 UX 및 코드 유지 관리성을 향상시키는 것을 목표로 하는 라이브러리 입니다.

https://www.nativewind.dev/

 

웹에서는 스타일을 className props 로 전달하면 됩니다.

그러나 React Native 에는 CSS 엔진이 없으므로 CSS 출력을 StyleSheet 객체로 처리해야 합니다.

그래서 NativeWind 는 Tailwind 를 대신하여 스타일을 CSS로 처리한 다음 NativeWindStyleObjects 로 컴파일합니다.

 

 

Solito 프로젝트는 일반적으로 모노레포를 공유하는 두 개의 별도 애플리케이션입니다
(일반적으로 Expo 및 Next.js 애플리케이션)

예제 프로젝트를 뜯어서 보면, 공통 UI 화면 컴포넌트 Solito API 를 사용하여 페이지 라우팅을 처리하고 있습니다. 라우팅 처리와 스타일을 플랫폼에 공통적으로 사용할 수 있게 되면서 이러한 모노레포 구조가 가능하게 되었습니다.

위:ReactNatvie(EXPO) / 아래:Next.js

이와 같이 UserDetailScreen 은 크로스 플랫폼 공용 화면 컴포넌트로 사용되고 있습니다.

크로스 플랫폼 공용 화면 컴포넌트

물론 마법처럼 그냥은 안됩니다. 

web 에서 하는 것 처럼 className 을 먹일 수 있게 하기 위해 nativewind 라이브러리의 styled 또는 StyledProps 를 넣어서 Wrapping 해주는 과정이 필요합니다. 

귀찮은 과정이긴 하지만, 크로스 플랫폼 구축에 이정도 비용을 치룰만한 가치가 충분히 있다고 생각됩니다. 웹, 앱 간의 화면 단위가 다른 (px, dp) 것과 flex 스타일 처리, className 사용 등을 처리해줍니다.

특히 a 테그는 좀 복잡하군요.

 

아래는 각 플랫폼에 다른 스타일 적용하는 방법 입니다.

 

 

feed 라는 컴포넌트를 예로 들자면

App 용은 feed.tsx, Web 용은 feed.web.tsx 로 파일을 만들어서 각각 처리 할 수도 있는 듯 합니다.

 

그러나 이 라이브러리에도 당연히 단점이 있는데.. tailwind css 완전 최신 버전을 사용하지 못한다는 단점이 있습니다.

그래도 업데이트가 정기적으로 이루어지고 있으며, 문서도 잘 되어있다는 점이 강점입니다.

 

 

예제 프로젝트

아래 명령어를 통해 예제 프로젝트를 테스트해볼 수 있습니다. (제가 만든건 아닙니다 ㅎㅎ)

npx create-solito-app@latest my-solito-app -t with-tailwind
 
 

마무리

tailwind 문법 그대로 쓰는 것만 해도 감사합니다 절을 해야 할 판인데 기존에 쓰던 UI 컴포넌트를 못쓴다고 또 징징거리게 됩니다.😅

(tailwind 가 싫은 분들은 nativewind 말고도 dripsytamagui 도 사용해볼 수는 있습니다.)

 

당연히 커스텀이 제한적이지 않을까 라는 걱정도 있습니다.

이슈 발생시 도움받을 곳이 없다는 것도 큰 문제 입니다... 이것 때문에라도 프로덕션 레벨에서는 못쓸 것 같습니다.

그래도 예제 프로젝트 돌려보면 정말 재미있고 놀랍습니다. 대단히 복잡한 프로젝트가 아니라면 어려움 없이 똑같은 코드로 크로스 플렛폼에서 돌아가는 화면이 만들어집니다.

 

 

정리하자면...

  • Solite + NativeWInd 조합으로 라우팅 걱정없이 UI 화면을 모든 플랫폼에 일관성있게 사용 가능하다.
  • 모노레포 구성으로 크로스플렛폼 간 리소스와 상수 파일 등 많은 것들을 공유할 수 있다. 개발팀이 극소수거나 1인 개발시 어쩌면 매우 훌륭한 선택이 될 지도?..
  • web전용 라이브러리와 native전용 라이브러리가 호환 안되기 때문에 라이브러리 범벅된 컴포넌트는 각자 만들어야 한다. 이경우,
    • 앱용은 컴포넌트.tsx
    • 웹용은 컴포넌트.web.tsx
  • Next.js 에서 되는 기능을 Native 에도 적용하려면 추가 설정을 알아서 해줘야 한다. Solite 공식 문서에 이런것들을 잘 설명해준다. 
반응형