chore: initial Expo SDK 56 + RN 0.85 + TS 6 setup with vision-camera/skia deps

W1 Task 1 Windows 가능 범위 완료.

핵심 파일:
- package.json: lapie name + scripts(start/ios/android/web/test/typecheck)
- app.json: bundleIdentifier com.lapie.app + iOS 권한 3종
  (NSCameraUsageDescription, NSPhotoLibraryUsageDescription, NSPhotoLibraryAddUsageDescription)
- tsconfig.json: strict + noUncheckedIndexedAccess + types:["jest"]
- jest.config.js: jest-expo preset
- src/__tests__/sanity.test.ts: jest 동작 검증용 (W1 Task 3에서 실제 테스트로 대체 예정)

의존성:
- expo ~56.0.4, react 19.2.3, react-native 0.85.3
- react-native-vision-camera ^5.0.10
- @shopify/react-native-skia 2.6.2
- react-native-worklets-core ^1.6.3
- react-native-gesture-handler ~2.31.1
- react-native-safe-area-context ~5.7.0
- zustand ^5.0.13
- jest ^29.7.0, jest-expo ^56.0.4, @types/jest ^30

SDK 버전은 v0-plan(2026-05-23 작성)의 표기보다 상향:
- Expo SDK 52 → 56 (작업 시점 최신 stable)
- RN 0.76 → 0.85, TS 5 → 6
- vision-camera v4 → v5, skia v1 → v2.6
plan은 "7월 착수 직전 재검토" 명시 — 작업 시점 최신 적용.

검증:
- npx tsc --noEmit: 무에러
- npm test: sanity 1 passed

다음 단계 (Mac):
- npx expo prebuild --platform ios
- npx expo run:ios --device
- W1 Task 2 (vision-camera 카메라 화면 + 권한)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-24 15:41:31 +09:00
parent 1a03b71779
commit 2919b7b4ac
14 changed files with 10833 additions and 0 deletions

20
App.tsx Normal file
View File

@@ -0,0 +1,20 @@
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<Text>Open up App.tsx to start working on your app!</Text>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});

32
app.json Normal file
View File

@@ -0,0 +1,32 @@
{
"expo": {
"name": "Lapie",
"slug": "lapie",
"version": "0.0.1",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"ios": {
"supportsTablet": false,
"bundleIdentifier": "com.lapie.app",
"infoPlist": {
"NSCameraUsageDescription": "옷을 카메라에 비춰 합성 미리보기에 사용합니다.",
"NSPhotoLibraryUsageDescription": "정면 사진을 등록하고 캡쳐를 저장하기 위해 사용합니다.",
"NSPhotoLibraryAddUsageDescription": "합성 결과 사진을 저장하기 위해 사용합니다."
}
},
"android": {
"package": "com.lapie.app",
"adaptiveIcon": {
"backgroundColor": "#E6F4FE",
"foregroundImage": "./assets/android-icon-foreground.png",
"backgroundImage": "./assets/android-icon-background.png",
"monochromeImage": "./assets/android-icon-monochrome.png"
},
"predictiveBackGestureEnabled": false
},
"web": {
"favicon": "./assets/favicon.png"
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
assets/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB

BIN
assets/splash-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

8
index.ts Normal file
View File

@@ -0,0 +1,8 @@
import { registerRootComponent } from 'expo';
import App from './App';
// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
// It also ensures that whether you load the app in Expo Go or in a native build,
// the environment is set up appropriately
registerRootComponent(App);

6
jest.config.js Normal file
View File

@@ -0,0 +1,6 @@
/** @type {import('jest').Config} */
module.exports = {
preset: 'jest-expo',
testPathIgnorePatterns: ['/node_modules/', '/ios/', '/android/'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
};

10720
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

33
package.json Normal file
View File

@@ -0,0 +1,33 @@
{
"name": "lapie",
"version": "0.0.1",
"private": true,
"main": "index.ts",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"test": "jest",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@shopify/react-native-skia": "2.6.2",
"expo": "~56.0.4",
"expo-status-bar": "~56.0.4",
"react": "19.2.3",
"react-native": "0.85.3",
"react-native-gesture-handler": "~2.31.1",
"react-native-safe-area-context": "~5.7.0",
"react-native-vision-camera": "^5.0.10",
"react-native-worklets-core": "^1.6.3",
"zustand": "^5.0.13"
},
"devDependencies": {
"@types/jest": "^30.0.0",
"@types/react": "~19.2.2",
"jest": "^29.7.0",
"jest-expo": "^56.0.4",
"typescript": "~6.0.3"
}
}

View File

@@ -0,0 +1,5 @@
describe('sanity', () => {
it('jest는 잘 동작한다', () => {
expect(1 + 1).toBe(2);
});
});

9
tsconfig.json Normal file
View File

@@ -0,0 +1,9 @@
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"types": ["jest"]
},
"include": ["**/*.ts", "**/*.tsx"]
}