30 秒看懂
T3 Stack 创建者审视 2022 年各组件与默认设置的局限,涵盖部署、认证、渲染和 TypeScript 性能,并说明为何技术栈应适合项目需求。
- 1边缘与启动2022 年的 Prisma 设置有包体积与边缘限制;后续版本已有变化。
- 2tRPC 的边界客户端和服务端紧密协作时,共享 TypeScript 类型最有优势。
- 3认证设置通用认证库仍需要认真配置。
- 4框架约定路由和数据加载约定以部分灵活性换取便利。
- 5模块化可替换组件更多,也意味着需要作出更多决策。
- 6初始 HTML所描述的默认方案在客户端加载应用数据。
- 7类型与验证编译期类型不会验证所有运行时数据。
要点建议
- 2022 年的 Prisma 设置有包体积与边缘限制;后续版本已有变化。
- 客户端和服务端紧密协作时,共享 TypeScript 类型最有优势。
- 通用认证库仍需要认真配置。
- 路由和数据加载约定以部分灵活性换取便利。
- 可替换组件更多,也意味着需要作出更多决策。
- 所描述的默认方案在客户端加载应用数据。
- 编译期类型不会验证所有运行时数据。
按章节阅读整理后的全文
各项技术
Prisma、tRPC、Tailwind 与认证。
我创建了 T3 Stack,也在使用这些技术,但这场 2022 年的讨论专门关注它们的弱点。一个技术栈即使适合高效构建全栈应用,也可能不适合某些项目。
我讨论的组件包括 Prisma、tRPC、Tailwind、NextAuth、Next.js、React 和 Vercel。它们的能力自录制以来已发生变化,具体限制应视为历史背景,做决定前需查看当前文档。
在我当时使用的版本中,Prisma 的 Rust 二进制和包体积给边缘部署及无服务器冷启动带来了困难。常驻服务器可以只初始化一次客户端,短暂运行的环境则更容易暴露启动成本。
Prisma 在安装期间生成类型,我觉得这种做法较为固定,有时也不够顺手。生成类型有助于数据库类型安全,但构建步骤及其与依赖的交互也增加了开发者需要考虑的问题。
我也提醒,大型或嵌套查询可能遇到性能问题。这些观察取决于工作负载,并非普遍适用的基准。[Prisma 后来的边缘部署文档](https://www.prisma.io/docs/orm/v6/prisma-client/deployment/edge)介绍了不随包发布 Rust 查询引擎二进制的配置。
当客户端和服务端都使用 TypeScript、能够共享类型时,tRPC 尤其有吸引力。我认为它不太适合直接作为第三方 API 或其他语言客户端的主要接口契约。
大量过程也可能给 TypeScript 工具带来压力。我观察到 tRPC v10 有改进,但建议项目增长时关注编辑器和类型检查性能,而不是假定可以无限扩展。
2022 年,不同客户端集成的成熟度并不一致,React 绑定尤其成熟。[tRPC 文档](https://trpc.io/docs/)介绍了其 TypeScript 类型推导方式;需要其他框架时应查看当前客户端支持。
Tailwind 会扫描文件以寻找工具类,开发者也需要足够了解 CSS,才能用好这些类。生成的样式表整体可能很小,但不一定对每个页面都达到最小。
我认为 NextAuth 很有价值,但某些方面也令人沮丧:它覆盖的范围与配置选择可能让看似简单的场景需要额外工作。2022 年我尤其提到用户 ID、类型覆盖和令牌刷新。
我还遇到边缘运行问题,以及 React 之外支持程度不一致的问题。这些描述的是我对当时版本的经验;认证与部署细节应以当前所选版本为准。
框架与部署
2022 年的 Next.js、React 和 Vercel。
Next.js 对路由、构建工具和 React 作了具体选择。这些约定可能提高效率,但也减少了替换单个组件的自由;对于大部分内容静态的页面,发送的 JavaScript 可能超过实际需要。
我批评了 2022 年设置中的数据加载和页面属性模式,包括服务端渲染与路由参数的棘手之处。这些评论针对我当时使用的 Pages Router 时代代码,并不适用于所有后来的 Next.js 版本。
对于大部分内容静态的网站,React 的客户端机制可能引入页面不需要的工作。对于交互式应用,这些成本可能合理;选择取决于渲染内容与用户体验。
React 有意把路由、数据和样式等许多选择留给周边生态。我重视这种灵活性,但追求统一约定的团队可能觉得广阔的选择空间更难管理。
我称赞 React 文档工作,同时指出当时新版文档尚未本地化。对主要不使用英语的开发者来说,文档可获得性与翻译会影响采用。
对于我使用的 Vercel 部署模式,我指出无状态函数、冷启动以及需要单独规划存储等问题。区域选项、边缘运行行为和价格也是 2022 年的决策因素;当前套餐与产品可能不同。
我喜欢部署与 CDN 集成的便利,但提醒图像优化和函数调用的成本增长方式可能不同。应根据工作负载和服务商当前条款估算成本。
整个技术栈的权衡
模块化、测试与渲染。
技术栈的模块化既是好处也是责任。团队可以替换组件并选择不同架构,但灵活性也为难以维护的决策留下空间。
我见过这个技术栈被用于静态博客、直接服务器部署和分布式数据库。这些例子体现了不同需求;对于简单博客,我通常更倾向于为主要静态内容设计的方案。
需要学习的组件不少:React、TypeScript、Next.js、tRPC 及其使用的查询库,再加上团队选择的数据库和认证方案。即使每个组件的职责清楚,这个清单仍可能令人望而生畏。
当时 Create T3 App 没有规定测试方案。这给了团队选择空间,也让团队需要自行选择工具并建立有用的测试实践。
我解释,当时的默认数据获取设置不会把获取到的应用数据放进首个 HTML 响应。客户端获取数据期间,用户可能看到加载状态;这是该实现中的有意权衡。
这种权衡可能适合交互式应用,但对需要完整初始 HTML 或元数据的内容页、商品页可能不理想。这是我所描述设置的特性,并不意味着 Next.js 普遍无法进行服务端渲染。
此后生态已经变化。当前的 [Create T3 App 安装选项](https://create.t3.gg/en/installation)包括 App Router 和多个可选组件,因此应直接评估生成的项目及其版本。
类型、性能与适用性
类型安全、学习和项目选择。
端到端类型并不会自动证明数据库数据或运行时输入有效。团队仍需理解假设从哪里进入系统,并在适当边界验证数据。
大型 TypeScript 项目可能拖慢编辑器服务和类型检查,尤其在类型推导和复杂类型不断累积时。项目引用等工具选择可能有帮助,但应在实际代码库中衡量效果。
我区分运行时延迟与水平扩展能力。另一种运行时可能更快地执行某个后端操作,而无服务器平台可以增加实例处理并发负载;两种属性都不能单独保证另一种。
学习曲线取决于既有经验。熟悉 TypeScript 和查询库的 React 开发者可能上手很快,而编程新手需要同时学习更多概念。
模块化技术栈还有文档方面的权衡。我解释,当时项目较多依赖各组件库自己的文档和视频,这可能迫使新手在多个来源之间查找。
我的结论是根据应用选择。我仍然偏好用这个技术栈构建数据经常变化的交互式全栈应用,同时承认主要静态的网站或约束不同的团队可能更适合其他方案。
在工作中采用技术栈前,应与团队一起审视其局限,并与项目需求比较。工具的权衡适合实际工作时,它才有用。
同频道的其他文章
49:29EN → 简体中文
41:49EN → 简体中文
38:47EN → 简体中文
36:07EN → 简体中文
30:37EN → 简体中文
0:43EN → 简体中文