news 2026/9/25 3:41:31

React Native MMKV 示例工程实战指南:从 Metro 启动、双端构建到 Harness 跨平台测试

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
React Native MMKV 示例工程实战指南:从 Metro 启动、双端构建到 Harness 跨平台测试

【免费下载链接】react-native-mmkv

⚡️ The fastest key/value storage for React Native. ~30x faster than AsyncStorage!

项目地址:https://gitcode.com/gh_mirrors/re/react-native-mmkv
点击查看免费下载

本文以 example/README.md 中的「Getting Started」流程为核心,讲解如何在本仓库中把example/示例工程完整跑起来:启动 Metro、构建 Android/iOS 应用、通过 Fast Refresh 修改并验证 UI,并额外覆盖仓库实际存在的 Web 运行脚本与 react-native-harness 跨平台测试体系。读完后你能够独立操作该示例工程的开发、调试、构建与测试全流程。

一、示例工程定位与目录结构

example/是一个使用@react-native-community/cli引导的标准 React Native 应用(应用名MmkvExample,见 app.json),通过 monorepo 工作区内的react-native-mmkv: "*"依赖直接引用本仓库的库包(见 example/package.json)。其目录职责如下:

  • example/src/App.tsx:演示应用入口组件,直接使用createMMKV与 MMKV Hooks;
  • example/index.js/example/index.web.js:原生与 Web 两套注册入口(均通过AppRegistry.registerComponent注册MmkvExample);
  • example/android/、example/ios/:双端原生壳工程(Android 为com.mrousavy.mmkv.example,iOS 目标名为MmkvExample);
  • example/scripts/web-dev.mjs、example/scripts/web-proxy.mjs:仓库自建的 Web 开发服务器与同源代理;
  • example/__tests__/MMKV.harness.ts:基于 react-native-harness 的真实设备端到端测试;
  • example/rn-harness.config.mjs:Harness 多平台运行器配置。

example/package.json 中定义的 npm scripts 是本工程一切操作命令的来源,完整对照如下:

脚本实际命令用途
startreact-native start启动 Metro(对应文档 Step 1)
androidreact-native run-android构建并安装 Android 应用(Step 2)
iosreact-native run-ios构建并运行 iOS 应用(Step 2)
podsbundle install && cd ios && bundle exec pod install一步完成 CocoaPods 安装与安装
testjest运行 Jest(Harness preset)
test:harnessreact-native-harness在真实模拟器/浏览器上运行 harness 测试
web:devnode ./scripts/web-dev.mjs启动 Web 开发服务器
web:proxynode ./scripts/web-proxy.mjsHarness Web 测试的同源代理
build:android-releasecd android && ./gradlew assembleRelease --no-daemon构建 Android 发布包
lint/lint-cieslint + prettier代码风格检查(CI 模式零容忍警告)

运行环境前置条件:example/package.json 的engines字段要求node >= 20.19.4;依赖 React Native 0.85.3、React 19.2.6 与react-native-nitro-modules0.35.9(MMKV 4.x 基于 Nitro Modules 而非传统 Bridge)。开始之前请先按 React Native 官方「Set Up Your Environment」指南配置好 Xcode、Android SDK 等基础环境(原文档中的外部链接在此不再展开,以官方文档为准)。

二、Step 1:启动 Metro

在示例工程根目录执行:

# 使用 npm npm start # 或使用 Yarn yarn start

该命令即react-native start,启动 JavaScript 构建工具 Metro。示例工程的 Metro 配置并非默认值,example/metro.config.js 做了三处关键定制,理解它们是排查加载问题的前提:

  1. watchFolders: [workspaceRoot]:监视范围扩大到 monorepo 根目录,使 Metro 能感知packages/react-native-mmkv内源码的变化——这也是示例工程可以直接依赖本地库包而非 npm 版本的原因;
  2. resolver.platforms: ['web', 'ios', 'android', 'native']:显式声明平台解析顺序,让同一个依赖在四端都能正确解析到对应实现(例如*.web.ts文件);
  3. 单例重定向(SINGLETONS):重写resolver.resolveRequest,将react、react-native、react-dom、react-native-web强制解析到工作区根目录的node_modules,避免 monorepo 中出现双份 React 实例;并且当 platform 为web时,把裸的react-native入口重定向到react-native-web。
// example/metro.config.js 中的单例解析核心逻辑 const SINGLETONS = ['react', 'react-native', 'react-dom', 'react-native-web']; // platform === 'web' 且模块为 react-native 根入口时,重定向到 react-native-web

三、Step 2:构建并运行应用

在 Metro 保持运行的前提下,另开一个终端执行以下命令(原文档 Step 2 的双端流程完整保留)。

Android

# 使用 npm npm run android # 或使用 Yarn yarn android

