束葵顺头像
关注

create-t3-app 新项目启动指南:数据库初始化与 Discord 登录配置(First Steps 全解析)

create-t3-app 新项目启动指南:数据库初始化与 Discord 登录配置(First Steps 全解析)

【免费下载链接】create-t3-app The best way to start a full-stack, typesafe Next.js app 【免费下载链接】create-t3-app 项目地址: https://gitcode.com/gh_mirrors/cr/create-t3-app

创建完一个 create-t3-app 项目之后,真正的开发才刚刚开始。这篇指南以官方文档 fr/usage/first-steps.md(及对应的英文版 en/usage/first-steps.md)为骨架,结合仓库内 CLI 的实际安装器源码,讲清楚让新生成的 T3 应用真正跑起来的"最小必要步骤":数据库的初始化与推模式(Prisma / Drizzle)、NextAuth.js 的 Discord 登录配置,以及如何从示例代码理解 tRPC 查询。读完你就能独立把脚手架项目启动到可登录、可读写数据的状态。

概览:脚手架生成后你需要做什么

当你通过 pnpm create t3-app@latest(或 npm / yarn / bun 等价命令)完成交互式选型后,CLI 已经替你完成了依赖安装、目录脚手架和基础配置。但有两类事情是 CLI 无法替你完成的:

  1. 数据库本身:CLI 只写入了 DATABASE_URL 等环境变量和 schema,并不会替你创建数据库实例;
  2. 第三方 OAuth 应用:Discord 的 Client ID / Secret 必须由你在 Discord 开发者后台申请,并回填到 .env。

CLI 在项目生成结束时,会通过 logNextSteps.ts 在终端打印后续步骤提示,其逻辑恰好对应本文的三大部分:启动数据库(./start-database.sh)、推送 schema(db:push)、填充 .env 认证变量(Fill in your .env with necessary values)。

数据库:三种情况的处理方式

脚手架根据你的选型,会生成不同的数据库工具链。官方文档将其拆为三类场景。

MySQL / PostgreSQL:使用 start-database.sh 一键拉起容器

如果你在 CLI 交互中选择了 MySQL 或 PostgreSQL,生成的工程根部会带有一个 start-database.sh bash 脚本。它的作用是用 Docker(或 Podman)启动一个本地开发数据库容器,避免你手动安装数据库服务。

仓库中的模板脚本 postgres.sh 展示了它的实现思路:

  • 从 .env 中解析 DATABASE_URL,用 awk 提取出密码(DB_PASSWORD)、端口(DB_PORT)和库名(DB_NAME);
  • 优先使用 docker,不可用时回退到 podman;
  • 检查端口是否被占用(依赖 nc/netcat);
  • 若容器已存在则直接启动,否则执行 docker run,以 -p "$DB_PORT":5432 映射端口并传入 POSTGRES_USER、POSTGRES_PASSWORD、POSTGRES_DB 三个环境变量;
  • 如果检测到密码仍是默认的 password,会提示你是否用 openssl rand -base64 12 生成随机密码并回写 .env。

对应地,CLI 安装器在 dbContainer.ts 阶段为 postgres/mysql 两种 provider 复制该脚本,并在 logNextSteps.ts 中提示你 Start up a database, if needed using './start-database.sh'。

如果你已经有一个现成的数据库,官方文档的建议是:直接删除这个脚本文件,把真实连接串填进 .env 的 DATABASE_URL 即可。macOS 用户若不想用 Docker,也可以使用 DBngin 这类数据库管理工具。

Prisma:npx prisma db push 同步 schema

如果工程包含 Prisma,请从工程根目录执行:

npx prisma db push

这条命令做两件事:

  1. 把 prisma/schema.prisma 中的模型定义同步到数据库(创建/更新表结构);
  2. 根据 schema 重新生成 Prisma Client 的 TypeScript 类型。

其中第 2 步对编辑器体验很关键:生成类型后需要重启 TypeScript 服务(VS Code 中通过命令面板执行 "TypeScript: Restart TS Server"),否则编辑器无法识别新生成的 Prisma Client 类型,会报大量类型错误。

仓库中的 Prisma 安装器 prisma.ts 印证了这套工作流:它会向 package.json 注入 db:push(prisma db push)、db:studio(prisma studio)、db:migrate(prisma migrate deploy)、db:generate(prisma migrate dev)以及 postinstall: prisma generate 等脚本。也就是说,你也可以用包管理器等价命令:

pnpm db:push   # 或 npm run db:push / yarn db:push / bun run db:push

安装器还会根据你的选型复制不同版本的 schema:base.prisma 只有 Post 模型;若启用了 NextAuth,则换成 with-auth.prisma,额外包含 Account、Session、User、VerificationToken 四个 NextAuth 适配器必需的模型。同时,schema 中的 provider 会按所选数据库改写为 sqlite / mysql / postgresql,MySQL 与 PlanetScale 场景还会自动取消 @db.Text 注释。

Drizzle:db:push 推送 schema

如果选择 Drizzle ORM,官方文档的指引是:先查看 .env 中关于如何构造 DATABASE_URL 的注释说明,填好环境变量后运行:

pnpm db:push

Drizzle 安装器 drizzle.ts 为工程注入的脚本包括:db:push(drizzle-kit push)、db:studio(drizzle-kit studio)、db:generate(drizzle-kit generate)、db:migrate(drizzle-kit migrate)。生成的配置模板 drizzle-config-postgres.ts 演示了 drizzle.config.ts 的标准形态:

import { type Config } from "drizzle-kit";
import { env } from "~/env";

export default {
  schema: "./src/server/db/schema.ts",
  dialect: "postgresql",
  dbCredentials: {
    url: env.DATABASE_URL,
  },
  tablesFilter: ["project1_*"],
} satisfies Config;

注意其中的 tablesFilter:安装器会把 project1_* 占位符替换为你的项目名,用来限制 drizzle-kit 只管理属于本应用的表,避免误伤同库中的其他表。

环境变量与 .env 的生成规则

无论选择哪条数据库路线,.env 都是关键。CLI 的 envVars.ts 会按选型生成不同的 .env / .env.example 内容:

  • sqlite:DATABASE_URL="file:./db.sqlite"
  • mysql:DATABASE_URL="mysql://root:password@localhost:3306/<appName>"
  • postgres:DATABASE_URL="postgresql://postgres:password@localhost:5432/<appName>"
  • planetscale(Prisma):DATABASE_URL='mysql://YOUR_MYSQL_URL_HERE?sslaccept=strict'
  • planetscale(Drizzle):DATABASE_URL='mysql://YOUR_MYSQL_URL_HERE?ssl={"rejectUnauthorized":true}'

同时,envVars.ts 会为认证功能生成随机的 AUTH_SECRET(32 字节随机数的 base64)写入 .env,但不会写入 .env.example——因为后者会提交到版本库,绝不能包含密钥。

认证:配置 NextAuth.js 的 DiscordProvider

如果工程包含 NextAuth.js,脚手架默认用 DiscordProvider 帮你起步。之所以选 Discord,是因为它是 NextAuth 提供的最简单的 OAuth 提供方之一,但即便如此,仍需要你手动完成少量初始配置。

为什么默认是 Discord

在 auth/config/base.ts 中可以看到,生成的认证配置直接引入了 DiscordProvider:

export const authConfig = {
  providers: [
    DiscordProvider,
    /**
     * ...add more providers here.
     *
     * Most other providers require a bit more work than the Discord provider.
     * For example, the GitHub provider requires you to add the
     * `refresh_token_expires_in` field to the Account model.
     */
  ],
  callbacks: {
    session: ({ session, token }) => ({
      ...session,
      user: { ...session.user, id: token.sub },
    }),
  },
} satisfies NextAuthConfig;

注释里明确写着:其他大多数 provider 比 Discord 需要更多工作(比如 GitHub provider 要求在 Prisma 的 Account 模型上补充 refresh_token_expires_in 字段)。这正是"先从 Discord 起步"的工程考量。如果你偏好其他提供方,可以直接替换 providers 数组并到 NextAuth 官方 providers 列表中选择。

Discord 后台配置步骤

  1. 准备一个 Discord 账号(没有就先注册);
  2. 打开 https://discord.com/developers/applications,点击右上角 "New Application",为应用命名并同意服务条款;
  3. 创建成功后,进入 "Settings → OAuth2 → General";
  4. 复制 "Client ID",填入 .env 的 AUTH_DISCORD_ID;
  5. 点击 "Reset Secret",复制新生成的 secret,填入 .env 的 AUTH_DISCORD_SECRET(注意官方文档法文版中误写的 DISCORD CLIENT_SECRET 实为 AUTH_DISCORD_SECRET,英文版与 envVars.ts 源码均以 AUTH_DISCORD_SECRET 为准);
  6. 点击 "Add Redirect",填入 http://localhost:3000/api/auth/callback/discord:
    • 生产部署时:按同样步骤另建一个 Discord Application,并把 http://localhost:3000 替换为你实际部署的域名;
  7. 保存更改。

