资讯详情

资讯详情

Next.js 集成 Turso 实战指南:用 libSQL 实现本地 SQLite 与云端数据库的平滑切换

Next.js 集成 Turso 实战指南用 libSQL 实现本地 SQLite 与云端数据库的平滑切换【免费下载链接】next.jsThe React Framework项目地址: https://gitcode.com/GitHub_Trending/next/next.js导读本指南基于 examples/with-turso 官方示例系统讲解如何在 Next.js 应用中接入 Turso——一个基于 libSQLSQLite 的开源贡献分支构建、兼容 SQLite 协议的数据库服务。通过该示例你可以掌握一套本地开发用 SQLite 文件、云端部署自动切换到 Turso 托管数据库的开发模式并学会使用 App Router 的 Server Components 与 Server Actions 在 React 服务端直接执行 SQL 读写。读完本文你将能够独立搭建一个使用 Next.js Turso 的全栈应用并完成从本地到 Vercel 的完整部署。为什么选择 TursoSQLite 生态的云端延伸示例 README 开篇给出了 Turso 的核心定位Turso 是一个与 SQLite 兼容的数据库构建在 libSQL 之上。libSQL 是 SQLite 的开放贡献Open Contribution分支它让组织可以横向扩展到每组织数十万级数据库并支持将数据库复制到任何位置包括你自己的服务器从而实现微秒级延迟的数据访问。这套架构带来的实际好处是明显的对开发者而言本地与云端使用同一套 SQLite 语法与驱动不需要在开发环境和生产环境之间维护两套 ORM 或两种 SQL 方言对应用而言Turso 的边缘复制能力让全球用户的读取请求可以就近命中副本而 Next.js 的边缘运行时、Server Components 等特性恰好与之互补——数据库离计算近查询延迟自然更低。示例的功能构成与目录结构with-turso示例实现了一个极简的 Todo 应用其声明的能力包含三点见 README 的 Features 一节本地使用 SQLitedev.db无需任何外部服务即可跑通App Router页面渲染完全基于 Next.js 的目录约定Server Actions数据写入通过服务端动作函数完成。仓库中examples/with-turso的目录结构如下examples/with-turso/ ├── app/ │ ├── actions.ts # Server ActionsaddTodo / removeTodo │ ├── form.tsx # 客户端表单组件 │ ├── layout.tsx # 根布局与 Metadata │ ├── page.tsx # 首页Server Component │ ├── todo-list.tsx # 异步 Server Component查表、建表、渲染列表 │ ├── todo.tsx # 单条 Todo 项客户端组件绑定删除动作 │ └── globals.css ├── lib/ │ └── turso.ts # libSQL 客户端单例负责环境切换 ├── next.config.mjs # 空配置无需特殊配置项 ├── package.json ├── tsconfig.json # 含 /*: [./*] 路径别名 └── README.md整体数据流非常清晰Server Component 直接通过 libSQL 客户端读库渲染页面用户提交由 Server Action 写库并调用revalidatePath触发重新渲染。下面逐步拆解每个环节的实现。核心抽象lib/turso.ts 中的环境切换整个示例最精巧的设计集中在 lib/turso.ts全文仅 6 行import { createClient } from libsql/client; export const db createClient({ url: process.env.TURSO_DB_URL ? process.env.TURSO_DB_URL : file:./dev.db, authToken: process.env.TURSO_DB_TOKEN, });这里揭示了 TursolibSQL客户端的两大核心概念url必填数据库连接地址。本地开发时未设置TURSO_DB_URL回退到file:./dev.db——libSQL 以文件型 SQLite 连接本地数据库文件云端部署时设置TURSO_DB_URL它指向 Turso 提供的远端数据库地址格式通常为libsql://database-name-org.turso.io。authToken可选访问远端数据库所需的认证令牌。本地文件数据库不需要令牌因此在未配置时为undefinedTurso 云上则必须通过TURSO_DB_TOKEN注入。这正是同一份代码本地跑 SQLite、线上跑 Turso的关键客户端根据环境变量自动切换数据源业务代码完全无感知。依赖方面示例在 package.json 中声明了libsql/client版本0.4.0即官方 JavaScript/TypeScript 驱动其createClient是连接到文件型或远程型数据库的统一入口。数据库初始化与查询Server Component 直接读库app/todo-list.tsx 是一个async的 Server Component它演示了如何在 React 组件内直接执行 SQLimport { type TodoItem, Todo } from ./todo; import { db } from /lib/turso; // The code below can be removed in production apps // Useful for getting started locally with SQLite async function findOrCreateTodosTable() { const result await db.execute( SELECT name FROM sqlite_master WHERE typetable AND nametodos, ); if (!result || result?.rows?.length 0) { await db.execute( CREATE TABLE todos(id INTEGER PRIMARY KEY AUTOINCREMENT, description TEXT NOT NULL), ); } } export async function TodoList() { await findOrCreateTodosTable(); const result await db.execute(SELECT * FROM todos); const rows result.rows as unknown as TodoItem[]; if (!result || result?.rows?.length 0) return null; return rows.map((row, index) ( Todo key{index} item{{ id: row.id, description: row.description }} / )); }需要关注的两个要点幂等的建表逻辑findOrCreateTodosTable先通过sqlite_master系统表查询todos是否已存在不存在才执行建表语句。这就是 README 所述示例会自动使用dev.db文件创建todos表的底层实现。由于这段代码在每次渲染时都会执行 SQLREADME 注释也明确指出它仅适用于本地起步生产环境应移除——生产环境应该在部署前由迁移工具或手动执行建表 SQL准备好表结构。建表语句与部署章节的表结构完全一致CREATE TABLE todos(id INTEGER PRIMARY KEY AUTOINCREMENT, description TEXT NOT NULL)这也意味着本地建好的表结构与云端的建表 DDL 必须保持对应本地产生的数据可以通过 Turso 的导入能力上云。写入路径Server Actions 与 revalidatePathapp/actions.ts 用use server指令声明了两个服务端动作构成所有写操作的入口use server; import { revalidatePath } from next/cache; import { db } from /lib/turso; export const addTodo async (formData: FormData) { await db.execute({ sql: INSERT INTO todos (description) VALUES (?), args: [formData.get(description) as string], }); revalidatePath(/); }; export const removeTodo async (formData: FormData) { await db.execute({ sql: DELETE FROM todos WHERE id ?, args: [formData.get(id) as string], }); revalidatePath(/); };这段代码展示了 Server Actions 与 libSQL 配合的规范写法参数化查询db.execute接受{ sql, args }对象值通过?占位符与args数组绑定避免字符串拼接带来的 SQL 注入风险revalidatePath(/)触发数据刷新写入完成后调用 Next.js 的revalidatePath使首页的缓存失效并重新渲染TodoList会重新执行查询页面上立即反映新增/删除的结果。这是提交表单后数据为何会自动更新的机制答案。交互层客户端表单与单条删除写操作虽然发生在服务端但交互仍然由客户端组件承接分别对应 form.tsx 与 todo.tsx。**新增表单form.tsx**是一个use client组件要点有三使用 React 19 风格/兼容的form action{...}直接把addTodoServer Action 作为表单动作formRef.current?.reset()在提交后清空输入框实现增完即清的交互通过useFormStatus的pending状态以sr-only隐藏按钮的禁用态保证无 JS 降级场景下表单依然可用该按钮仅用于无障碍/进度语义样式上对用户隐藏。form action{async (formData) { await addTodo(formData); formRef.current?.reset(); }} ref{formRef} input iddescription namedescription required ... / Submit / /form注意表单输入框的namedescription它与 actions.ts 中formData.get(description)一一对应。**删除按钮todo.tsx**同样用表单承载 Server Action每个Todo项渲染一个form action{removeTodo}内部按钮的nameid与value{item.id}会把行 id 作为表单数据提交从而命中DELETE ... WHERE id ?。这与addTodo不同——removeTodo并不依赖FormData做类型转换而是直接读取name命名的字段。最后page.tsx 作为服务端页面把TodoList与Form组合渲染而 layout.tsx 设置页面元信息title: Next.js Turso、description: Next.js Server Actions Demo Turso。本地运行从零到可访问README 给出了两条本地启动路径下面完整整理。方式一直接以模板创建新项目使用脚手架工具从本仓库的with-turso示例创建一个全新的 Next 应用以下三种包管理器任选其一npx create-next-app --example with-turso with-turso-appyarn create next-app --example with-turso with-turso-apppnpm create next-app --example with-turso with-turso-app该命令会把examples/with-turso中的全部文件复制到新建的with-turso-app目录。方式二基于本仓库源码直接运行如果你已克隆本仓库也可以直接进入examples/with-turso目录安装依赖并启动。安装与启动命令同样覆盖三种包管理器npm install npm run dev # or yarn install yarn dev # or pnpm install pnpm dev需要说明的是示例 package.json 的dev脚本实际为next dev --turbopack即默认使用 Turbopack 作为开发打包器build与start分别对应生产构建与启动。由于开发阶段不设置TURSO_DB_URLlib/turso.ts 会自动回退到file:./dev.db首次渲染TodoList时便会在仓库内生成dev.db文件并创建todos表。启动成功后访问 http://localhost:3000即可在页面上添加、删除 Todo所有数据持久化在本地 SQLite 文件中刷新不丢失。部署到 Vercel完整六步走本地运行验证通过后README 的 Deploy to Vercel 一节 给出了把同一应用切换到 Turso 云端数据库并部署的完整流程。第 1 步注册并登录 Turso先安装 Turso CLI# macOS brew install tursodatabase/tap/turso# Windows (WSL) 与 Linux 使用官方安装脚本 # curl -sSfL https://get.tur.so/install.sh | bash随后在 Turso 平台上使用 GitHub 账号完成注册登录Turso 使用 GitHub OAuth 作为默认登录方式。第 2 步创建数据库在命令行创建你的第一个数据库其中[database-name]替换为你自定义的库名turso db create [database-name]第 3 步创建表进入该数据库的交互式 shell执行与本地代码一致的表结构 DDLturso db shell database-nameCREATE TABLE todos(id INTEGER PRIMARY KEY AUTOINCREMENT, description TEXT NOT NULL)注意表结构与 todo-list.tsx 内自动建表语句保持一致。因为生产部署后 Server Component 内的findOrCreateTodosTable不再负责建表README 建议移除云端表需要在这里预先手动创建。第 4 步获取数据库 URL部署时需要把数据库地址注入到环境变量TURSO_DB_URLturso db show database-name --url该命令会输出形如libsql://database-name-organization.turso.io的远程地址。它对应 lib/turso.ts 中url的分支逻辑环境变量存在时即使用该远端地址覆盖本地的file:./dev.db回退值。第 5 步创建访问令牌为数据库创建一个认证令牌注入环境变量TURSO_DB_TOKENturso db tokens create database-name该令牌对应客户端初始化中的authToken: process.env.TURSO_DB_TOKEN。url与authToken必须配套使用缺少令牌会导致远端认证失败。第 6 步一键部署到 Vercel示例 README 提供了带预置环境变量的 Vercel 部署入口Deploy with Vercel按钮其克隆链接已预先声明envTURSO_DB_URL,TURSO_DB_TOKEN两个变量。选择一键部署时按提示分别粘贴第 4、5 步拿到的值即可。更通用的做法是在 Vercel 项目设置的Environment Variables面板手动添加TURSO_DB_URL与TURSO_DB_TOKEN两个变量再执行常规的 Git 导入或vercelCLI 部署。部署完成后线上实例将直连 Turso 云端数据库实现同一套代码本地 SQLite、线上 Turso的完整闭环。关键技术点小结关注点实现位置要点说明客户端初始化与环境切换lib/turso.tscreateClient依据TURSO_DB_URL是否存在在file:./dev.db与远程libsql://地址间切换TURSO_DB_TOKEN用于远端认证读路径app/todo-list.tsxServer Component 内直接await db.execute(...)自带幂等建表逻辑仅限本地起步写路径app/actions.tsuse server动作函数执行参数化 INSERT/DELETE随后revalidatePath(/)刷新页面表单交互app/form.tsx、app/todo.tsxform action{ServerAction}绑定服务端动作隐藏按钮配合useFormStatus本地数据落盘file:./dev.db未配置环境变量时由 libSQL 以文件数据库模式自动生成整体来看with-turso示例为边缘数据库 全栈 React 框架提供了最小可运行的参考实现把数据库访问收敛在单一lib/turso.ts模块中业务层只面对一致的db.executeAPI这让本地迭代与云端发布之间的切换成本几乎为零也恰好契合 Next.js Server Components 的服务端数据获取模型。【免费下载链接】next.jsThe React Framework项目地址: https://gitcode.com/GitHub_Trending/next/next.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →