Next.js 14 带来了许多激动人心的新特性,包括局部渲染、Server Actions 增强等。作为一名前端开发者,我最近在项目中升级到了 Next.js 14,今天就来分享一下从项目搭建到实际应用的完整过程。
项目初始化
首先,让我们创建一个全新的 Next.js 14 项目:- # 使用 create-next-app 创建项目
- npx create-next-app@latest my-next-app
复制代码 在初始化过程中,你会看到以下选项:- ✔ Would you like to use TypeScript? Yes
- ✔ Would you like to use ESLint? Yes
- ✔ Would you like to use Tailwind CSS? Yes
- ✔ Would you like to use `src/` directory? Yes
- ✔ Would you like to use App Router? Yes
- ✔ Would you like to customize the default import alias? No
复制代码 目录结构解析
创建完成后,我们来看看项目的核心目录结构:- my-next-app/
- ├── src/
- │ ├── app/
- │ │ ├── layout.tsx # 根布局文件
- │ │ ├── page.tsx # 首页组件
- │ │ ├── error.tsx # 错误处理组件
- │ ├── loading.tsx # 加载状态组件
- │ │ └── not-found.tsx # 404页面组件
- │ ├── components/ # 组件目录
- │ └── lib/ # 工具函数目录
- ├── public/ # 静态资源目录
- ├── next.config.js # Next.js 配置文件
- └── package.json # 项目依赖配置
复制代码 App Router 基础
Next.js 14 推荐使用 App Router,它基于 React Server Components,提供了更好的性能和开发体验。
1. 基础路由
- // src/app/page.tsx - 首页
- export default function Home() {
- return (
- <main className="flex min-h-screen flex-col items-center justify-between p-24">
- <h1>Welcome to Next.js 14</h1>
- </main>
- );
- }
- // src/app/about/page.tsx - 关于页面
- export default function About() {
- return (
-
- <h1>About Us</h1>
-
- );
- }
复制代码 2. 布局组件
- // src/app/layout.tsx
- export default function RootLayout({
- children,
- }: {
- children: React.ReactNode;
- }) {
- return (
- <html lang="en">
- <body>
- <header>
- <nav>{/* 导航栏组件 */}</nav>
- </header>
- <main>{children}</main>
- <footer>{/* 页脚组件 */}</footer>
- </body>
- </html>
- );
- }
- // src/app/blog/layout.tsx - 博客专属布局
- export default function BlogLayout({
- children,
- }: {
- children: React.ReactNode;
- }) {
- return (
-
-
- {/* 博客侧边栏 */}
- </aside>
-
- {children}
-
-
- );
- }
复制代码 数据获取
Next.js 14 提供了多种数据获取方式,默认都是基于 Server Components:
1. 服务端获取数据
- // src/app/posts/page.tsx
- async function getPosts() {
- const res = await fetch('https://api.example.com/posts', {
- next: {
- revalidate: 3600 // 1小时重新验证一次
- }
- });
-
- if (!res.ok) {
- throw new Error('Failed to fetch posts');
- }
-
- return res.json();
- }
- export default async function Posts() {
- const posts = await getPosts();
-
- return (
-
- {posts.map(post => (
- <PostCard key={post.id} post={post} />
- ))}
-
- );
- }
复制代码 2. 动态路由数据获取
- // src/app/posts/[id]/page.tsx
- async function getPost(id: string) {
- const res = await fetch(`https://api.example.com/posts/${id}`, {
- cache: 'no-store' // 禁用缓存,始终获取最新数据
- });
-
- if (!res.ok) {
- throw new Error('Failed to fetch post');
- }
-
- return res.json();
- }
- export default async function Post({
- params: { id }
- }: {
- params: { id: string }
- }) {
- const post = await getPost(id);
-
- return (
-
- <h1>{post.title}</h1>
- {post.content}
- </article>
- );
- }
复制代码 Server Actions
Next.js 14 增强了 Server Actions,让表单处理变得更简单:- // src/app/posts/new/page.tsx
- export default function NewPost() {
- async function createPost(formData: FormData) {
- 'use server';
-
- const title = formData.get('title');
- const content = formData.get('content');
-
- // 服务端验证
- if (!title || !content) {
- throw new Error('Title and content are required');
- }
-
- // 直接在服务端处理数据
- await db.post.create({
- data: {
- title: title as string,
- content: content as string,
- },
- });
-
- // 重定向到文章列表
- redirect('/posts');
- }
-
- return (
- <form action={createPost}>
- <input type="text" name="title" placeholder="文章标题" />
- <textarea name="content" placeholder="文章内容" />
- <button type="submit">发布文章</button>
- </form>
- );
- }
复制代码 客户端组件
虽然 Server Components 是默认的,但有时我们需要客户端交互:- // src/components/Counter.tsx
- 'use client';
- import { useState } from 'react';
- export default function Counter() {
- const [count, setCount] = useState(0);
-
- return (
-
- <p>Count: {count}</p>
- <button onClick={() => setCount(count + 1)}>
- Increment
- </button>
-
- );
- }
复制代码 元数据配置
Next.js 14 提供了强大的元数据 API:- // src/app/layout.tsx
- import { Metadata } from 'next';
- export const metadata: Metadata = {
- title: {
- template: '%s | My Next.js App',
- default: 'My Next.js App',
- },
- description: 'Built with Next.js 14',
- openGraph: {
- title: 'My Next.js App',
- description: 'Built with Next.js 14',
- images: ['/og-image.jpg'],
- },
- };
- // src/app/blog/[slug]/page.tsx
- export async function generateMetadata({
- params
- }: {
- params: { slug: string }
- }): Promise<Metadata> {
- const post = await getPost(params.slug);
-
- return {
- title: post.title,
- description: post.excerpt,
- openGraph: {
- title: post.title,
- description: post.excerpt,
- images: [post.coverImage],
- },
- };
- }
复制代码 静态资源处理
Next.js 14 优化了图片和字体的处理:- // src/components/ProfileImage.tsx
- import Image from 'next/image';
- export default function ProfileImage() {
- return (
- <Image
- src="/profile.jpg"
- alt="Profile"
- width={200}
- height={200}
- placeholder="blur"
- blurDataURL="data:image/jpeg;base64,..."
- priority
- />
- );
- }
- // src/app/layout.tsx
- import { Inter } from 'next/font/google';
- const inter = Inter({
- subsets: ['latin'],
- display: 'swap',
- });
- export default function RootLayout({
- children,
- }: {
- children: React.ReactNode;
- }) {
- return (
- <html lang="en" className={inter.className}>
- <body>{children}</body>
- </html>
- );
- }
复制代码 环境配置
Next.js 14 支持多环境配置:- # .env.local
- DATABASE_URL="postgresql://..."
- API_KEY="your-api-key"
- # .env.production
- NEXT_PUBLIC_API_URL="https://api.production.com"
- # .env.development
- NEXT_PUBLIC_API_URL="http://localhost:3000"
复制代码 使用环境变量:- // src/lib/db.ts
- const dbUrl = process.env.DATABASE_URL;
- const apiKey = process.env.API_KEY;
- // 客户端也可以使用 NEXT_PUBLIC_ 前缀的环境变量
- console.log(process.env.NEXT_PUBLIC_API_URL);
复制代码 错误处理
Next.js 14 提供了完善的错误处理机制:- // src/app/error.tsx
- 'use client';
- export default function Error({
- error,
- reset,
- }: {
- error: Error;
- reset: () => void;
- }) {
- return (
-
- <h2>Something went wrong!</h2>
- <p>{error.message}</p>
- <button onClick={() => reset()}>Try again</button>
-
- );
- }
- // src/app/not-found.tsx
- export default function NotFound() {
- return (
-
- <h2>404 - Page Not Found</h2>
- <p>Could not find requested resource</p>
-
- );
- }
复制代码 开发调试
Next.js 14 改进了开发体验:- // 使用 React Developer Tools
- import { useDebugValue } from 'react';
- function useCustomHook() {
- const value = // ... 一些计算
-
- // 在 React DevTools 中显示自定义值
- useDebugValue(value, value => `Custom: ${value}`);
-
- return value;
- }
- // 使用 next.config.js 配置开发环境
- /** @type {import('next').NextConfig} */
- const nextConfig = {
- reactStrictMode: true,
- // 启用详细的构建输出
- logging: {
- fetches: {
- fullUrl: true,
- },
- },
- // 配置重写规则
- rewrites: async () => {
- return [
- {
- source: '/api/:path*',
- destination: 'http://localhost:3001/api/:path*',
- },
- ];
- },
- };
- module.exports = nextConfig;
复制代码 写在最后
Next.js 14 带来了许多激动人心的新特性,特别是在性能优化和开发体验方面有了显著提升。这篇文章介绍的只是基础功能,在实际项目中,你还可以:
- 使用 Middleware 进行路由控制
- 配置国际化路由
- 实现增量静态再生成(ISR)
- 使用 Edge Runtime 优化性能
- 集成各种第三方服务
在接下来的系列文章中,我们会深入探讨这些进阶主题。如果你对某个特定主题特别感兴趣,欢迎在评论区告诉我!
如果觉得这篇文章对你有帮助,别忘了点个赞
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |