☰
Blitz.js 新应用模板(app 目录版)完整指南:从 blitz new 到可运行的认证全栈应用
2026/10/14 7:21:27 网站建设 项目流程
  • 后端
  • 前端

【免费下载链接】blitz

⚡️ The Missing Fullstack Toolkit for Next.js

项目地址:https://gitcode.com/gh_mirrors/bl/blitz
点击查看免费下载

这篇技术指南以 Blitz.js 官方脚手架生成的新应用模板(仓库中的 packages/generator/templates/app)为讲解对象,面向使用blitz new创建 Next.js 全栈应用的开发者。读完本文,你将掌握模板的启动流程、环境变量配置、CLI 命令体系、目录结构规划,以及模板内置的"注册 / 登录 / 找回密码"认证体系与 Prisma 数据层的源码级实现细节,能够在此基础上快速扩展自己的业务模型。

一、模板是什么:Blitz.js 脚手架的默认产物

Blitz.js(项目名 blitz,仓库见 README.md)是面向 Next.js 的"全栈工具包"。当你执行blitz new创建一个新项目时,生成器会把 templates/app 这套模板复制到目标目录,并把模板文件名中的__name__占位符替换为你的应用名。

这套模板与另一套经典模板最大的差异在于:它默认采用 Next.jsApp Router(src/app目录)结构,而不是旧版的pages目录结构。从 app-generator.ts 可以看到,生成器在template.path === "app"时会把认证相关的组件与 mutation 统一移动到(auth)路由组下,这是 App Router 特有的组织方式。

模板自带的package.json(即 package.ts.json)锁定了一套完整的技术栈:blitz+@blitzjs/auth+@blitzjs/next+@blitzjs/rpc+next15 +react19 +prisma+zod+formik,并默认开启 Prisma 与一套"开箱即用"的邮箱密码认证。

二、快速开始:安装 CLI 并创建应用

模板 README 指出,Blitz 自带一个强大的 CLI,全局安装即可使用:

npm i -g blitz

安装后,创建应用:

blitz new my-app

生成器源码位于 packages/generator/src/generators/app-generator.ts,它会询问 TypeScript / JavaScript、表单库(final-form / formik / react-hook-form,对应 templates/app/_forms 下的三个实现)等选项,然后渲染模板。

三、启动开发服务器

模板 README 给出的第一个操作是:

blitz dev

随后用浏览器打开 http://localhost:3000 即可看到应用首页。首页代码位于 src/app/page.tsx,它是一个异步 Server Component:通过invoke(getCurrentUser, null)直接调用服务端查询,如果当前没有登录用户就展示Sign Up / Login按钮,否则展示用户 id、角色与登出按钮——也就是说,模板生成的应用天然自带完整的注册登录闭环。

首页还提示了一条后续开发主线:在终端依次执行blitz generate all project、Ctrl + c、blitz dev,即可为Project模型生成查询、变更与页面,然后访问/projects验证新生成的 CRUD 页面。

四、环境变量配置

Blitz 遵循 dotenv 惯例读取环境变量。模板要求准备两个文件:

.env.local(开发/生产本地环境)

DATABASE_URL=postgresql://<YOUR_DB_USERNAME>@localhost:5432/__name__

.env.test.local(测试环境)

DATABASE_URL=postgresql://<YOUR_DB_USERNAME>@localhost:5432/__name___test

注意这里的__name__是模板占位符,创建应用后会被替换为你的数据库名。测试库通常与开发库分开命名(后缀_test),避免测试数据污染。

环境变量被 db/schema.prisma 引用:

datasource db { provider = "sqlite" url = env("DATABASE_URL") }

模板默认的 provider 是sqlite,也就是说即使不配置 Postgres,直接使用DATABASE_URL=file:./dev.db之类的 SQLite 连接串也能跑通开发(模板 db/dev.db 即是预置的开发库)。要切换到 PostgreSQL,把 provider 改为postgresql并配置对应的连接串即可,同时注意 schema.prisma 中的注释提示:枚举类型(如 TokenType)仅在 Postgres 下可用。

