{"id":13905817,"url":"https://github.com/funnyzak/react-native-v2ex","last_synced_at":"2025-05-16T13:04:25.218Z","repository":{"id":39662260,"uuid":"460782045","full_name":"funnyzak/react-native-v2ex","owner":"funnyzak","description":"项目使用了 React Native 构建了一个 V2EX 移动客户端应用。目的是为了构建一个 React Native 快速开发脚手架。客户端数据完全基于 V2EX 开放 API。基于 RN 0.71.5。","archived":false,"fork":false,"pushed_at":"2025-05-09T12:31:48.000Z","size":10066,"stargazers_count":282,"open_issues_count":3,"forks_count":47,"subscribers_count":5,"default_branch":"dev","last_synced_at":"2025-05-13T09:54:34.656Z","etag":null,"topics":["android","app","clientapp","ios","react","react-native","react-native-starter","typescript","v2ex","v2ex-android","v2ex-api"],"latest_commit_sha":null,"homepage":"https://v2hub.yycc.dev","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/funnyzak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":["https://github.com/funnyzak/funnyzak/blob/storage/assets/coffee.png"]}},"created_at":"2022-02-18T09:07:48.000Z","updated_at":"2025-04-03T07:40:49.000Z","dependencies_parsed_at":"2024-01-19T11:00:26.762Z","dependency_job_id":"79177018-0442-4836-af5f-565f7ce229d7","html_url":"https://github.com/funnyzak/react-native-v2ex","commit_stats":null,"previous_names":[],"tags_count":38,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funnyzak%2Freact-native-v2ex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funnyzak%2Freact-native-v2ex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funnyzak%2Freact-native-v2ex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funnyzak%2Freact-native-v2ex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/funnyzak","download_url":"https://codeload.github.com/funnyzak/react-native-v2ex/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254535826,"owners_count":22087398,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","app","clientapp","ios","react","react-native","react-native-starter","typescript","v2ex","v2ex-android","v2ex-api"],"created_at":"2024-08-06T23:01:24.302Z","updated_at":"2025-05-16T13:04:25.171Z","avatar_url":"https://github.com/funnyzak.png","language":"TypeScript","funding_links":["https://github.com/funnyzak/funnyzak/blob/storage/assets/coffee.png"],"categories":["TypeScript"],"sub_categories":[],"readme":"# React Native V2EX\n\n[![Build Status][build-status-image]][build-status]\n[![license][license-image]][repository-url]\n[![GitHub repo size][repo-size-image]][repository-url]\n[![Release Date][rle-image]][rle-url]\n[![GitHub last commit][last-commit-image]][repository-url]\n[![tag][tag-image]][rle-url]\n\n项目使用了 React Native 构建了一个 [V2EX](https://v2ex.com) 移动客户端应用。目的是为了构建一个 React Native 快速开发脚手架。客户端数据完全基于 [V2EX](https://v2ex.com) 开放 API。基于 RN 0.71.5。\n\n`Figma 设计稿` 已经开源，可[从此 Duplicate](https://www.figma.com/community/file/1101074002447399194)。\n\n## Installation\n\n- [Android APK](https://github.com/funnyzak/react-native-v2ex/releases/latest)\n- [iOS Testflight](https://testflight.apple.com/join/7UnGRzH1)\n\n## TODO\n\n- [ ] 上架 App Store、Google Play\n- [ ] 通过 cheerio，获取更多的数据，开发交互功能\n\n## Done\n\n- [x] 升级提醒\n- [x] 升级 RN 到到 **0.71.5**\n- [x] 升级 RN 到到 **0.71.3**\n- [x] 升级 RN 到到 **0.70.6**\n- [x] 升级 RN 到到 **0.70.5**\n- [x] 升级 RN 到到 **0.70.4**\n- [x] 升级 RN 到到 **0.70.3**\n- [x] plop 模板创建\n- [x] 升级 RN 到到 **0.70.1**\n- [x] 升级 RN 到到 **0.69.4**\n- [x] 整体规划，重新设计功能架构\n- [x] 发布 Testflight 版\n- [x] 节点模块\n- [x] 规划重新设计 UI 交互\n- [x] 界面语言文案修正\n- [x] 整理项目所使用开源库\n- [x] 全新开发\n- [x] 评论列表\n- [x] 通知模块\n- [x] 收藏主题\n- [x] 关注的人\n\n## Features\n\n1. 基于 React Native 0.71.3 版本。\n2. 引入 TypeScript 强类型检查，保证维护性、可读性、稳定性。\n3. eslint 代码规范检查，prettier 代码美化、Husky 作为 git hooks 进行代码格式化、规范校验。\n4. i18n 集成，支持多国语言。实现了语言切换功能。\n5. 实现 APP 主题（浅色、深色、自动切换）切换功能。\n6. 使用 Redux，异步用 Redux Thunk，并用 Redux Persist 数据持久化。\n7. 使用 **@redux-devtools/extension** 进行 Redux 调试。\n8. 路由使用 React Navgiation，并使用了 Stack Navigator、 Bottom Tabs Navigator、 Material Top Tabs Navigator。\n9. 使用 **[react-native-splash-screen](https://github.com/crazycodeboy/react-native-splash-screen)** 控制开屏图。\n10. Toast 同时集成了 [react-native-easy-toast](https://github.com/crazycodeboy/react-native-easy-toast#api)、[react-native-toast-message](https://github.com/calintamas/react-native-toast-message)。\n11. 日期格式化使用 [dayjs](https://dayjs.gitee.io/docs/zh-CN/installation/typescript)。\n12. WebView 使用 [react-native-webview](https://github.com/react-native-webview/react-native-webview)。\n\n## Preview\n\n### iOS\n\n![preview](https://raw.githubusercontent.com/funnyzak/react-native-v2ex/dev/_docs/assets/screenshot/iOS/preview2.jpeg)\n\n### Android\n\n![preview](https://raw.githubusercontent.com/funnyzak/react-native-v2ex/dev/_docs/assets/screenshot/Android/preview2.jpeg)\n\n## Development\n\n目前在 MacOS 下开发，在 iOS 为 16+ 的 iPhone Simulator/iPhone 14、Android 9.0 的 AVD 模拟器/Mi Phone 均编译成功运行。\n\n- 安装 NodeJS(18.0+)、Yarn、[Watchman](https://reactnative.cn/docs/environment-setup)。\n- Java JDK 建议用 11（配置环境变量 **JAVE_HOME**，高于这个版本编译可能会报错）。\n- iOS 平台需要配置[CocoaPods](https://reactnative.cn/docs/environment-setup)、Xcode、iOS Simulator。\n- Android Studio、Gradle、Android SDK、[Android Home 配置](https://reactnative.cn/docs/environment-setup)、Android NDK。\n- Android 平台需要 [Android 真机](https://reactnative.cn/docs/running-on-device) 或 [Android AVD](https://developer.android.com/studio/run/managing-avds)（建议用真机）。\n\n具体可根据官网进行 React Native 开发环境和 iOS、Android 运行环境的配置。参考[这里](https://reactnative.dev/docs/environment-setup)。\n\n## Develop\n\n```bash\n\n# clone repos\n$ git clone https://github.com/funnyzak/react-native-v2ex.git \u0026\u0026 cd react-native-v2ex\n\n# deps install\n$ yarn\n\n# 依赖包额外补丁\nyarn postinstall\n\n# ios pod install\nyarn pod\n\n# start react-native-debugger（only mac）\nyarn debug\n\n# debug https://reactnative.cn/docs/debugging\nnpx react-devtools\n\n# iOS simulator start\nyarn ios\n\n# Android simulator start\nyarn android\n\n# plop generate template\nyarn p\n\n# print rn info\nnpx react-native info\n\n# upgrade rn version\nnpx react-native upgrade\n\n# iOS debug info start\nnpx react-native run-ios --verbose\n\n# iOS release build\nnpx react-native run-ios --configuration Release\n\n# iOS debug use special device\nreact-native run-ios --simulator=\"iPhone 8\"\n\n# Android debug info start\nnpx react-native run-android --verbose\n\n# Testing the release build\nnpx react-native run-android --variant=release\n\n# build android release apk\ncd android\n# aab file\n./gradlew bundleRelease\n# apk file\n./gradlew assembleRelease\n\nnpx react-native run-android --variant release\n\n```\n\n## Structure\n\n```plain\n├── src                      # 源码目录\n│   ├── App.tsx              # app根组件\n│   ├── actions              # actions\n│   ├── assets               # 静态资源\n│   ├── components           # 组件\n│   ├── config               # 配置文件\n│   ├── helper               # 应用服务类\n│   ├── hooks                # 钩子\n│   ├── i18n                 # 多语言支持\n│   ├── navigation           # 路由导航\n│   ├── reducers             # reducers\n│   ├── store                # store\n│   ├── theme                # 主题\n│   ├── types                # 类型定义\n│   ├── utils                # 工具类\n│   └── api                  # API库\n├── .editorconfig            # 编辑器配置\n├── .eslintrc.js             # eslint的配置文件\n├── .gitignore               # 配置git提交需要忽略的文件\n├── .husky                   # git钩子配置\n├── .prettierrc.js           # 代码格式化规则\n├── .watchmanconfig          # Watchman的配置文件，用于监控bug文件和文件变化，并且可以出发指定的操作\n├── __tests__                # 测试\n├── android                  # Android文件所在目录，包含AndroidStudio项目环境文件；\n├── app.json                 #\n├── babel.config.js          # Babel的配置文件\n├── global.d.ts              # ts全局声明文件\n├── index.js                 # 程序入口文件\n├── ios                      # iOS文件所在目录，包含XCode项目环境；\n├── metro.config.js\n├── package.json             # 项目基本信息（比如名称、版本、许可证等元数据）以及依赖信息（npm install安装的模块）等\n├── tsconfig.json            # typescript编译配置文件\n└── yarn.lock                # 依赖版本锁定文件\n```\n\n## Contribution\n\n如果你有任何的想法或者意见，欢迎提 Issue 或者 PR。\n\n\u003ca href=\"https://github.com/funnyzak/react-native-v2ex/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=funnyzak/react-native-v2ex\" /\u003e\n\u003c/a\u003e\n\n## Debug\n\n### Debug Tools\n\n- **[Hermes Debugger](https://reactnative.cn/docs/hermes#debugger)** is a standalone app for debugging React Native apps that use Hermes.\n- **[Flipper](https://fbflipper.com/docs/getting-started/index/)** is a desktop debugging platform for mobile developers.\n- **[react-devtools](https://www.npmjs.com/package/react-devtools)** is a standalone app for inspecting the React component hierarchy.\n- \\*\\*[React Native Debugger](https://github.com/jhen0409/react-native-debugger/blob/master/docs/getting-started.md) is a standalone app for debugging React Native apps, and includes React DevTools.\n- Google Chrome 调试，[参考](https://reactnative.cn/docs/debugging#chrome)。\n\n### Debug Menu\n\n可以通过摇晃设备或是选择 iOS 模拟器的\"Hardware\"菜单中的\"Shake Gesture\"选项来打开开发菜单。另外，如果是在 iOS 模拟器中运行，还可以按下 Command⌘ + D 快捷键，Android 模拟器对应的则是 Command⌘ + M（windows 上可能是 F1 或者 F2），或是直接在命令行中运行 adb shell input keyevent 82 来发送菜单键命令。\n\n### react-native-debugger\n\n1. 安装 **[react-native-debugger](https://github.com/jhen0409/react-native-debugger/blob/master/docs/getting-started.md)**;\n2. `yarn debug` 启动 react-native-debugger;\n3. 启动模拟器 `yarn ios`，在模拟器打开 debug remote 选项。\n\n**注意：** 使用此方式，需要禁用 `Hermes`，否则会报错。建议启用 Hermes 开关，使用 Hermes 调试。\n\n## FAQ\n\n### 配置 BugSnag\n\n1. [Create a bugsnag account](https://app.bugsnag.com/user/new).\n2. Add your project api key to [android/app/src/main/AndroidManifest.xml](android/app/src/main/AndroidManifest.xml#L25-L26):\n\n   ```xml\n      \u003cmeta-data android:name=\"com.bugsnag.android.API_KEY\"\n                 android:value=\"YOUR-API-KEY-HERE\" /\u003e\n   ```\n\n   and [ios/app/Info.plist](ios/app/Info.plist):\n\n   ```xml\n    \u003ckey\u003eBugsnagAPIKey\u003c/key\u003e\n    \u003cstring\u003eYOUR-API-KEY-HERE\u003c/string\u003e\n   ```\n\n   The API key can be found in the Bugsnag settings for your project.\n\n### Invariant Violation: Module AppRegistry is not a registered callable module\n\n```bash\nnpm cache clean --force\nwatchman watch-del-all\nrm -rf node_modules\n\n# for ios\ncd ios\npod update \u0026\u0026 pod install\ncd ..\nnpx react-native run-ios\n# for android\ncd android \u0026\u0026 ./gradlew clean\ncd ..\nnpx react-native run-android\n```\n\nReference: [https://stackoverflow.com/questions/64768328/invariant-violation-module-appregistry-is-not-a-registered-callable-module-cal](https://stackoverflow.com/questions/64768328/invariant-violation-module-appregistry-is-not-a-registered-callable-module-cal)\n\n### RCTBridge required dispatch_sync to load RNGestureHandlerModule\n\n\u003e [https://github.com/software-mansion/react-native-gesture-handler/issues/722](https://github.com/software-mansion/react-native-gesture-handler/issues/722)\n\n### xcode 编译报错\n\n```bash\n# 删除编译缓存\nrm -rf ~/Library/Developer/Xcode/DerivedData\n```\n\n### Android 编译启动注意\n\n注意 gradle 和 java sdk(java home)的版本对应，可在 ./android/gradle.properties 设置 org.gradle.java.home\n\n### 开屏图的设置\n\niOS 使用 LaunchScreen.storyboard，使用 Xcode 修改即可。\n\n### 修改 bundle name\n\n[看这里](https://stackoverflow.com/questions/37389905/change-package-name-for-android-in-react-native)。\n\n### Android 签名打包发布\n\n[看这里](https://reactnative.cn/docs/signed-apk-android/)。\n\n### Using fetch to get/post on a HTTPS web server which is using a valid and trusted but not public CA.\n\n1. Edit the android/app/src/main/AndroidManifest.xml\n2. Add the android:networkSecurityConfig=\"@xml/network_security_config\" to the \u003capplication /\u003e tag\n3. Create the folder android/app/src/main/res/xml and inside a file called network_security_config.xml\n   ```xml\n   \u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n   \u003cnetwork-security-config\u003e\n     \u003cbase-config cleartextTrafficPermitted=\"true\" /\u003e\n   \u003c/network-security-config\u003e\n   ```\n\n- [https://github.com/facebook/react-native/issues/32931](https://github.com/facebook/react-native/issues/32931)\n- [https://developer.android.com/training/articles/security-config](https://developer.android.com/training/articles/security-config)\n\n## Dependencies\n\n- eslint\n- lodash\n- redux\n- react-native-safe-area-context\n- react-native-render-html\n- react-navigation\n- react-devtools\n- @redux-devtools/extension\n- async-storage\n- react-native-gesture-handler\n- react-native-fast-image\n- react-native-reanimated\n- react-native-localize\n- react-native-device-info\n- react-native-webview\n- [react-native-skeleton-placeholder](https://github.com/chramos/react-native-skeleton-placeholder)\n- [react-native-actions-sheet](https://github.com/ammarahm-ed/react-native-actions-sheet)\n- prettier\n- [patch-package](https://github.com/ds300/patch-package)\n\n## Reference\n\n- [enviroment setup](https://reactnative.dev/docs/environment-setup) to setup react-native development environment.\n- [running on device](https://reactnative.dev/docs/running-on-device) to run app on device.\n- [debugging](https://twitter.com/i/spaces/1YqJDqDpqzAxV) to debug app.\n- [react native typescript](https://reactnative.dev/docs/typescript) to use typescript in react-native.\n- [react native cn](https://reactnative.cn/) to learn react-native.\n- [react-devtools](https://www.npmjs.com/package/react-devtools) to debug react component.\n- [fetch](https://reactnative.cn/docs/network) to use fetch in react-native.\n- [bundle tool](https://developer.android.google.cn/studio/command-line/bundletool) to generate android bundle.\n- [android build](https://reactnative.cn/docs/signed-apk-android) to generate android apk.\n- [watchman](https://facebook.github.io/watchman/docs/cli-options.html) to watch file change.\n- [EsLint](https://eslint.org/docs/user-guide/configuring/) to lint code.\n- [eslintignore-file](https://eslint.org/docs/user-guide/configuring/ignoring-code#the-eslintignore-file) to ignore lint file.\n- [TSconfig](https://www.typescriptlang.org/tsconfig/) to config typescript.\n- [npmrc](https://docs.npmjs.com/cli/v7/configuring-npm/npmrc) to config npm.\n- [gitignore](https://git-scm.com/docs/gitignore) to ignore git file.\n- [prettier](https://prettier.io/docs/en/index.html) to format code.\n- [v2ex api 2.0](https://v2ex.com/help/api) to get v2ex api.\n- [v2ex api](https://www.v2ex.com/p/7v9TEc53) to get v2ex api.\n- [v2ex token](https://www.v2ex.com/settings/tokens) to get v2ex token.\n- [react native sample](https://github.com/facebook/react-native) to learn react-native.\n- [react native typescript sample](https://github.com/react-native-community/react-native-template-typescript) to learn react-native typescript.\n- [React Native Upgrade Helper](https://react-native-community.github.io/upgrade-helper/) to upgrade react-native.\n- [Easy App Icon](https://easyappicon.com/) to generate app icon.\n- [App Image Sets](https://appicon.co/#image-sets) to generate app icon and image set.\n\n## License\n\nApache-2.0 License © 2021 [funnyzak](https://github.com/funnyzak)\n\n\u003c!-- [![action][ci-image]][ci-url] --\u003e\n\u003c!-- [![js-standard-style](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/feross/standard) --\u003e\n\u003c!-- [![GitHub commit activity][commit-activity-image]][repository-url] --\u003e\n\u003c!-- [![Sourcegraph][sg-image]][sg-url] --\u003e\n\n[repo-size-image]: https://img.shields.io/github/repo-size/funnyzak/react-native-v2ex?style=flat-square\u0026logo=github\u0026logoColor=white\u0026label=size\n[down-latest-image]: https://img.shields.io/github/downloads/funnyzak/react-native-v2ex/latest/total.svg\n[down-total-image]: https://img.shields.io/github/downloads/funnyzak/react-native-v2ex/total.svg\n[commit-activity-image]: https://img.shields.io/github/commit-activity/m/funnyzak/react-native-v2ex?style=flat-square\n[last-commit-image]: https://img.shields.io/github/last-commit/funnyzak/react-native-v2ex?style=flat-square\n[license-image]: https://img.shields.io/github/license/funnyzak/react-native-v2ex.svg?style=flat-square\n[repository-url]: https://github.com/funnyzak/react-native-v2ex\n[rle-url]: https://github.com/funnyzak/react-native-v2ex/releases/latest\n[rle-all-url]: https://github.com/funnyzak/react-native-v2ex/releases\n[ci-image]: https://img.shields.io/github/workflow/status/funnyzak/react-native-v2ex/react-native-android-build-apk\n[ci-url]: https://github.com/funnyzak/react-native-v2ex/actions\n[rle-image]: https://img.shields.io/github/release-date/funnyzak/react-native-v2ex.svg?style=flat-square\u0026label=release\n[sg-image]: https://img.shields.io/badge/view%20on-Sourcegraph-brightgreen.svg?style=flat-square\n[sg-url]: https://sourcegraph.com/github.com/funnyzak/react-native-v2ex\n[build-status-image]: https://github.com/funnyzak/react-native-v2ex/actions/workflows/release.yml/badge.svg\n[build-status]: https://github.com/funnyzak/react-native-v2ex/actions\n[tag-image]: https://img.shields.io/github/tag/funnyzak/react-native-v2ex.svg\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunnyzak%2Freact-native-v2ex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffunnyzak%2Freact-native-v2ex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunnyzak%2Freact-native-v2ex/lists"}