Lzh on GitHub

尽管 Valibot 的 API 初看起来与其他解决方案相似,但其实现和源代码结构却大相径庭。接下来,我们将重点介绍这些差异,它们将对你和你的用户都有益处。

模块化设计

Valibot 的 API 设计和源代码并非依赖于几个包含许多方法的大型函数,而是基于许多小而独立的函数,每个函数都只有一个任务。这种模块化设计有几个优点。

一方面,Valibot 的功能可以轻松地通过外部代码进行扩展。另一方面,它使得源代码更加健壮和安全,因为单个函数的功能以及特殊的边缘情况都可以通过单元测试更容易地进行测试。

然而,也许最大的优势是,打包工具可以利用静态导入语句来移除任何不需要的代码。因此,只有实际使用的代码才会进入生产构建。这使得我们能够用额外的功能来扩展库,而不会增加所有用户的捆绑包大小。

这可以带来很大的不同,特别是对于客户端验证而言,因为它减少了捆绑包大小,并且根据框架的不同,可以加快启动时间。

import * as v from 'valibot'; // 1.37 kB

const LoginSchema = v.object({
  email: v.pipe(
    v.string(),
    v.nonEmpty('请输入你的电子邮件。'),
    v.email('电子邮件地址格式不正确。')
  ),
  password: v.pipe(
    v.string(),
    v.nonEmpty('请输入你的密码。'),
    v.minLength(8, '你的密码必须至少有 8 个字符。')
  ),
});

与 Zod 的比较

例如,要验证一个简单的登录表单,Zod 需要 13.5 kB,而 Valibot 只需要 1.37 kB。这是捆绑包大小减少了 90%。这是因为 Zod 的函数有几个带有额外功能的方法,当它们在你的源代码中没有被执行时,当前的打包工具无法轻易移除它们。

import { object, string } from 'zod'; // 13.5 kB

const LoginSchema = object({
  email: string()
    .min(1, '请输入你的电子邮件。')
    .email('电子邮件地址格式不正确。'),
  password: string()
    .min(1, '请输入你的密码。')
    .min(8, '你的密码必须至少有 8 个字符。'),
});

你可以使用我们的 迁移指南 从 Zod 迁移到 Valibot。它提供了一个 codemod 和一个关于两个库之间差异的详细概述。

性能

对于一个模式库,必须区分启动性能和运行时性能。启动性能描述了加载和初始化库所需的时间。这个基准主要受捆绑包大小和创建模式所需的工作量影响。运行时性能描述了使用模式验证未知数据所需的时间。

由于 Valibot 的实现是为了最小化捆绑包大小和初始化工作量而优化的,因此在 TTI(可交互时间)基准测试中,几乎没有哪个库的表现比它更好。在运行时性能方面,Valibot 处于中游。粗略地说,该库的速度大约是 Zod 的两倍,但比 TypiaTypeBox 慢得多,因为我们还没有使用可以生成高度优化运行时代码的编译器,而且我们的实现不允许使用 Function 构造函数。

有关性能的更多详细信息,请参阅 Valibot 所基于的 学士论文