该脚本映射到react-native run-android,会编译 example/android 下的 Gradle 工程并推送到已连接的设备或模拟器。原生壳工程的MainActivity.kt/MainApplication.kt位于example/android/app/src/main/java/com/mrousavy/mmkv/example/。若要产出发布包,可改用仓库提供的npm run build:android-release。

iOS

iOS 需要额外处理 CocoaPods 依赖。原文档说明:首次 clone 后需先安装 CocoaPods 本身,之后每次更新原生依赖时都要重新安装:

# 首次:安装 Ruby bundler 依赖(即 CocoaPods 本身) bundle install # 之后:每次更新原生依赖时执行 bundle exec pod install

仓库也封装了等价的npm run pods(即bundle install && cd ios && bundle exec pod install)。随后执行:

# 使用 npm npm run ios # 或使用 Yarn yarn ios

从 example/ios/Podfile 可以看到这是标准 RN 0.85 Podfile:目标MmkvExample内调用use_native_modules!与use_react_native!,由 Nitro Modules 的自动链接机制(见 packages/react-native-mmkv/ios 与NitroMmkv.podspec)把库的原生实现链入。配置正确后,应能在 Android 模拟器、iOS 模拟器或真机上看到运行中的应用;也可以绕过 CLI,直接用 Android Studio 或 Xcode 打开example/android、example/ios构建。

附:Web 端运行(仓库扩展能力)