另外,模板的 gitignore 明确忽略了.env*.local,保证密钥类环境变量不会进入版本控制。

五、运行测试

模板 README 给出了测试命令:

yarn test

模板配套了基于Vitest与react-testing-library的测试环境。查看模板 package.ts.json 的 scripts 可以看到实际命令是:

"test": "vitest run --passWithNoTests", "test:watch": "vitest"

模板已经内置了两个真实的单元测试示例,直接展示了如何测试认证 mutation:

  • forgotPassword.test.ts:用vi.mock固定generateToken返回值、mockpreview-email,验证"用户不存在时不抛错"以及"创建新 token、删除旧 token、发送邮件"的完整流程;
  • resetPassword.test.ts:构造"过期 token / 有效 token / 不存在 token"三种场景,验证无效 token 抛错、有效 token 被删除、密码被更新且可以用SecurePassword.verify验证。

这两个测试文件在生成应用后会被保留,是编写后续业务测试的绝佳参照。

六、Blitz CLI 命令总览

模板 README 列出了 CLI 的全部子命令。下表在原文基础上补充了每个命令的用途说明:

命令用途
blitz dev启动开发服务器(热更新)
blitz build创建生产构建
blitz start启动生产服务器(需先 build)
blitz export把应用导出为静态站点
blitz prisma运行 Prisma 相关命令(如blitz prisma migrate dev)
blitz generate为项目生成新文件(模型、页面、查询、变更等)
blitz console运行 Blitz 控制台 REPL,可交互式调用查询与变更
blitz install安装 recipe(社区维护的预置功能包)
blitz help显示帮助
blitz test运行项目测试

从源码结构看,这些命令分别实现在 packages/blitz/src/cli/commands 下:new.ts(创建应用)、generate.ts(生成文件)、console.ts(REPL)、prisma.ts与db.ts(数据库)、codegen.ts(类型代码生成)、routes.ts(路由工具)以及next/子目录(dev/build/start 等 Next.js 相关命令),统一由 cli/index.ts 组装分发。

七、项目目录结构逐层解读

模板 README 给出了生成后的完整目录树。结合仓库中真实模板,将关键目录整理如下(__name__为你的应用名):

__name__ ├── README.md ├── db │ ├── index.ts # Prisma 客户端实例(enhancePrisma 增强) │ └── schema.prisma # 数据模型定义 ├── integrations # 第三方集成(Stripe、Sentry 等)放在这里 ├── mailers │ └── forgotPasswordMailer.ts ├── next-env.d.ts ├── next.config.js # Next.js 配置(withBlitz 包装) ├── package.json ├── public # 静态资源 ├── src │ ├── app # App Router 应用目录 │ │ ├── (auth) # 认证路由组(login/signup/forgot-password/reset-password + mutations + components) │ │ ├── api/rpc/... # Blitz RPC 路由挂载点 │ │ ├── components # Form / LabeledTextField 等通用表单组件 │ │ ├── users # 当前用户查询与 hook │ │ ├── blitz-client.ts / blitz-server.ts / blitz-auth-config.ts │ │ ├── error.tsx / loading.tsx / layout.tsx / page.tsx │ │ └── styles # 全局样式 │ └── pages # 兼容的 Pages Router(仅保留 API RPC 路由时为空) ├── tsconfig.json └── types.ts # Role 类型与 Session PublicData 的全局声明

