🙋 创建一个 Next.js 项目有多简单?一行命令。但理解项目结构和配置项,才能在开发中游刃有余。
创建项目#
使用 create-next-app(推荐)#
# 环境要求:Node.js 20+, pnpm 9+# Next.js 15.x
# 交互式创建pnpm create next-app@latest
# 或一键创建(使用默认配置)pnpm create next-app@latest my-app --yes交互式创建会询问以下选项:
✔ What is your project named? my-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 your code inside a `src/` directory? Yes✔ Would you like to use App Router? (recommended) Yes✔ Would you like to use Turbopack for `next dev`? Yes✔ Would you like to customize the import alias (@/* by default)? No🎯 推荐配置:TypeScript + ESLint + Tailwind + src 目录 + App Router
手动安装#
如果需要集成到现有项目,可以手动安装:
# 安装依赖pnpm add next@latest react@latest react-dom@latest
# 安装开发依赖pnpm add -D typescript @types/node @types/react @types/react-dom创建 package.json 脚本:
{ "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "eslint .", "lint:fix": "eslint . --fix" }}目录结构#
使用 src/ 目录的标准项目结构:
my-app/├── src/│ ├── app/ # App Router 路由目录│ │ ├── layout.tsx # 根布局(必需)│ │ ├── page.tsx # 首页│ │ ├── globals.css # 全局样式│ │ └── favicon.ico # 网站图标│ ├── components/ # 共享组件│ └── lib/ # 工具函数├── public/ # 静态资源(直接访问)├── next.config.ts # Next.js 配置├── tsconfig.json # TypeScript 配置├── tailwind.config.ts # Tailwind 配置├── package.json└── .env.local # 环境变量核心目录说明#
| 目录/文件 | 用途 |
|---|---|
src/app/ | App Router 路由,文件夹即路由 |
public/ | 静态文件,可通过 / 直接访问 |
next.config.ts | 框架配置,自定义构建行为 |
.env.local | 本地环境变量,不提交到 Git |
特殊文件约定#
App Router 中的特殊文件:
app/├── layout.tsx # 布局组件,包裹子路由├── page.tsx # 页面组件,定义路由内容├── loading.tsx # 加载状态 UI├── error.tsx # 错误边界 UI├── not-found.tsx # 404 页面├── route.ts # API 路由处理└── template.tsx # 模板组件(每次导航重新挂载)🔶 注意:layout.tsx 和 page.tsx 是最常用的两个文件。只有添加了 page.tsx 的文件夹才会成为可访问的路由。
next.config.ts 配置#
Next.js 15 推荐使用 TypeScript 配置文件:
// Next.js 15.ximport type { NextConfig } from 'next'
const nextConfig: NextConfig = { // 配置项}
export default nextConfig常用配置项#
1. 图片域名白名单#
import type { NextConfig } from 'next'
const nextConfig: NextConfig = { images: { remotePatterns: [ { protocol: 'https', hostname: 'example.com', pathname: '/images/**', }, { protocol: 'https', hostname: '*.amazonaws.com', }, ], },}
export default nextConfig2. 环境变量#
import type { NextConfig } from 'next'
const nextConfig: NextConfig = { env: { CUSTOM_KEY: 'custom-value', }, // 暴露给客户端的环境变量必须以 NEXT_PUBLIC_ 开头}
export default nextConfig3. 重定向与重写#
import type { NextConfig } from 'next'
const nextConfig: NextConfig = { async redirects() { return [ { source: '/old-page', destination: '/new-page', permanent: true, // 301 永久重定向 }, ] },
async rewrites() { return [ { source: '/api/:path*', destination: 'https://api.example.com/:path*', }, ] },}
export default nextConfig4. 自定义 Headers#
import type { NextConfig } from 'next'
const nextConfig: NextConfig = { async headers() { return [ { source: '/api/:path*', headers: [ { key: 'Access-Control-Allow-Origin', value: '*' }, { key: 'Access-Control-Allow-Methods', value: 'GET,POST,PUT,DELETE' }, ], }, ] },}
export default nextConfig完整配置示例#
// Next.js 15.ximport type { NextConfig } from 'next'
const nextConfig: NextConfig = { // 严格模式 reactStrictMode: true,
// 图片优化 images: { remotePatterns: [ { protocol: 'https', hostname: '**.example.com', }, ], formats: ['image/avif', 'image/webp'], },
// 实验性功能 experimental: { // React Compiler(需要额外安装) // reactCompiler: true, },
// Turbopack 配置(开发模式默认启用) turbopack: { // 自定义规则 },
// 输出模式 // output: 'standalone', // 用于 Docker 部署
// 压缩 compress: true,
// 生产环境移除 console compiler: { removeConsole: process.env.NODE_ENV === 'production', },}
export default nextConfig环境变量#
文件优先级#
Next.js 按以下顺序加载环境变量(后面覆盖前面):
.env- 所有环境.env.local- 所有环境,本地覆盖.env.development/.env.production- 特定环境.env.development.local/.env.production.local- 特定环境本地覆盖
客户端访问#
# 仅服务端可用DATABASE_URL=postgresql://...API_SECRET=xxx
# 客户端可用(必须 NEXT_PUBLIC_ 前缀)NEXT_PUBLIC_API_URL=https://api.example.com// 服务端组件中使用const dbUrl = process.env.DATABASE_URL
// 客户端组件中使用const apiUrl = process.env.NEXT_PUBLIC_API_URL🔶 警告:不要将敏感信息放在 NEXT_PUBLIC_ 变量中,它们会被打包到客户端代码。
TypeScript 配置#
create-next-app 自动生成的 tsconfig.json:
{ "compilerOptions": { "target": "ES2017", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "strict": true, "noEmit": true, "esModuleInterop": true, "module": "esnext", "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", "incremental": true, "plugins": [ { "name": "next" } ], "paths": { "@/*": ["./src/*"] } }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "exclude": ["node_modules"]}🎯 重点配置:
strict: true- 启用严格类型检查paths- 配置路径别名,@/指向src/
启动项目#
# 开发模式(自动使用 Turbopack)pnpm dev
# 生产构建pnpm build
# 启动生产服务器pnpm start访问 http://localhost:3000 即可看到项目首页。
常见问题#
🤔 Q: src 目录是必须的吗?
不是必须的。你可以直接把 app 目录放在项目根目录。使用 src 的好处是将应用代码与配置文件分离,结构更清晰。
🤔 Q: 配置改了不生效怎么办?
修改 next.config.ts 后需要重启开发服务器。环境变量的修改也需要重启。
🤔 Q: 如何禁用 Turbopack?
# 使用 Webpackpnpm dev --webpack下一篇将详细介绍 App Router 的核心概念,包括与 Pages Router 的区别和迁移策略。
-EOF-