使用 Next.js + React 技术栈构建现代 Web 应用
· 6 min read
随着前端技术的飞速发展,构建高效、现代化的 Web 应用变 得愈发重要。本文将围绕 Next.js、React、shadcn、TailwindCSS、Zod、Zustand、React Query 和 openapi-react-query 的技术栈,分享一个完整的开发方案。
1. 技术栈简介
Next.js
一个基于 React 的框架,支持服务端渲染 (SSR)、静态站点生成 (SSG) 和全栈开发。它提升了 SEO 能力,并优化了性能。
React
现代化的组件式前端开发库,是构建用户界面的核心工具。
shadcn
一个整合了 Radix UI 和 TailwindCSS 的组件工具库,提供丰富的 UI 基础组件。
TailwindCSS
一种实用的 CSS 框架,通过类名快速构建响应式、现代化的 UI。
Zod
一个类型安全的验证库,用于校验表单数据或 API 请求数据,完美配合 TypeScript。
Zustand
轻量级状态管理工具,适合管理复杂但局部的应用状态。
React Query
服务器状态管理工具,处理数据获取、缓存、同步及更新。
openapi-react-query
基于 OpenAPI 规范生成类型安全的 React Query API 客户端,提升开发效率和安全性。
2. 快速项目初始化
2.1 创建 Next.js 项目
使用 TypeScript 初始化项目:
npx create-next-app@latest my-nextjs-app --typescript
cd my-nextjs-app
2.2 安装依赖
安装技术栈中的核心库:
npm install tailwindcss postcss autoprefixer zustand @tanstack/react-query zod openapi-react-query
npm install @shadcn/ui
2.3 配置 TailwindCSS
初始化 TailwindCSS 配置文件:
npx tailwindcss init
修改 tailwind.config.js
:
module.exports = {
content: [
"./pages/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
"./app/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
};
在 styles/globals.css
中引入 TailwindCSS:
@tailwind base;
@tailwind components;
@tailwind utilities;
2.4 集成 React Query
创建 React Query 客户端:
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const queryClient = new QueryClient();
export default function App({ Component, pageProps }: any) {
return (
<QueryClientProvider client={queryClient}>
<Component {...pageProps} />
</QueryClientProvider>
);
}
2.5 配置 openapi-react-query
根据 OpenAPI 规范生成 API 客户端:
npx openapi-codegen generate --input ./path-to-openapi.json --output ./generated --client react-query
在项目中提供 API 配置:
import { createClient, ApiProvider } from "./generated";
const apiClient = createClient({
baseUrl: "https://api.example.com",
fetch: async (url, options) => {
// 你可以在这里添加认证逻辑,例如添加 Token 到请求头
const token = "your-auth-token";
return fetch(url, {
...options,
headers: {
...options.headers,
Authorization: `Bearer ${token}`,
},
});
},
});
export default function App({ Component, pageProps }: any) {
return (
<ApiProvider client={apiClient}>
<Component {...pageProps} />
</ApiProvider>
);
}