裸 React Native 并不自带 Web 开发模式,仓库为此在 example/scripts/ 下提供了两套脚本:

  • npm run web:dev(web-dev.mjs):自动以bunx react-native start --port 8081拉起 Metro,轮询/status等待就绪(最长 90 秒),然后在本地 3000 端口提供一个同源的 HTML 壳页面,通过/index.bundle?platform=web加载由 index.web.js 注册的MmkvExample。可用环境变量PORT(默认 3000)、METRO_PORT(默认 8081)、METRO_URL(复用已运行的 Metro)调整;
  • npm run web:proxy(web-proxy.mjs):当 Harness 自行托管 Metro 时,用HARNESS_METRO_URL(默认http://localhost:8081)与PROXY_PORT(默认 3000)在浏览器与 Harness 的 Metro 之间做同源代理,使 HTML、bundle 与/__harnessWebSocket 都从单一源加载,规避浏览器跨域限制。

四、Step 3:修改应用并验证热更新

示例应用的主界面在 example/src/App.tsx,它本身就是一份 MMKV 4.x API 的最小可用示例:

const storage = createMMKV(); // 模块级创建默认实例 export default function App() { const keys = useMMKVKeys(storage); // 响应式获取全部 key const [example, setExample] = useMMKVString('nitrooooo'); // 响应式读写字符串 useMMKVListener((k) => { console.log(`${k} changed! New size: ${storage.byteSize}`); // 监听任意实例的值变化 }); // Save 按钮:storage.set(key, text);Read 按钮:storage.getString(key) }

按原文档 Step 3 操作:在编辑器中打开App.tsx做修改,保存后应用会通过 Fast Refresh 自动更新界面;需要强制重置应用状态时执行全量重载:

  • Android:按两次R键,或通过开发者菜单(Windows/Linux 按Ctrl + M,macOS 按Cmd + M)选择Reload;
  • iOS:在 iOS 模拟器中按R键。

App.tsx中还演示了深色模式适配(useColorScheme+createDynamicStyles)与useMMKVString每秒翻转值的定时器——观察模拟器上nitrooooo键每秒的字符串写入,即可直观验证useMMKVListener打印的byteSize变化。

五、测试体系:Jest 与 react-native-harness

原文档未涉及、但仓库实际内置了完整的测试链路,且与「修改应用后验证行为」直接相关。

Jest 配置 只有一个 project:displayName为react-native-harness,preset 为react-native-harness,testMatch匹配__tests__/下所有.test/.spec/.harness文件。npm test即按此运行。

真正有价值的是 MMKV.harness.ts(约 1400 行):它不是 mock 单测,而是在真实的 Android 模拟器、iOS 模拟器与 Chromium 浏览器上执行完整 API 的端到端断言,覆盖范围包括:

  • 基础 CRUD:string/number/boolean 存取、contains、getAllKeys、remove、clearAll、类型混读(原始字节解释)、超长字符串、1000 键批量写入;
  • 实例管理:多实例隔离、同配置复用同一实例、importAllFrom跨实例导入、length/byteSize属性、trim;
  • 加密与安全:AES-128/AES-256 创建、encrypt/decrypt重加密、密钥长度边界(16/32 字节)、密文与明文实例隔离;
  • 只读模式:readOnly: true时set抛错、remove/clearAll静默失败;
  • compareBeforeSet:同值重复写入不增加byteSize;
  • 多进程模式(mode: 'multi-process')下的读写与加密;
  • 监听器:addOnValueChangedListener在 set/update/remove/clearAll 时的触发次数、多监听器并存、remove()幂等;
  • 实例级 API:deleteMMKV返回值、existsMMKV存在性判断;
  • 错误与边界:空 key 抛错、极端数值(MAX_SAFE_INTEGER、Infinity、NaN)、Unicode/emoji key、100 并发操作。

其中 Web 平台不适用的用例(ArrayBuffer 往返、加密、只读、多进程、existsMMKV/deleteMMKV语义差异)统一通过skipOnWeb(reason)跳过并在控制台打印原因。

运行器配置见 rn-harness.config.mjs:

entryPoint: './index.js', appRegistryComponentName: 'MmkvExample', runners: [ androidPlatform({ device: androidEmulator('Pixel_8_API_35', {...}), bundleId: 'com.mrousavy.mmkv.example' }), applePlatform({ device: appleSimulator('iPhone 16 Pro', '18.6'), bundleId: 'com.mrousavy.mmkv.example' }), webPlatform({ browser: chromium('http://localhost:8081') }), ], defaultRunner: 'android', bridgeTimeout: 120000,

设备均可用环境变量覆盖:HARNESS_ANDROID_AVD(默认Pixel_8_API_35)、HARNESS_ANDROID_API_LEVEL(默认 35)、HARNESS_IOS_DEVICE(默认iPhone 16 Pro)、HARNESS_IOS_VERSION(默认 18.6)、HARNESS_WEB_URL(默认http://localhost:8081)。执行npm run test:harness即可默认在 Android 模拟器上运行;Web runner 配合npm run web:proxy使用。另注意 babel.config.js 同时加载了react-native-harness/babel-preset,这是 harness 能够插桩被测应用的前提。

六、故障排查

  • 双端构建失败或环境报错:按原文档指引,优先对照 React Native 官方 Troubleshooting 文档排查(Xcode 版本、Gradle/AGP 版本、JDK 版本是 RN 0.85 常见冲突点);
  • JS 改动不生效:确认 Metro 的watchFolders是否覆盖 monorepo 根目录,即本地库包源码修改是否被监视(见 example/metro.config.js);
  • React 双实例告警:确认SINGLETONS重定向未被移除,且node_modules解析指向工作区根目录;
  • iOS 依赖问题:更新原生依赖后忘记执行bundle exec pod install(或npm run pods)是最高频原因;
  • Web 页面白屏:确认 HTML 壳加载的 bundle 路径为/index.bundle?platform=web,且 Metro 已按platforms配置接受web平台解析;若使用 Harness,检查PROXY_PORT/HARNESS_METRO_URL是否指向实际在跑的 Metro;
  • Harness 超时:bridgeTimeout默认 120000ms,模拟器首次冷启动较慢时可检查defaultRunner指向的设备是否已启动。

七、延伸阅读路径

  • 库本身的 API 与 Hook 文档:packages/react-native-mmkv/src/index.ts、docs/HOOKS.md、docs/LISTENERS.md;
  • 原生绑定与 Nitro Modules 生成物:packages/react-native-mmkv/nitrogen、packages/react-native-mmkv/cpp/HybridMMKV.cpp;
  • 版本迁移参考:docs/V4_UPGRADE_GUIDE.md、docs/MIGRATE_FROM_ASYNC_STORAGE.md。

以上所有命令均以在example/目录下执行为前提;web:dev脚本内部使用bunx拉起 Metro,如未安装 Bun 可先手动npm start再通过METRO_URL环境变量把脚本指向已有 Metro 实例。

【免费下载链接】react-native-mmkv

⚡️ The fastest key/value storage for React Native. ~30x faster than AsyncStorage!

项目地址:https://gitcode.com/gh_mirrors/re/react-native-mmkv
点击查看免费下载
上一篇:Folly result 错误溯源机制深入解析:epitaph(墓志铭)注解的用法与原理
下一篇:从设计到部署:dev-resources全流程开发工具链详解

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/25 3:40:48

ESP32驱动墨水屏实战:GxEPD2库入门与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/25 3:38:59

SpringBoot+Vue二手交易系统:从业务建模到部署上线全解析

最近我把一套基于 SpringBoot Vue 的二手物品交易管理系统重新翻了出来,项目代号 bootpf,代码包名统一叫 com.bootpf。这套系统从用户注册、商品发布、浏览搜索、购物车、下订单,到后台的商品审核、用户管理和数据统计,基本把二手…

作者头像 李华
网站建设 2026/9/25 3:37:33

STM32入门第0集:从芯片认知到环境搭建,新手避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/25 3:37:08

华为昇腾推理引擎开源:边缘AI部署与性能优化实战

1. 昇腾推理引擎开源这件事,到底在解决什么问题第一次在昇腾社区看到推理引擎开源的消息时,我正蹲在一个边缘计算项目上折腾模型部署。当时手里的活儿是把一个视觉检测模型塞进一台功耗受限的工控机里,芯片用的是昇腾310P3。那会儿最头疼的不…

作者头像 李华