Skip to content

项目创建与配置

🙋 创建一个 Next.js 项目有多简单?一行命令。但理解项目结构和配置项,才能在开发中游刃有余。

创建项目#

使用 create-next-app(推荐)#

Terminal window
# 环境要求: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

手动安装#

如果需要集成到现有项目,可以手动安装:

Terminal window
# 安装依赖
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.tsxpage.tsx 是最常用的两个文件。只有添加了 page.tsx 的文件夹才会成为可访问的路由。

next.config.ts 配置#

Next.js 15 推荐使用 TypeScript 配置文件:

next.config.ts
// Next.js 15.x
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
// 配置项
}
export default nextConfig

常用配置项#

1. 图片域名白名单#

next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com',
pathname: '/images/**',
},
{
protocol: 'https',
hostname: '*.amazonaws.com',
},
],
},
}
export default nextConfig

2. 环境变量#

next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
env: {
CUSTOM_KEY: 'custom-value',
},
// 暴露给客户端的环境变量必须以 NEXT_PUBLIC_ 开头
}
export default nextConfig

3. 重定向与重写#

next.config.ts
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 nextConfig

4. 自定义 Headers#

next.config.ts
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.config.ts
// Next.js 15.x
import 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 按以下顺序加载环境变量(后面覆盖前面):

  1. .env - 所有环境
  2. .env.local - 所有环境,本地覆盖
  3. .env.development / .env.production - 特定环境
  4. .env.development.local / .env.production.local - 特定环境本地覆盖

客户端访问#

.env.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"]
}

🎯 重点配置

启动项目#

Terminal window
# 开发模式(自动使用 Turbopack)
pnpm dev
# 生产构建
pnpm build
# 启动生产服务器
pnpm start

访问 http://localhost:3000 即可看到项目首页。

常见问题#

🤔 Q: src 目录是必须的吗?

不是必须的。你可以直接把 app 目录放在项目根目录。使用 src 的好处是将应用代码与配置文件分离,结构更清晰。

🤔 Q: 配置改了不生效怎么办?

修改 next.config.ts 后需要重启开发服务器。环境变量的修改也需要重启。

🤔 Q: 如何禁用 Turbopack?

Terminal window
# 使用 Webpack
pnpm dev --webpack

下一篇将详细介绍 App Router 的核心概念,包括与 Pages Router 的区别和迁移策略。

-EOF-