# Apps in Toss Starter 새 프로젝트를 시작할 때 기준으로 쓰는 최소 설정이다. ## 목표 - RN `0.84.0` 타깃 번들이 포함된 `.ait` 생성 - 불필요한 Granite 플러그인 없이 Apps in Toss 기준으로 안정적으로 시작 ## 기본 원칙 - `build`는 반드시 `ait build` - `granite.config.ts`에는 `target: '0.84.0'` 명시 - `appsInToss({...})` 중심의 최소 구성 유지 - `router()`, `hermes()` 같은 추가 Granite 플러그인은 꼭 필요한 경우에만 사용 ## 시작 순서 ### 1. 프로젝트 생성 후 의존성 설치 프로젝트 루트에서: ```bash npm install ``` ### 2. `package.json` 설정 아래 형태로 맞춘다. ```json { "name": "my-app", "private": true, "scripts": { "dev": "granite dev", "build": "ait build", "deploy": "ait deploy", "check:build": "./check-apps-in-toss-build.sh" }, "dependencies": { "@apps-in-toss/framework": "^2.4.1", "@granite-js/native": "1.0.10", "@granite-js/react-native": "1.0.10", "brick-module": "0.5.1", "react": "19.2.3", "react-native": "0.84.0" }, "devDependencies": { "@types/react": "19.2.0", "babel-preset-granite": "1.0.10", "typescript": "^5.8.3" } } ``` ### 3. `babel.config.js` 추가 루트에 아래 파일을 반드시 둔다. ```js module.exports = { presets: ['babel-preset-granite'], }; ``` 이 파일이 없으면 `react-native` 패키지 내부 구문을 Metro가 잘못 파싱해서 `Missing semicolon` 에러가 날 수 있다. ### 4. `index.js` 엔트리 설정 루트 `index.js`는 아래처럼 시작한다. ```js const { register } = require('@granite-js/react-native'); register(require('./src/_app').default); ``` 그냥 `require('./src/_app')`만 하면 Granite 개발 엔트리포인트인 `shared`가 등록되지 않아 `"shared" has not been registered` 에러가 날 수 있다. ### 5. `granite.config.ts` 설정 아래처럼 시작한다. ```ts import { appsInToss } from '@apps-in-toss/framework/plugins'; import { defineConfig } from '@granite-js/react-native/config'; export default defineConfig({ appName: 'my-app', scheme: 'intoss', plugins: [ appsInToss({ target: '0.84.0', brand: { displayName: '내 앱 이름', primaryColor: '#0064FF', icon: 'https://static.toss.im/appsintoss/your-icon.png', }, navigationBar: { withBackButton: true, withHomeButton: true, }, permissions: [], }), ], }); ``` ### 6. `src/pages/_404.tsx` 추가 파일 기반 라우터가 fallback 페이지를 요구하므로 아래 파일을 기본으로 넣는다. ```tsx import { StyleSheet, Text, View } from 'react-native'; import { SafeAreaView } from '@granite-js/native/react-native-safe-area-context'; export default function NotFoundPage() { return ( Page not found 요청한 화면을 찾을 수 없습니다. ); } const styles = StyleSheet.create({ safeArea: { flex: 1, backgroundColor: '#F4F7FB', }, container: { flex: 1, alignItems: 'center', justifyContent: 'center', paddingHorizontal: 24, }, title: { color: '#111827', fontSize: 24, fontWeight: '700', marginBottom: 8, }, description: { color: '#4B5563', fontSize: 15, textAlign: 'center', }, }); ``` ## 권장하지 않는 시작 방식 아래는 이유 없으면 넣지 않는다. ```ts router() hermes() ``` 이 조합은 프로젝트에 따라 Apps in Toss 패키징 결과를 꼬이게 만들 수 있다. ## 개발 명령어 개발 서버: ```bash npm run dev ``` 빌드: ```bash npm run build ``` 배포: ```bash npm run deploy ``` 검증: ```bash npm run check:build ``` ## 빌드 후 반드시 확인할 것 ### 1. 빌드 로그 확인 아래 같은 로그가 보여야 한다. ```text [1/2] Built for RN 0.84.0 [2/2] Built for RN 0.72.6 ``` ### 2. `.ait` 안 번들 확인 아래 명령으로 확인: ```bash python3 - <<'PY' import zipfile path='my-app.ait' with zipfile.ZipFile(path) as z: for name in z.namelist(): if name.startswith('bundle.') and name.endswith('.js'): print(name) PY ``` 정상 예시: ```text bundle.ios.0_84_0.js bundle.android.0_84_0.js bundle.ios.0_72_6.js bundle.android.0_72_6.js ``` 중요한 건 최소한 아래 두 파일이 포함되는 것이다. - `bundle.ios.0_84_0.js` - `bundle.android.0_84_0.js` ## 문제 생겼을 때 체크리스트 ### `지원하지 않는 번들이에요. 최신 SDK를 사용해주세요`가 뜨면 순서대로 확인: 1. `granite.config.ts`에 `target: '0.84.0'`가 있는지 2. `package.json`의 `build`가 `ait build`인지 3. `.ait` 내부에 `bundle.*.0_84_0.js`가 실제로 들어 있는지 4. 예전 `.ait` 파일을 업로드한 건 아닌지 5. 불필요한 Granite 플러그인을 추가하지 않았는지 ## 새 프로젝트 시작용 빠른 체크 프로젝트 준비 후 아래만 실행하면 된다. ```bash npm install npm run build ``` 개발 실행 전에는 아래 파일들이 있는지 먼저 확인한다. - `babel.config.js` - `index.js` - `src/pages/_404.tsx` 그 다음 `.ait` 확인: ```bash python3 - <<'PY' import zipfile import pathlib ait_files = sorted(pathlib.Path('.').glob('*.ait')) if not ait_files: raise SystemExit('No .ait file found') path = str(ait_files[0]) print(path) with zipfile.ZipFile(path) as z: for name in z.namelist(): if name.startswith('bundle.') and name.endswith('.js'): print(name) PY ``` ## 실전 기준 요약 - 새 프로젝트는 Apps in Toss 최소 설정으로 시작 - `build`는 `ait build` - `target: '0.84.0'` 필수 - `.ait`에 `0_84_0` 번들이 있는지 꼭 확인 ## 템플릿 폴더 `starter/template` 폴더에는 새 프로젝트 시작용 기본 파일 세트를 넣어뒀다. - `package.json` - `granite.config.ts` - `babel.config.js` - `index.js` - `tsconfig.json` - `require.context.ts` - `.watchmanconfig` - `src/_app.tsx` - `src/pages/index.tsx` - `src/pages/_404.tsx` - `check-apps-in-toss-build.sh` 새 프로젝트를 만들 때는 이 폴더 내용을 복사한 다음 아래 값만 먼저 바꾸면 된다. - `package.json`의 `name` - `granite.config.ts`의 `appName` - `granite.config.ts`의 `brand.displayName` - `granite.config.ts`의 `brand.icon` - `src/pages/index.tsx`의 화면 문구