架构

了解运行时架构、Provider、启动门禁和导航。

Expo 模板把架构放在少数关键文件中,而不是藏在额外框架层里。 app/_layout.tsx 是 runtime composition root,Expo Router 负责导航, TanStack Query 负责 server state,provider hooks 是 dependency-injection surface。

路由

Expo Router 把文件映射为 routes,app.config.ts 开启了 experiments.typedRoutes

模式文件或示例说明
Route groupsapp/(auth)app/(tabs)分组文件,不改变 URL path
Tabsapp/(tabs)/_layout.tsx四个可见 tab,加上 href: null 的隐藏 tab-context screens
Pushed screensapp/todos.tsxapp/profile.tsxapp/permissions.tsx从 drawer、cards 或 deep links 打开
Dynamic routesapp/component/[slug].tsxuseLocalSearchParams() 读取 slug
ModalsStack.Screen name="paywall"name="redeem-code"Root stack 设置 presentation: 'modal'
Fallbackapp/+not-found.tsx处理未知 path
Web shellapp/+html.tsxpnpm web 与 Metro static output 使用

可通过 deep link 打开的 path 在 lib/deep-links.ts 中显式 allow-list。 新增 route 不会自动变成适合 push notification、referral link 或外部 URL 打开的页面。

Provider stack

RootLayoutSentry.wrap(...) 包裹,内部顺序如下:

顺序Provider/component作用
1RootErrorBoundary品牌化 runtime fallback 与 Sentry capture
2GestureHandlerRootViewKeyboardProviderSafeAreaProvidergestures、keyboard、insets 所需 native infrastructure
3QueryProviderTanStack Query cache、persistence、focus/online managers
4AuthProviderSupabase session 与 auth actions
5AnalyticsProviderPostHog capture、identify/reset、consent-aware queueing
6ConsentProviderOnboardingProvider持久化 legal 与 onboarding preferences
7EntitlementProviderPurchasesProviderSupabase entitlement read-model 与 RevenueCat purchase mechanism
8I18nProvidertlocalesetLocale
9ThemePreferenceProvider、React Navigation ThemeProviderNativeWind preference 与 navigation colors
10NotificationsProviderBiometricProviderToastProviderBottomSheetModalProviderApp services 与全局 UI surfaces

这些 gates 不是包住 navigator 的 wrapper。它们是 provider tree 内的 sibling: OnboardingGateAuthGateVersionGate 在 root Stack 前渲染; ConsentGateBiometricGate 在后面作为 overlay-style gates 渲染。

依赖注入通过 hooks 完成:useAuth()useI18n()useEntitlement()usePurchases()useToast()useNotifications()useThemePreference(), 以及各 service helper。

State conventions

State 类型负责人
Server statelib/query.tsx 与 screen hooks 中的 TanStack Query
Supabase sessionAuthProvider;native 上用 SecureStore chunking
EntitlementEntitlementProvider;读取 subscriptions table
PurchasesPurchasesProvider;RevenueCat SDK state 与 purchase actions
App preferences小型 providers,底层使用 AsyncStorage/SecureStore/localStorage
UI notificationsToastProviderNotificationsProvider、bottom sheets/dialogs

模板没有 Redux 或 Zustand。只有当未来功能真的需要全局 client state,且它不属于 server cache、auth/session state 或简单持久化偏好时,才考虑引入。

Styling

Styling 分三层:

文件作用
NativeWind classesScreens 与 componentsclassName 表达 layout、type、spacing、tokens
CSS variablesglobal.csslight/dark shadcn-style tokens 与 iOS grouped color tokens
JS tokenslib/theme.tsTHEMEIOS_COLORSgetIOSColor()NAV_THEME

可复用 variants 使用 CVA,例如 buttonVariantsbuttonTextVariantstextVariants。Platform fallback 使用常规 React Native 文件模式: store-review.web.tstracking-permissions.web.ts 在 web 上 no-op。

Code style 与 checks

模板使用 strict TypeScript、带 Tailwind class sorting 的 Prettier、Expo ESLint flat config、Husky 与 lint-staged。

pnpm typecheck
pnpm lint
pnpm format:check

当前模板没有 Jest/Vitest 配置。随附的自动检查是 TypeScript、Expo lint、formatting, 以及 RevenueCat webhook mapper 的 Deno test:

deno test supabase/functions/_shared/revenuecat.test.ts

相关页面

On this page