라떼는 expo 쓰면 RN 하는거 아니라고 했었는데
expo 도 꾸준히 발전해서 요즘에는 스타트업
프로덕션에서도 가끔 쓰이는 것 같다
npx create-expo-app@latest my-app --template blank-typescript
blank-typescript 템플릿 특징
• TypeScript 사용: 프로젝트가 TypeScript로 설정되어 있어, 타입 안전성을 제공합니다.
• 빈 프로젝트: 최소한의 설정만 포함되어 있어, 개발자가 원하는대로 프로젝트를 구성할 수 있습니다.
• Expo SDK 포함: 최신 Expo SDK가 포함되어 있어, Expo의 다양한 기능을 사용할 수 있습니다.
expo 라우터는 RN 에서 자주 쓰이던 React Navigation 기반으로 클라이언트 라우팅을 제공하는
expo 추가 기능
Next.js 의 App router 폴더 기반 라우팅과 비슷하게
기본적으로 파일 기반 라우팅을 제공한다
React Navigation 의 다른 기능도 사용 가능
npx expo install react-native-screens react-native-safe-area-context @react-navigation/native @react-navigation/native-stack @react-navigation/elements @expo/next-adapter @expo/router
app.json 설정
{
"expo": {
// ...
"plugins": ["expo-router"],
"router": {
"base": "src/app"
},
"experiments": {
"typedRoutes": true
}
}
}
tsconfig.json
{
"compilerOptions": {
"types": ["expo-router"]
}
}
typedRoutes 와 tsconfig 설정을 해줘야
타입 검사를 해준다
next.js 에서는 이제 기본 제공되지만
둘 다 만들어줘야 한다 작동 방식은 비슷함
_layout.tsx
import { View, Text, SafeAreaView, StatusBar } from "react-native";
import { Slot } from "expo-router";
function Layout() {
return (
<SafeAreaView style={{ flex: 1, backgroundColor: "#aaa" }}>
{/* iOS 는 상태바가 background 에 포함되어 있음 */}
<StatusBar
barStyle={"light-content"}
backgroundColor="#aaa" // 상태바 색상은 Android 에서만 작동
translucent={false}
hidden={false}
networkActivityIndicatorVisible={true}
animated={true}
/>
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Slot />
<Text>Footer</Text>
</View>
</SafeAreaView>
);
}
export default Layout;
app 하위에 두면 기본 layout 으로 사용되면서
slot 을 통해 파일 기반 라우팅이 된다
+not-found.tsx
import { View, Text } from "react-native";
import { Link } from '@expo/router';
function NotFound() {
return (
<View>
<Text>404 Not Found</Text>
<Link href="/">Home</Link>
</View>
);
}
export default NotFound;
NotFound 페이지는 + 로 작성하는게 컨벤션인듯
npm install --save-dev babel-plugin-module-resolver
babel.config.js
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
[
'module-resolver',
{
root: ['.'],
alias: {
'@': './src',
},
},
],
],
};
tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
},
},
}