58.实战篇最佳实践总览
前言
在之前的项目中,我们都是使用 npx create-next-app@latest
初始化项目,它是 Next.js 的官方脚手架,提供了开发 Next.js 项目最基本的配置。
然而在实际的开发中,Next.js 通常会搭配多种技术选型一起使用,主流的比如 Tailwind CSS、TypeScript、Prisma、Drizzle、NextAuth.js、tRPC、ESLint、Prettier、Husky、Lint-Staged、Commitlint 等等。如果每次都要重复配置一遍,属实有些麻烦,所以诞生了很多包含 Next.js 最佳实践的模板、Cli、框架等等。
这其中最常用的有:
- create-t3-app(23.7k)
create-t3-app 是一个交互式的 Cli 用于启动一个全栈、类型安全的 Next.js 应用程序。它专注于简单性、模块化和全栈类型安全。它的技术栈包括 Next.js、tRPC、Tailwind CSS、TypeScript、Prisma、Drizzle、NextAuth.js
- Next-js-Boilerplate(7.6k)
Next-js-Boilerplate 是一个 Next.js 项目模板。它的技术栈包括:Next.js + TypeScript + ESLint + Prettier + Husky + Lint-Staged + Jest + Testing Library + Cypress + Storybook + Commitlint + VSCode + Netlify + PostCSS + Tailwind CSS
- Blitz(13.4k)
Blitz 致力于添补 Next.js 缺失的全栈工具,比如类型安全的内容层(RPC)、Authentication、各种预配置(eslint、prettier、husky git hooks 等)、丰富的脚手架用于创建各种技术选型方案。
Next-js-Boilerplate
我们的项目会以 Next-js-Boilerplate 为模板进行开发。
注:尽管以我们项目的复杂程度并不适合用这个模板,但这个模板涉及的技术栈众多且基本都是主流技术选型,从这个模板出发,可以帮助大家快速建立起自己的 Next.js 最佳实践模板。
除此之外,在实际开发中,如果喜欢 TypeScript,也推荐使用 t3,Next.js + TypeScript + tRPC 也是常用的技术选型。
使用 Next-js-Boilerplate 模板:
git clone --depth=1 https://github.com/ixartz/Next-js-Boilerplate.git my-project-name
如果出现以下这种错误:
可以改为使用 SSH 地址:
git clone --depth=1 git@github.com:ixartz/Next-js-Boilerplate.git my-project-name
项目运行方式同正常的 Next.js 项目:
# 进入项目目录
cd my-project-name
# 安装
npm install
# 开启开发模式
npm run dev
浏览器效果如下:
从这个简单的起始界面可以看出自带了国际化和登录功能。
功能介绍
当然这个模板涉及的技术栈和功能可远不止这些,具体功能如下:
- 支持 Next.js App Router + TypeScript + Tailwind CSS
- 开启 TypeScript 和 React 18 的严格模式
- 使用 Clerk 实现鉴权:实现登录、注册、登出、忘记密码、重置密码等功能
Clerk 是一款现代化的身份验证和用户管理平台,旨在帮助开发人员轻松实现身份验证、授权和用户管理功能。它提供了全功能的身份验证选项,包括MFA和社交媒体集成,以满足不同应用程序的需求。
Clerk允许开发人员自定义身份验证界面,并提供安全性功能,以确保用户数据的安全。通过Clerk,开发人员可以轻松构建安全的用户身份验证系统和用户管理界面。
- 支持无口令身份认证(也被称为免密认证)的 Magic Links、Multi-Factor Auth (MFA)、Social Auth (Google, Facebook, Twitter, GitHub, Apple, and more),也支持使用通行密钥实现无密码登录
所谓 Magic Links,中文译为“魔法链接”,指的是在身份验证过程中发送给客户的一次性使用链接。输入用户名后,系统会向用户发送一个 URL,通过文本发送到用户的电子邮件地址或手机。用户单击即可验证自己的身份,而无需输入密码,对于某些人来说,这可能看起来像“魔法”,因此得名。
所谓 Multi-Factor Auth,中文译为“多重身份验证”,是指在授予用户帐户访问权限之前以多种不同方式对用户进行身份验证的过程。像我们常见的两步验证就是 MFA。
所谓 Socail Auth,则是通过社交媒体登录,比如 Google, Facebook, Twitter, GitHub, Apple 等等
- 使用 Turso 作为全局数据库
Turso 是一个 sqlite 数据库。之所以使用 Turso,应该是因为 Turso 是这个项目的 Sponser。免费容量共计 9 GB,支持建立一个本地数据库和远程数据库同步。
- 支持 ORM Drizzle
现代 TypeScript ORM,在《实战篇 | React Notes | Prisma》篇我们分析过 Node.js 下常用的 ORM 库,结论是目前使用度和满意度最高的是 Prisma、Drizzle、Mongoose。
Next.js 实现国际化就 2 个主流的技术选型,react-i18next 和 next-intl。Crowdin 则是面向团队和企业的 AI 驱动本地化软件。你可以把它简单的理解为管理翻译文件的平台,可以上传、翻译、下载文件。
- 使用 T3 Env 定义类型安全的环境变量
定义文件在 src/libs/Env.ts,使用 zod 定义环境变量,可对环境变量进行验证并完成自动补全和类型推断。
- 使用 React Hook Form 进行表单处理
React Hook Form (40.1k Star)是一个老牌的用于 React 应用程序的表单验证和状态管理库。它提供了一组钩子,可以轻松地创建和管理表单,而无需编写大量样板代码
- 使用数据校验库 Zod
Next.js 官方推荐,用于数据校验
- 使用 ESLint (默认 Next.js, Next.js Core Web Vitals, Tailwind CSS and Airbnb 配置)
代码检测工具,规则查看 .eslintrc.json
- 使用 Prettier
代码美化工具,具体查看 .eslintrc.json,ESLint + Prettier,也算是常见配置了
- 使用 Husky 添加 Git Hooks
自动检查 Commit Messge、代码,并在提交或推送时运行测试
- 使用 Lint-staged
在 git 暂存文件上运行 linter,命令执行在
.husky/pre-commit
- 使用 Commitlint
校验 Git Commit Messge,命令执行在
.husky/commit-msg
。Husky +Prettier + ESLint + Lint-Staged + Commitlint 是常见的用于提升代码质量和提交质量的工具
- 使用 Commitizen
用于优化提交信息。与 commitlint 的区别在于 commitlint 校验提交信息,commitizen 辅助填写提交信息;在Git 提交工作流程中,commitlint 作用于 commit-msg 阶段,commitizen 作用于 pre-commit。
可以在 package.json 中看到添加了 commit 脚本命令。使用 Commitizen 后,提交命令改为使用 npm run commit
- 使用 Vitest 和 React Testing Library 进行单元测试(Unit Testing)
Vitest 是一款JavaScript 的单元测试框架。React Testing Library 是一款用于 React 组件的 DOM Testing Library
- 使用 Playwright 进行 Integration Testing 和 E2E Testing
Playwright 是一个由 Microsoft 开发的用于浏览器测试和网页抓取的开源自动化库。
测试的三大基本类型:单元、集成和 E2E 测试。
单元测试用于验证代码中最基本的逻辑部分。
集成测试(英语:Integration testing),又称组装测试,即对程序模块采用一次性或增值方式组装起来,对系统的接口进行正确性检验的测试工作。整合测试一般在单元测试之后、系统测试之前进行。 实践表明,有时模块虽然可以单独工作,但是并不能保证组装起来也可以同时工作
E2E 是“End to End”的缩写,可以翻译成“端到端”测试。它模仿用户,从某个入口开始,逐步执行操作,直到完成某项工作。与单元测试不同,后者通常需要测试参数、参数类型、参数值、参数数量、返回值、抛出错误等,目的在于保证特定函数能够在任何情况下都稳定可靠完成工作。单元测试假定只要所有函数都正常工作,那么整个产品就能正常工作。
相对来说,E2E 测试并没有那么强调要覆盖全部使用场景,它关注的是一个完整的操作链是否能够完成。对于 Web 前端来说,还关注界面布局、内容信息是否符合预期。
- 使用 GitHub Actions 运行测试
GitHub Actions 是一个持续集成 (Continuous integration)和持续交付 (Continuous delivery)的平台,它可以做到自动化构建、测试、部署。你可以创建工作流,构建和测试每一个 pull request 或者部署合并后的代码到生产环境。
GitHub Actions 可以在你的代码仓库发生某个事件时运行一个工作流。举个例子,当有人给你的代码仓库新建了一个 issue,你可以跑一个工作流自动的添加合适的标签。
GitHub 提供了 Linux、Windows、和 macOS 虚拟机运行你的工作流,当然你也可以自定义运行环境。
查看 .github/workflows 下的命令,可以看到会执行 Checkly、测试、Crowdin 等操作
- Storybook 用于 UI 开发
Storybook 是一个用于开发 UI 组件的开源工具,它允许您创建可交互的组件并将其独立于应用程序进行开发和测试。Storybook 支持多种框架,包括 React、Vue、Angular 等。
简单来说,Storybook 用于可视化查看 UI 组件,组件根据不同的 props 传入形成不同的 “ story”,共同组成了一个 “Storybook”。可用于测试组件、添加组件文档。
- Sentry 用于错误监控
常见的用于监控错误和性能的解决方案。需要在平台注册账号。
- Codecov 用于代码覆盖率
Codecov 是一个用于代码覆盖率分析的工具,它可以帮助开发人员了解他们的代码被测试的程度。 Codecov 支持多种编程语言,并提供多种功能,例如可视化覆盖率报告、代码审查集成和与其他工具的集成
- 使用 Pino.js 打日志并使用 Better Stack 做日志管理
Pino 是一个非常快速且简洁的 Node.js 日志库,其设计宗旨在于提供最小的开销以及高性能的日志记录功能。
Better Stack是一个日志管理与分析协作平台,通过将监控、日志记录、事件管理和状态页面整合到一个平台中,为开发人员提供实时协作服务。
- 使用 Checkly 监控应用程序
Checkly 是一款验证 API 端点正确性和浏览器点击流的监控工具。
- 使用 semantic-release 做自动化 changelog 生成
自动化包的发布工作流程,包括:确定下一个版本号,生成发行说明,以及发布包。
- 使用 Percy 可视化测试(可选)
Percy是一个可视化回归测试工具。它非常适合保持你的UI测试的相关性,帮助你在不同的浏览器和设备上保持用户界面的一致性。
-
使用
@
作为绝对地址引入前缀 -
添加 VSCode 配置如: Debug、Settings、Tasks 和 Extensions
-
SEO metadata, JSON-LD 和 Open Graph tags
-
Sitemap.xml 和 robots.txt
-
Bundler Analyzer 用于分析包依赖关系,参考《实战篇 | 博客 | 性能分析》
简单总结一下:
- App Router + TypeScript + Tailwind CSS
- 自带鉴权(Clerk)和国际化实现(next-intl 和 Crowdin)
- 配套技术选型:React Hook Form(表单处理) + Zod(数据校验)
- 提升代码和 Git 提交质量相关:Husky +Prettier + ESLint + Lint-Staged + Commitlint + Commitizen + Codecov + semantic-release + VSCode 配置
- 测试相关: Vitest、React Testing Library、Playwright、Percy
- 可视化相关:Storybook、Bundler Analyzer
- 数据监控相关:Sentry + Pino.js + Better Stack + Checkly
- SEO 相关:metadata, JSON-LD、Open Graph tags、Sitemap.xml、robots.txt
- 数据库相关: Drizzle + Turso
总的来说,使用这个模板的好处在于:
- 只是作为项目的初始化代码,拥有高度自由根据自己的需要调整配置,且容易自定义
- 最小化代码模板、SEO 友好、可用于生产环境
如何使用
因为项目涉及的技术栈和平台众多,很多都需要登录到对应的平台上,获取特殊的 key 或者 token 等。所以如果真的要使用这些技术栈的话,还要做一些配置
1. 设置身份验证
在 Clerk.com 创建一个 Clerk 帐户,并在 Clerk Dashboard 中创建新应用程序。然后,将 NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY
和 CLERK_SECRET_KEY
复制到 .env.local
文件中:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_clerk_pub_key
CLERK_SECRET_KEY=your_clerk_secret_key
现在就拥有了一个功能齐全的身份验证系统:注册、登录、注销、忘记密码、重置密码、更新个人资料、更新密码、更新电子邮件、删除帐户等等。
2. 设置远程数据库
首先,需要在 Turso.tech 创建一个 Turso 帐户并安装 Turso CLI:
brew install tursodatabase/tap/turso
turso auth signup # Sign up to Turso
然后,创建一个新数据库:
turso db create nextjs-boilerplate
再然后,使用 Turso 提供的数据库 URL 更新 .env
文件中的 DATABASE_URL
:
turso db show nextjs-boilerplate --url
# .env
# DATABASE_URL=libsql://[RANDOM-CHARS]-[DB-NAME]-[ORG-NAME].turso.io
最后,还需要使用 Turso 提供的身份验证令牌在 .env.local
中创建一个新的环境变量 DATABASE_AUTH_TOKEN
:
turso db tokens create nextjs-boilerplate
# .env.local
# DATABASE_AUTH_TOKEN=[your-auth-token]
3. 修改自定义配置
项目搜索 FIXME
可以看到一些需要自定义配置的地方。这是一些需要自定义的最重要的文件:
public/apple-touch-icon.png
、public/favicon.ico
、public/favicon-16x16.png
、public/favicon-32x32.png
: 网站图标,可以从 https://favicon.io/favicon-converter/ 生成src/utils/AppConfig.ts
: 配置文件src/templates/BaseTemplate.tsx
: 默认主题next.config.mjs
: Next.js 配置.env
: 环境变量
4. 提交消息
npm run commit
5. 运行测试
npm run test
6. 集成和E2E测试
npx playwright install # Only for the first time in a new environment
npm run test:e2e
7. 部署生产环境
npm run build
npm run start
8. 其他功能
- 如果要设置翻译功能 (i18n),需要登录 Crowdin.com 创建帐户并进行配置
- 如果要用到 Sentry,需要登录 Sentry 创建账号并进行配置
- 如果要用到代码覆盖率报告,需要创建 Codecov 帐户并进行设置
- 如果要查看日志,需要 Better Stack 账户并进行配置
具体的配置方案可以在官方文档中查看:https://github.com/ixartz/Next-js-Boilerplate
最后
Next-js-Boilerplate 用到的基本都是主流技术选型,即便不使用这个模板,这些技术选择也很有借鉴意义,我们在这个项目中也会使用一些,帮助大家更深入的理解这些功能。