各目录职责如下:

  • src/:整个项目的主容器,页面与 API 路由都放在这里。App Router 下页面即src/app/**/page.tsx;
  • db/:数据库配置与迁移所在地。db/index.ts 使用enhancePrisma(PrismaClient)创建增强版 Prisma 客户端,并在查询时自动附带ctx.session相关的请求上下文;模型与迁移则看schema.prisma与db/migrations/;
  • public/:存放图片、视频等静态资源;
  • integrations/:存放第三方集成代码,如 Stripe、Sentry 的客户端实例封装;
  • mailers/:邮件发送器。forgotPasswordMailer.ts 展示了模板的做法:开发环境下用preview-email在浏览器预览邮件,生产环境下抛出 "No production email implementation" 错误,提示你接入真实的邮件服务商;
  • package.json:依赖与脚本;tsconfig.json:TypeScript 推荐配置(strict 模式 +@/*路径别名);next.config.js则用 withBlitz 包装,并开启experimental.typedRoutes;
  • types.ts:types.ts 声明了Role = "ADMIN" | "USER",并通过模块扩充把Session.PublicData的类型钉死为{ userId, role },让鉴权逻辑全程类型安全。

表单组件与数据模型

模板在_forms/下提供了 final-form / formik / react-hook-form 三套等价实现。以 final-form 版 Form.tsx 为例,它接收zodschema,用validateZodSchema做校验,把提交错误渲染到role="alert"区域;LabeledTextField.tsx 则封装了字段 label、错误提示与 number 类型解析。

数据层模型在 schema.prisma 中定义:

  • User:id、createdAt、updatedAt、可选name、唯一email、可选hashedPassword、默认"USER"的role,并关联tokens与sessions;
  • Session:handle(唯一)、hashedSessionToken、antiCSRFToken、publicData、privateData与可选的user关联——这是 Blitz 会话机制在数据库侧的落点;
  • Token:hashedToken、type、expiresAt、sentTo,并以@@unique([hashedToken, type])约束唯一性,用于密码重置等一次性令牌场景。

八、模板内置的认证与 RPC 体系(源码纵深)

这是模板最有价值的部分——一个开箱即用的认证闭环。我们从"两端 + 一路由"看它的装配方式。

服务端装配

src/app/blitz-server.ts 是服务端的核心:

const {api, getBlitzContext, useAuthenticatedBlitzContext, invoke, withBlitzAuth} = setupBlitzServer({ plugins: [ AuthServerPlugin({ ...authConfig, storage: PrismaStorage(db), isAuthorized: simpleRolesIsAuthorized, }), RpcServerPlugin({}), ], logger: BlitzLogger({}), })

要点:

  • AuthServerPlugin使用PrismaStorage(db)把会话持久化到数据库(即上面 schema 中的 Session 模型),simpleRolesIsAuthorized提供基于角色的轻量鉴权;
  • RpcServerPlugin让查询/变更函数变成可跨端调用的 RPC;
  • 导出的invoke允许在 Server Component 中直接调用查询/变更,首页正是这样拿到当前用户的。

客户端装配

src/app/blitz-client.ts 通过setupBlitzClient组合AuthClientPlugin(authConfig)与BlitzRpcPlugin({}),导出BlitzProvider,由 layout.tsx 包裹全局;认证配置在 blitz-auth-config.ts,目前只有cookiePrefix: "app-dir",用于给会话 Cookie 加前缀,避免多应用冲突。

RPC 路由挂载

src/app/api/rpc/blitzrpcroute/route.ts 是 App Router 下 RPC 的唯一入口:

export const {GET, HEAD, POST} = withBlitzAuth(rpcAppHandler())

rpcAppHandler()处理全部查询/变更的 HTTP 调用,withBlitzAuth负责注入认证上下文。

认证流程逐个拆解

模板的认证 mutation 全部位于 src/app/auth/mutations:

  • 注册 signup.ts:SecurePassword.hash哈希密码,db.user.create建用户,再blitzContext.session.$create({userId, role: "user"})直接建立会话——注册即登录;
  • 登录 login.ts:Login.parse做 zod 校验,SecurePassword.verify验密;若返回VALID_NEEDS_REHASH,说明哈希强度可升级,自动用新哈希更新数据库(安全加固细节);校验失败统一抛AuthenticationError,避免泄露"用户是否存在";
  • 登出 logout.ts:一行ctx.session.$revoke()吊销当前会话;
  • 忘记密码 forgotPassword.ts:完整实现"生成 token(generateToken明文 +hash256落库)→ 删除该用户旧 token → 写入 4 小时过期的RESET_PASSWORDtoken → 发送邮件"的流程;用户不存在时故意setTimeout(750)等待相同时间,防止攻击者通过响应时间探测邮箱是否注册;
  • 重置密码 resetPassword.ts:按hash256(token)查找、使用后立即删除 token(防重放)、校验过期时间、更新密码、删除该用户全部会话,最后调用login用新密码重新登录;
  • 修改密码 changePassword.ts:用resolver.authorize()强制登录态,先验证当前密码再写新哈希。

所有 mutation 都用resolver.pipe(resolver.zod(Schema), ...)包裹,输入校验由 validations.ts 中的 zod schema 完成——例如密码要求 10~100 位并自动 trim,ResetPassword用refine保证两次密码一致。

当前用户查询与 Hook

  • getCurrentUser.ts:ctx.session.userId为空直接返回 null,否则按 id 查出用户(只 select id/name/email/role);
  • useCurrentUser.ts:客户端 Hook,用useQuery包装上述查询,供客户端组件使用。

九、内置开发工具:ESLint、Husky 与 Prettier

模板 README 强调,Blitz 自带一组"纠正与格式化代码"的工具,且可修改、可卸载:

  • ESLint:检查坏实践并提示。可通过.eslintrc.js自定义,内置blitz的 eslint 配置(见仓库根目录 packages/config/eslint.js 的配置包),也可安全移除;
  • Husky:注入 Git hooks,例如pre-commit在每次提交前执行。hooks 存放在.husky/;提交/推送遇到问题时参照 Husky 官方 troubleshooting 排查;
  • Prettier:统一代码风格。通过.prettierrc配置,.prettierignore指定忽略文件。模板在 package.ts.json 中预置了semi: false、printWidth: 100风格,并用lint-staged在提交前对*.{js,ts,tsx}自动eslint --fix。

此外,模板还带一个 npmrc,通过public-hoist-pattern提升@tanstack/react-query、next、secure-password等关键依赖的安装层级,注释明确写着"Needed for Blitz to work properly. Don't remove the lines above"——如果安装后运行时出现依赖解析问题,先检查这个文件是否被改动。

十、基于模板快速扩展业务

模板 README 给出了一套最小可用的扩展工作流:

# 1. 为 Project 模型生成全套文件(模型、查询、变更、页面) blitz generate all project # 2. 停止开发服务器 # Ctrl + c # 3. 重新启动 blitz dev # 4. 浏览器访问生成的 CRUD 页面 # http://localhost:3000/projects

blitz generate的实现位于 packages/generator,它支持从schema.prisma读取模型并按需生成 query / mutation / page / route 等文件。每生成一个新模型,都可以沿用模板已有的安全模式:用resolver.pipe(resolver.zod(Input), resolver.authorize(), handler)包裹变更,用 zod 校验输入,用SecurePassword处理密码类敏感数据。

结语

从blitz new到一套带认证、带数据库、带测试的全栈应用,模板把 Blitz.js 的最佳实践浓缩在一个可复制的目录结构中。理解这份模板的装配方式——setupBlitzServer/setupBlitzClient的插件机制、PrismaStorage的会话落库、RPC 路由与invoke调用链、以及一整套密码学安全的认证 mutation——就等于掌握了 Blitz.js 的核心运行原理。后续无论是接入 Postgres、接入真实邮件服务,还是生成新的业务模型,都可以在这份模板的基础上平滑演进。

  • 后端
  • 前端

【免费下载链接】blitz

⚡️ The Missing Fullstack Toolkit for Next.js

项目地址:https://gitcode.com/gh_mirrors/bl/blitz
点击查看免费下载
上一篇:三月七小助手:星穹铁道自动化助手完整配置指南
下一篇:告别重复刷本!三月七小助手如何为你每天节省2小时游戏时间

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询