12k
All articles

Valibot 入门指南

介绍在 TypeScript 中使用 Valibot 验证运行时数据,涵盖 schema 定义、类型推断与可组合 pipeline 构建,并保持较小的打包体积。

OpenReplay Team
OpenReplay Team
Valibot 入门指南

TypeScript 为你提供编译时的类型安全,但它无法在运行时保护你。当数据来自表单提交、API 响应或配置文件时,TypeScript 的类型已经不复存在。这正是模式验证库填补的空白——也正是 Valibot 的闪光之处。

本指南将带你了解 Valibot 是什么、它如何工作,以及如何在实际的前端项目中开始使用它进行 TypeScript 模式验证。

核心要点

  • Valibot 是一个模块化的、TypeScript 优先的模式验证库,它在运行时验证数据并从你的模式中推断静态类型。
  • 其可摇树优化的架构使打包体积保持最小——经过 tree-shaking 后通常约为 ~1 KB——这使其成为前端应用的理想选择。
  • pipe 函数支持可组合的验证管道,提供清晰的字段级错误消息。
  • Valibot 与流行的表单库集成良好,并通过配套包支持 JSON Schema 输出,用于 API 文档。

什么是 Valibot,为什么要使用它?

Valibot 是一个模块化的、TypeScript 优先的模式验证库。它在运行时验证未知数据,并从你的模式中推断静态 TypeScript 类型,因此你的模式成为运行时安全和编译时类型的唯一真实来源。

它的突出之处在于其架构。Valibot 不是采用一个带有链式方法的大对象(Zod 采用的方法),而是由许多小型、独立的函数构建而成。打包工具可以摇树优化掉任何你不使用的内容,这使你的生产包保持最小——根据使用情况通常约为 ~1 KB。这在前端应用中是一个有意义的优势,因为打包体积直接影响加载时间。

Valibot 稳定、积极维护,并且已达到 v1+ 版本,使其成为生产环境使用的可靠选择。

定义你的第一个 Valibot 模式

在 Valibot 中定义模式看起来类似于编写 TypeScript 类型,但它在运行时执行:

import * as v from 'valibot'

const LoginSchema = v.object({
  email: v.string(),
  password: v.string(),
})

然后你可以直接从模式派生 TypeScript 类型:

type LoginData = v.InferOutput<typeof LoginSchema>
// { email: string; password: string }

无需重复。你的模式和类型自动保持同步。

解析和验证数据

Valibot 为你提供两种主要的数据验证方式。

parse 在验证失败时抛出错误:

const data = v.parse(LoginSchema, { email: 'jane@example.com', password: '12345678' })

safeParse 返回结果对象而不是抛出错误,当你想在不使用 try/catch 的情况下处理错误时很有用:

const result = v.safeParse(LoginSchema, { email: '', password: '' })

if (!result.success) {
  console.log(result.issues) // 结构化的错误详情
}

对于表单验证,safeParse 通常是更好的选择——它使错误处理保持清晰和可预测。

可组合的验证管道

Valibot 的 pipe 函数让你可以链式调用验证和转换步骤。管道始终以基础模式开始,后跟按顺序运行的操作:

const EmailSchema = v.pipe(
  v.string('Email must be a string.'),
  v.nonEmpty('Please enter your email.'),
  v.email('Invalid email format.')
)

每个操作都接收前一个操作的输出。这使得执行最小长度、特定格式或自定义约束等规则变得简单明了——所有这些都带有你可以控制的清晰的字段级错误消息。

Valibot vs Zod:关键区别

两个库都解决相同的核心问题。实际区别在于设计理念和打包影响。

特性ValibotZod
打包体积~1 KB+ (tree-shaken)~10–15 KB
可摇树优化✅ 完全支持⚠️ 部分支持
API 风格函数式、可组合方法链式调用
TypeScript 类型推断

如果你已经在使用 Zod,迁移很简单——概念映射紧密,Valibot 文档包含了为进行切换的开发者提供的指导。

生态系统和后续发展

Valibot 与流行的表单库集成良好。用于 SvelteKit 的 Superforms 库对 Valibot 提供一流支持,并且存在用于 React Hook Form 和其他工具的适配器。

对于需要 JSON Schema 输出的团队——用于 API 文档或 OpenAPI 规范——单独的 @valibot/to-json-schema 包可以处理这个需求。通过 @valibot/i18n 也支持错误消息的国际化,使 Valibot 适用于多语言应用。

结论

Valibot 为你提供运行时类型安全、清晰的 TypeScript 类型推断和最小的占用空间——而没有更重的替代方案的开销。安装它,定义一个模式,让你的验证逻辑成为构建类型的基础。

npm install valibot

从那里开始,你的模式可以随着应用的增长而增长——从简单的字符串检查到复杂的嵌套对象——而不会使你的打包体积膨胀。

常见问题

Valibot 可以验证嵌套对象和数组吗?

可以。Valibot 支持使用 v.object 嵌套在另一个 v.object 内来验证嵌套对象,使用 v.array 验证数组。你可以将这些与 pipe 结合使用,在任何深度级别添加约束,推断的 TypeScript 类型将自动反映完整的嵌套结构。

Valibot 是否适用于 Next.js 或 SvelteKit 等服务器端框架?

当然可以。Valibot 在任何 JavaScript 环境中运行,因此它可以在客户端和服务器端工作。你可以使用它在服务器操作、API 路由处理程序或中间件中验证表单提交。其小体积使其特别适合有严格打包限制的边缘运行时。

如何在 Valibot 中创建自定义验证规则?

你可以在 pipe 内使用 v.check 操作来定义自定义逻辑。它接受一个返回 true 或 false 的函数,以及一个错误消息。对于转换,v.transform 允许你修改验证后的输出。两者都可以无缝集成到任何验证管道中。

从 Zod 迁移到 Valibot 困难吗?

不是特别困难。模式、解析和类型推断等核心概念在两个库之间紧密映射。主要的转变是从方法链式调用转向使用独立函数的函数式风格。Valibot 文档提供了迁移指导,以帮助简化这一过程。

Open-source session replay

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.