使用 Expo 的本地优先架构

编辑页面

对新兴的本地优先软件运动的介绍,包括相关学习资源和工具的链接。


For the complete documentation index, see llms.txt. Use this Use this file to discover all available pages.

本指南仍在完善中。如果你有任何反馈,请在我们的 GitHub 仓库中 提交 issue

“local-first” 这个术语最早出现在研究实验室 Ink & Switch 撰写的论文 "Local-first software" 中,但其背后的理念早已存在很久。这种架构支撑着我们最喜欢的一些应用,比如 LinearSuperhumanExcalidraw,甚至还有 Apple Notes

在 local-first 软件中,“另一台电脑的可用性绝不应阻碍你工作” (via Martin Kleppmann)。当你离线时,你仍然可以直接从设备上的数据库读取和写入。你可以信任软件在离线状态下正常工作,并且你知道当你连接到互联网时,你的数据会无缝同步,并且可以在运行该应用的任何设备上使用。当你在线时,这种架构也非常适合“多人协作”应用,正如 Figma 所推广的那样。

要更深入了解 local-first 是什么以及它如何工作,请参阅下面的 其他资源

为什么使用 local-first 架构?

用户体验优势

Local-first 软件给人的感觉是很快的,因为交互不再受网络限制,你可以直接从设备上的数据库读取和写入。

你可以信任软件在离线状态下正常工作,并且你知道当你连接到互联网时,你的数据会无缝同步,并且可以在运行该应用的任何设备上使用。

local-first 软件的另一个特点是它支持协作 — 多个设备可以处理同一份数据,而且更改会在所有设备之间同步。这可以在你使用 Figma 协作设计时实时发生,也可以在你离线时在 Linear 中创建任务、随后联网后再同步时异步发生。

开发者体验优势

你不再需要为每个网络请求管理应用的各种状态 — “已加载”、“加载中”、“错误”等,以及它们对应的 UI 状态和其他逻辑。向本地数据库写入,应用会自动将更改同步到服务器。这意味着你可以专注于构建应用,而不必过多担心网络和离线状态。

你的服务器可用性仍然可能很重要,但在服务中断时,你的用户仍然可以访问应用并继续工作。你甚至可以提供一种无需经过服务器即可同步数据的机制。

构建 local-first 应用的挑战

如今可用的工具仍处于早期阶段,因此你可能会发现自己在解决一些你本以为今天所使用的工具已经能解决的问题。例如,你可能需要实现自定义同步层,或者你可能不得不弄清楚如何处理在同一份数据上操作的多个用户的权限。随着生态系统的发展,我们预计构建 local-first 应用会变得更容易。如果你还没有准备好成为早期采用者,并接受随之而来的一切,那么在开始使用 local-first 工具构建应用之前,也许最好等工具成熟一些。

用于构建 local-first 应用的工具

完整工具列表可在 "Local-first software" 社区网站 上找到。下面列出的是 Expo 团队有直接使用经验的一些较短的工具列表。

可以将 local-first 工具按以下类别来理解:持久化、状态管理和同步。如果某些工具同时处理了问题的多个方面,它们可能会属于多个类别。同步还可以进一步细分为可同步的数据结构和传输层。

Legend-State

Legend-State 是一个超快的一体化状态和同步库,它让你用更少的代码构建更快的应用。它有以下主要目标:

  • 为 React 应用提供更快的状态管理
  • 细粒度响应式,减少渲染
  • 强大的同步和持久化(内置 Supabase 支持)

它可与 Expo 和 React Native 配合使用(通过 react-native-async-storage)。这使它非常适合构建 local-first 的移动端和 Web 应用。你可以通过 Legend-State Supabase 示例 开始:

Terminal
npx create-expo-app --example with-legend-state-supabase

TinyBase

TinyBase 自称是“面向 local-first 应用的响应式数据存储”。它是一个状态管理库,可接入许多最流行的同步和持久化层,例如 YjsSQLite。对于需要持久化和同步数据的 local-first 应用来说,它是一个很好的选择。你可以通过 TinyBase 示例 开始:

Terminal
npx create-expo-app --example with-tinybase

TinyBase 可与 Expo Go 无缝配合,让你快速开发。在 Android 和 iOS 上,它使用 expo-sqlite 库来持久化数据。在 Web 上,它依赖 localStorage API。Beto Moedano 在下面的视频中演示了如何构建一个 通用 local-first 购物清单应用

观看:使用 Expo 和 TinyBase 构建一个 local-first 实时购物清单应用
观看:使用 Expo 和 TinyBase 构建一个 local-first 实时购物清单应用

使用 TinyBase、expo-sqlite 持久化以及自动同步来构建一个实时购物清单应用。

SQLite

Expo SQLite 是一个 SQLite 库,是 local-first 应用持久化的绝佳选择。你可以将 SQLite 与位于其前面的不同状态管理和同步层一起使用,例如用 y-expo-sqlite 来持久化 Yjs 文档,或者使用 TinyBase 作为状态管理层。使用 SQLite 很灵活,但你需要将它与其他工具组合,或者自己构建工具,才能得到完整的 local-first 解决方案。更多信息请参见 Expo SQLite API 参考

Yjs

Yjs 是一个 CRDT 实现,它提供可在多个客户端之间同步的数据类型。当使用 Yjs 构建应用并处理你希望能够同步的数据时,你会使用 Y.ArrayY.Map 来表示数据,而不是 ArrayObject。你可以使用像 TinyBase 这样的库在 Yjs 之上进行状态管理,而持久化则可以由多种工具来处理,从文件系统中的一个 JSON 文件到完整的数据库(例如 y-expo-sqlite),以及介于两者之间的一切。更多信息请参见 Yjs 的 GitHub 仓库

Prisma

Prisma 作为 Node.js 和 TypeScript 后端最流行的 ORM 而广为人知,现在也已在 Expo 和 React Native 早期访问版 中可用。Prisma 旨在提供完整的 local-first 解决方案,状态管理、同步和持久化都为你覆盖好了。虽然它仍处于早期阶段,Beto Moedano 已经整理出一份完整教程,讲解如何使用 Prisma 和 Expo 构建一个 local-first 的 Notion 克隆版, 在 GitHub 上查看代码

观看:使用 React Native Expo 和 Prisma 构建 local-first Notion 克隆版
观看:使用 React Native Expo 和 Prisma 构建 local-first Notion 克隆版

使用 Prisma ORM 为 Expo 构建一个 local-first 的 Notion 克隆版,涵盖状态管理、同步和持久化。

Jazz

Jazz.tools 是一个用于构建 local-first 应用的框架。它是开源的,对 Expo 提供一流支持,你可以自托管,也可以使用 Jazz Cloud 快速开始。Jazz。要了解更多,请查看 示例 或参阅 入门指南 获取详细说明。

LiveStore

LiveStore 是一个以客户端为中心的 local-first 数据层,适用于高性能应用。它对 Expo 提供一流支持,是构建 local-first 应用的绝佳选择。请参阅博客文章 LiveStore:面向 local-first 应用的基于 SQLite 的数据层

观看:如何使用 LiveStore 和 Expo 构建 local-first 原生应用
观看:如何使用 LiveStore 和 Expo 构建 local-first 原生应用

使用 LiveStore 基于 SQLite 的数据层,通过 Expo 构建高性能的 local-first 应用。

Turso

Turso 是一项构建在 SQLite 之上的现代数据库服务。它现在支持 离线同步,这使真正的 local-first 体验成为可能。你可以在本地和远程来源之间进行双向同步,并内置冲突检测来同步数据库。虽然目前还没有自动冲突解决功能,但这仍然是一个重大进步。你今天就可以将 Turso 与 expo-sqlite 一起使用。要了解更多,请阅读 Turso:离线同步公开测试版 博客文章。示例集成可查看 Notes App

观看:如何使用 Turso 和 Expo 构建 local-first Notes 应用
观看:如何使用 Turso 和 Expo 构建 local-first Notes 应用

使用 Turso 的离线同步和 expo-sqlite 进行双向数据同步,构建一个 local-first 笔记应用。

Instant

Instant 是 Firebase 的一个现代替代方案。它为你提供实时数据库,让你可以专注于构建应用的前端。要开始使用,请查看 入门指南。你也可以探索下面视频中展示的 Sketch App

观看:使用 Expo、Instant 和 Reanimated 构建一个 local-first Sketch 应用
观看:使用 Expo、Instant 和 Reanimated 构建一个 local-first Sketch 应用

使用 Instant 的实时数据库和 Reanimated 构建一个协作式草图应用,实现流畅的绘制交互。

RxDB

RxDB(Reactive Database)是一个适用于 JavaScript 应用的 local-first、NoSQL 数据库。它具有深度响应式能力,允许你订阅查询结果,这样当数据变化时,UI 会自动更新。RxDB 专注于离线优先能力,使应用即使没有互联网也能工作,并在重新联网后同步。RxDB 可通过 SQLite 存储适配器 与 Expo 配合使用,该适配器封装了 expo-sqlite。它还提供多种复制插件,可与现有后端同步,无论后端是 HTTP、GraphQL、Supabase 还是自定义后端。

其他工具

下面这份列表远非完整,但它提供了其他引起我们关注、且你可能会感兴趣去探索的工具。要获取更全面的工具列表,请参见 "Local-first software" 社区网站

其他资源