최근에 회사에서 Next.js 로 개발한 웹 서비스를 앱으로도 서비스 해야할 수도 있는 가능성이 생겼습니다.
간단하게는 React Native 껍데기에 Webview 로 웹 서비스를 띄울 생각이었으나,
찾아보니 이쪽 분야가 예전보다 꽤 많이 발전하고 있는 것 같아서 시험삼아 찍먹 해볼까? 그런 생각이 들 정도더군요.
예전에 프로젝트를 하면서 모노레포로 웹/앱 간 코드를 공유하여 크로스 플랫폼을 개발할 수 있으면 참 좋겠다 싶었는데 최근에는 그런 방식으로 개발을 할 수 있게 생태계가 정말 많이 성장 했습니다.
제 경험상 웹 개발에서 ReactNative 개발을 찍먹 할때 어려웠던 부분은 라우팅/내비게이션, View 등을 새로 배워야 한다는 것과 css 스타일 적용 방식이 달라서 그 부분을 다시 배워야 하고, 다시 개발해야 해야한다는 점이었습니다.
이를 해결하려 노력한 몇 가지 라이브러리를 소개합니다.
Solito : cross-platform navigation
fernando rojo 씨가 개발한 크로스 플랫폼간 내비게이션 코드를 공유할 수 있게 해주는 라이브러리 입니다.
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 및 코드 유지 관리성을 향상시키는 것을 목표로 하는 라이브러리 입니다.
웹에서는 스타일을 className props 로 전달하면 됩니다.
그러나 React Native 에는 CSS 엔진이 없으므로 CSS 출력을 StyleSheet 객체로 처리해야 합니다.
그래서 NativeWind 는 Tailwind 를 대신하여 스타일을 CSS로 처리한 다음 NativeWindStyleObjects 로 컴파일합니다.
Solito 프로젝트는 일반적으로 모노레포를 공유하는 두 개의 별도 애플리케이션입니다
(일반적으로 Expo 및 Next.js 애플리케이션)
예제 프로젝트를 뜯어서 보면, 공통 UI 화면 컴포넌트 Solito API 를 사용하여 페이지 라우팅을 처리하고 있습니다. 라우팅 처리와 스타일을 플랫폼에 공통적으로 사용할 수 있게 되면서 이러한 모노레포 구조가 가능하게 되었습니다.
이와 같이 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 말고도 dripsy, tamagui 도 사용해볼 수는 있습니다.)
당연히 커스텀이 제한적이지 않을까 라는 걱정도 있습니다.
이슈 발생시 도움받을 곳이 없다는 것도 큰 문제 입니다... 이것 때문에라도 프로덕션 레벨에서는 못쓸 것 같습니다.
그래도 예제 프로젝트 돌려보면 정말 재미있고 놀랍습니다. 대단히 복잡한 프로젝트가 아니라면 어려움 없이 똑같은 코드로 크로스 플렛폼에서 돌아가는 화면이 만들어집니다.
정리하자면...
- Solite + NativeWInd 조합으로 라우팅 걱정없이 UI 화면을 모든 플랫폼에 일관성있게 사용 가능하다.
- 모노레포 구성으로 크로스플렛폼 간 리소스와 상수 파일 등 많은 것들을 공유할 수 있다. 개발팀이 극소수거나 1인 개발시 어쩌면 매우 훌륭한 선택이 될 지도?..
- web전용 라이브러리와 native전용 라이브러리가 호환 안되기 때문에 라이브러리 범벅된 컴포넌트는 각자 만들어야 한다. 이경우,
- 앱용은 컴포넌트.tsx
- 웹용은 컴포넌트.web.tsx
- Next.js 에서 되는 기능을 Native 에도 적용하려면 추가 설정을 알아서 해줘야 한다. Solite 공식 문서에 이런것들을 잘 설명해준다.
'프론트엔드 개발 > Next.js' 카테고리의 다른 글
[프로젝트 기록] Next.js 의 SSG 는 너무 느려서 못써먹겠다. (4) | 2024.09.30 |
---|---|
Next.js 에서 소셜 로그인 구현하기 (next-auth.js 사용) (1) | 2023.02.18 |
Next.js 13 버전에서 ReactQuery 사용시 서버 컴포넌트에서 클라이언트 컴포넌트로 pre-fetch 데이터 전달하는 방법 (4) | 2023.02.05 |
웹 프레임워크 Next.js 는 무엇인가요? (프론트 면접 질문) (0) | 2023.02.05 |
Next 13 버전에서 App 디렉토리 사용방법 및 소개 (3) | 2023.01.30 |