完成后运行 pnpm dev(或 npm run dev),应用即可通过 Discord 登录。

生成的 .env 与类型安全校验

启用 NextAuth 后,CLI 会在 .env 中生成以下认证相关变量(见 envVars.ts):

# Next Auth
# You can generate a new secret on the command line with:
# npx auth secret
AUTH_SECRET=""

# Next Auth Discord Provider
AUTH_DISCORD_ID=""
AUTH_DISCORD_SECRET=""

同时,envVars.ts 已经为 AUTH_SECRET 生成了一串随机值,并注释 # Generated by create-t3-app.。

这些变量并非"填了就行"——它们还会被 with-auth-db.js 中的 createEnv 严格校验:AUTH_SECRET 在生产环境必须为非空字符串(开发环境可选)、AUTH_DISCORD_ID 与 AUTH_DISCORD_SECRET 必须是 z.string()、DATABASE_URL 必须是合法 URL。缺失或格式错误时,next dev / next build 会直接抛出类型校验错误,这就是 T3 应用"类型安全环境变量"的体现。若你需要在 Docker 等无 env 场景下跳过校验,可以设置 SKIP_ENV_VALIDATION 环境变量(见 with-auth-db.js)。

Prisma + NextAuth 的模型联动

若同时选择了 Prisma 与 NextAuth,生成的 schema 会包含四个认证模型:Account、Session、User、VerificationToken(见 with-auth.prisma)。其中 Post 模型还会新增 createdBy / createdById 字段,与 User 建立一对多关系。因此必须先执行 npx prisma db push 再启动登录流程,否则 NextAuth 写入 session 时会因表不存在而报错——这也解释了为什么官方文档把"数据库"排在"认证"之前。

下一步:从示例理解 tRPC 查询

登录与数据库就绪后,就可以开始写业务代码了。若工程包含 tRPC,官方文档建议你重点看两个文件:

  • src/pages/index.tsx(Pages Router 场景)或 src/app/page.tsx(App Router 场景)——页面如何调用 tRPC;
  • src/server/api/routers/post.ts——服务端路由如何定义。

仓库模板中的示例路由 post/base.ts 是理解 tRPC 用法的最小样例:

export const postRouter = createTRPCRouter({
  hello: publicProcedure
    .input(z.object({ text: z.string() }))
    .query(({ input }) => ({ greeting: `Hello ${input.text}` })),

  create: publicProcedure
    .input(z.object({ name: z.string().min(1) }))
    .mutation(async ({ input }) => { /* ... */ }),

  getLatest: publicProcedure.query(() => posts.at(-1) ?? null),
});

它展示了 tRPC 的三个核心概念:

  • createTRPCRouter:把一组 procedure 组合成一个路由对象;
  • publicProcedure.query / .mutation:区分只读查询与写入操作;
  • .input(z.object(...)):用 Zod 定义输入校验,实现端到端类型安全——客户端调用时的类型推断、运行时校验都由此驱动。

对照文件树,你会发现模板为不同选型准备了多套路由版本:post/base.ts、post/with-auth.ts、post/with-prisma.ts、post/with-drizzle.ts 等(见 post 路由目录),CLI 会根据是否启用认证/数据库复制对应版本。同理,页面模板(如 with-auth-trpc-tw.tsx)会按组合选型生成,这就是为什么不同选型的项目首页展示内容不同。

小结

让一个新建的 create-t3-app 工程跑起来,只需按顺序完成三件事:

  1. 数据库:MySQL/PostgreSQL 用 ./start-database.sh 起容器,或直接复用已有库并在 .env 填好 DATABASE_URL;Prisma 执行 npx prisma db push,Drizzle 执行 pnpm db:push(记得重启 TypeScript 服务);
  2. 认证:在 Discord 开发者后台创建应用,把 AUTH_DISCORD_ID、AUTH_DISCORD_SECRET 填入 .env,并配置回跳地址 http://localhost:3000/api/auth/callback/discord(生产环境换成部署域名);
  3. 开发:运行 pnpm dev 启动应用,通过 post/base.ts 等示例理解 tRPC 的 router / procedure / input 三段式写法。

关于脚手架生成时每一步具体做了什么,你可以在仓库的 installers 目录 找到全部安装器源码;CLI 打印的"Next steps"提示逻辑则见 logNextSteps.ts,它与你看到的终端输出一一对应。

【免费下载链接】create-t3-app The best way to start a full-stack, typesafe Next.js app 【免费下载链接】create-t3-app 项目地址: https://gitcode.com/gh_mirrors/cr/create-t3-app

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/gitblog_00472/article/details/156482450

文章来源转载

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--