Next.js: 环境搭建与项目结构
最后更新:2026-08-26
搭建 Next.js 16 开发环境就像装修新房子——脚手架帮你打好地基,剩下的结构、布局、配置都可以按需调整。
1. 你将学到
- 使用
create-next-app脚手架创建项目 - 理解
app/、public/、next.config.js等核心目录与文件 - 启动开发服务器并体验 Turbopack 即时热更新
- 解读
package.json中的关键脚本 - 配置 VS Code 推荐的开发插件
2. 一个前端新手的真实故事
(1) 痛点:三天搭不好开发环境
Charlie 是一名刚学会 React 的前端新手,想试试 Next.js。他打开官方文档,面对十几个配置选项和三个不同的脚手架命令,完全不知道该选哪个:
"我用
create-react-app只要一条命令就能跑。但 Next.js 有src/目录要不要?TypeScript 要不要?ESLint 要不要?Tailwind 要不要?光是研究这些选择就花了我 2 天时间。"
他还遇到了这些问题:
| 问题 | 表现 |
|---|---|
| 配置选择困难 | 7 个选项不知道哪些该启用 |
| 目录结构看不懂 | app/、public/、styles/ 各自的作用不清晰 |
| 热更新太慢 | 用 Webpack 每次保存要等 1-2 秒 |
| VS Code 没辅助 | 没有提示、没有自动补全,写得像在记事本 |
(2) create-next-app 的解法
用
create-next-app交互式脚手架,一键生成最佳实践的项目结构。
# 一条交互式命令,回答几个简单问题即可
npx create-next-app@latest taskflow --ts --tailwind --app --src-dir --import-alias "@/*"
(3) 收益
| 维度 | 之前(手动搭建) | 之后(create-next-app) |
|---|---|---|
| 项目搭建时间 | 2 天研究 | 3 分钟 |
| HMR 速度 | 1-2 秒(Webpack) | 3-10ms(Turbopack) |
| 代码提示 | 无 | JSX 自动补全 + Tailwind 类名提示 |
| 目录理解 | 混乱 | 按功能划分,一目了然 |
3. create-next-app 脚手架
(1) 交互式创建
# 运行脚手架命令
npx create-next-app@latest
你会看到如下交互式选项:
? What is your project named? taskflow
? Would you like to use TypeScript? Yes / No
? Would you like to use ESLint? Yes / No
? Would you like to use Tailwind CSS? Yes / No
? Would you like to use `src/` directory? Yes / No
? Would you like to use App Router? (recommended) Yes / No
? Would you like to customize the import alias (`@/*` by default)? No
(2) 推荐配置(本教程使用)
# 本课程的推荐选项(所有项目都使用这一组)
npx create-next-app@latest taskflow ^
--typescript ^
--eslint ^
--tailwind ^
--src-dir ^
--app ^
--import-alias "@/*"
| 选项 | 值 | 理由 |
|---|---|---|
| TypeScript | Yes | 生产级项目标配,类型安全 |
| ESLint | Yes | 代码质量保障 |
| Tailwind CSS | Yes | 本教程全程使用 Tailwind |
| src/ 目录 | Yes | 代码与配置分离 |
| App Router | Yes | Next.js 16 默认路由体系 |
| Import Alias | @/* | 简洁的导入路径 |
▶ 示例:脚手架创建完整流程
# ============================================
# 创建名为 shophub 的新项目
# ============================================
npx create-next-app@latest shophub --ts --tailwind --app --src-dir
# 控制台输出
cd shophub
npm run dev
输出:
Creating a new Next.js project in C:\Users\Charlie\shophub.
✔ 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? (recommended) … Yes
✔ Would you like to customize the import alias? … @/*
Success! Created shophub at shophub
Inside that directory, you can run:
npm run dev # 启动开发服务器
npm run build # 构建生产版本
npm start # 启动生产服务器
(3) 脚手架生成的项目结构
graph TB
A[shophub/] --> B[src/]
A --> C[public/]
A --> D[其他配置文件]
B --> E[app/]
B --> F[app/globals.css]
B --> G[app/layout.tsx]
B --> H[app/page.tsx]
C --> I[favicon.ico]
C --> J[图片等静态资源]
D --> K[package.json]
D --> L[tsconfig.json]
D --> M[next.config.ts]
D --> N[tailwind.config.ts]
D --> O[postcss.config.mjs]
style B fill:#d4edda
style C fill:#f8d7da
style E fill:#cce5ff
4. 项目目录结构详解
(1) src/app/ — 你的应用代码核心
| 文件 | 作用 | 必须? |
|---|---|---|
layout.tsx |
根布局(包裹所有页面) | ✅ 必须 |
page.tsx |
首页(/ 路由) |
✅ 必须 |
globals.css |
全局样式 | 推荐 |
favicon.ico |
网站图标 | 可选 |
▶ 示例:默认生成的 app/page.tsx
// ============================================
// create-next-app 默认生成的首页
// ============================================
import Image from "next/image";
export default function Home() {
return (
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
<main className="flex flex-col gap-8 row-start-2 items-center sm:items-start">
<Image
className="dark:invert"
src="/next.svg"
alt="Next.js logo"
width={180}
height={38}
priority
/>
<ol className="list-inside list-decimal text-sm text-center sm:text-left font-[family-name:var(--font-geist-mono)]">
<li className="mb-2">
Get started by editing{" "}
<code className="bg-black/[.05] dark:bg-white/[.06] px-1 py-0.5 rounded font-semibold">
src/app/page.tsx
</code>
</li>
<li>Save and see your changes instantly.</li>
</ol>
<div className="flex gap-4 items-center flex-col sm:flex-row">
<a className="...">Deploy now</a>
<a className="...">Read our docs</a>
</div>
</main>
</div>
);
}
输出:
在浏览器中打开 http://localhost:3000,可以看到:
- Next.js 官方 Logo
- "Get started by editing src/app/page.tsx" 提示
- "Deploy now" 和 "Read our docs" 两个链接
- 深色/浅色主题自适应
(2) public/ — 静态资源目录
public/
├── favicon.ico # 浏览器标签页图标
├── file.svg # 文件类型图标
├── globe.svg # 地球图标
├── next.svg # Next.js Logo
├── vercel.svg # Vercel Logo
└── window.svg # 窗口图标
所有放在 public/ 下的文件可以通过 / 根路径直接访问:
// 在组件中引用 public 目录下的图片
<img src="/logo.png" alt="Logo" />
// 或使用 next/image 组件
import Image from 'next/image';
<Image src="/logo.png" alt="Logo" width={200} height={100} />
(3) 根配置文件
| 文件 | 作用 | 修改频率 |
|---|---|---|
next.config.ts |
Next.js 编译时配置 | 低(项目启动时配置) |
tsconfig.json |
TypeScript 编译选项 | 低 |
tailwind.config.ts |
Tailwind CSS 主题/插件 | 中(添加自定义颜色) |
postcss.config.mjs |
PostCSS 插件配置 | 极低 |
package.json |
项目依赖 + NPM 脚本 | 中(添加依赖时) |
.eslintrc.json |
ESLint 规则 | 低 |
▶ 示例:配置 next.config.ts
// ============================================
// next.config.ts — Next.js 编译时配置
// ============================================
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
// 允许从指定域名加载外部图片
images: {
remotePatterns: [
{
protocol: "https",
hostname: "fakestoreapi.com",
},
{
protocol: "https",
hostname: "images.unsplash.com",
},
],
},
// 启用 PPR(Partial Prerendering)
experimental: {
ppr: true,
},
};
export default nextConfig;
输出:
配置生效后:
1. <Image> 组件可以加载 fakestoreapi.com 和 images.unsplash.com 的图片
2. 页面中 Suspense 边界后面的内容会使用 PPR 流式渲染
3. 重新运行 npm run dev 后配置生效
5. 开发服务器与 Turbopack
(1) 启动开发服务器
# 进入项目目录
cd shophub
# 启动开发服务器
npm run dev
▶ 示例:Turbopack 即时热更新体验
# ============================================
# 启动开发服务器,观察 Turbopack 的极速 HMR
# ============================================
npm run dev
# 控制台输出
> shophub@0.1.0 dev
> next dev
▲ ▲
▲ Next.js 16.2
▲ - Local: http://localhost:3000
▲ - Turbopack: ✓ loaded in 742ms
✔ Compiled /src/app/page.tsx in 142ms (modules: 523)
现在编辑 src/app/page.tsx 修改任意文字,保存:
✔ Updated /src/app/page.tsx in 4ms ← 4 毫秒!几乎瞬间更新
对比 Webpack:
| 操作 | Webpack (v15) | Turbopack (v16) | 提升倍数 |
|---|---|---|---|
| 冷启动 | 5-10s | 0.7-1.2s | 8x |
| 单文件热更新 | 50-200ms | 2-10ms | 20x |
| 大型项目构建 | 基线 | 10x 更快 | 10x |
(2) npm run build 生产构建
# 构建生产版本
npm run build
输出:
✓ Linting and checking validity of types
✓ Collecting page data
✓ Generating static pages (5/5)
✓ Collecting build traces
✓ Finalizing page optimization
Route (app) Size First Load JS
┌ ○ / 5.1 kB 89 kB
├ ○ /_not-found 152 B 84.1 kB
└ λ /api/hello 0 B 84.1 kB
+ First Load JS shared by all 84.1 kB
├ chunks/main-app ...
└ chunks/webpack ...
○ (Static) 静态生成(SSG)
λ (Dynamic) 动态渲染(SSR)
▶ 示例:npm run build 显示路由类型
# ============================================
# 生产构建输出解读
# ============================================
# 假设创建了两个页面:
# app/about/page.tsx 和 app/dashboard/page.tsx
# 其中 dashboard 使用了 cookies() 动态函数
npm run build
# 输出中的符号含义:
○ / # 静态页面(无动态函数)
○ /about # 静态页面
λ /dashboard # 动态页面(使用了动态 API)
○ /_not-found # 404 页面
输出:
Route (app) Size First Load JS
┌ ○ / 5.1 kB 89 kB
├ ○ /about 3.2 kB 87 kB
├ λ /dashboard 6.8 kB 92 kB
└ ○ /_not-found 152 B 84.1 kB
(3) npm start 生产服务器
# 构建后启动生产服务器
npm run build
npm start
npm start 必须在 npm run build 之后运行,它启动的是优化后的生产版本,而不是开发版本。
6. package.json 脚本解读
(1) 默认脚本一览
{
"name": "shophub",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "^16.2.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@types/node": "^22.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"typescript": "^5.7.0",
"tailwindcss": "^4.0.0",
"eslint": "^9.0.0",
"@eslint/eslintrc": "^3.0.0"
}
}
| 脚本 | 命令 | 用途 |
|---|---|---|
npm run dev |
next dev |
启动开发服务器(Turbopack) |
npm run build |
next build |
生产构建 |
npm start |
next start |
启动生产服务器 |
npm run lint |
next lint |
代码风格检查 |
▶ 示例:添加自定义脚本
// ============================================
// 在 package.json 中添加常用的自定义脚本
// ============================================
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"type-check": "tsc --noEmit",
"format": "prettier --write .",
"preview": "npm run build && npm start"
}
}
输出:
npm run type-check → 运行 TypeScript 类型检查(不输出文件)
npm run format → 用 Prettier 格式化全部代码
npm run preview → 先构建再启动生产服务器(一条命令完成)
7. VS Code 推荐插件
(1) 核心插件
| 插件名称 | 用途 | 安装量 |
|---|---|---|
| Tailwind CSS IntelliSense | Tailwind 类名自动补全 + 悬停预览 | 10M+ |
| ES7+ React/Redux/React-Native snippets | JSX 代码片段(rafce → 组件模板) |
8M+ |
| Prettier - Code formatter | 自动代码格式化 | 40M+ |
| Error Lens | 行内错误提示 | 5M+ |
| GitLens | Git 历史可视化 | 15M+ |
▶ 示例:VS Code 配置
// ============================================
// .vscode/settings.json — 项目级 VS Code 配置
// ============================================
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"tailwindCSS.experimental.classRegex": [
["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
],
"typescript.preferences.importModuleSpecifier": "non-relative"
}
输出:
配置生效后:
1. 每次保存文件自动格式化(Prettier)
2. 自动修复 ESLint 问题
3. Tailwind CSS 类名自动补全(输入 "flex" → 提示所有 flex 变体)
4. TypeScript 导入使用 @/ 别名路径
▶ 示例:用代码片段快速创建页面
// ============================================
// 使用 ES7+ React 插件创建新页面
// 新建文件 src/app/about/page.tsx
// 输入 "rafce" 回车,自动生成模板
// ============================================
// 输入 rafce → 自动展开为:
import React from 'react'
const page = () => {
return (
<div>page</div>
)
}
export default page
// 手动修改为实际页面内容:
export default function AboutPage() {
return (
<div className="p-8">
<h1 className="text-3xl font-bold">About Us</h1>
<p className="mt-4 text-gray-600">
TaskFlow helps teams collaborate on projects.
</p>
</div>
);
}
输出:
在浏览器访问 http://localhost:3000/about
看到:
About Us
TaskFlow helps teams collaborate on projects.
8. 完整示例:从零搭建 TaskFlow 项目
# ============================================
# 综合示例:从零搭建完整的 Next.js 16 项目
# TaskFlow — 项目协同管理平台
# ============================================
# 1. 创建项目
npx create-next-app@latest taskflow ^
--typescript ^
--eslint ^
--tailwind ^
--src-dir ^
--app ^
--import-alias "@/*"
# 2. 进入项目目录
cd taskflow
# 3. 查看目录结构
tree . /F | findstr /r "^.*src" > nul && dir /s /b src
# 4. 启动开发服务器
npm run dev
# 5. 在另一个终端中,添加推荐的 VS Code 配置
mkdir .vscode
// .vscode/settings.json — 项目级配置
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"typescript.preferences.importModuleSpecifier": "non-relative"
}
// src/app/page.tsx — 修改首页为 TaskFlow 欢迎页
import Link from "next/link";
export default function Home() {
return (
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100">
<div className="container mx-auto px-4 py-16 text-center">
<h1 className="text-5xl font-bold text-gray-900 mb-4">
TaskFlow
</h1>
<p className="text-xl text-gray-600 mb-8 max-w-2xl mx-auto">
A collaborative project management platform built with Next.js 16.
Plan, track, and deliver projects together.
</p>
<div className="flex gap-4 justify-center">
<Link
href="/login"
className="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
>
Get Started
</Link>
<Link
href="/about"
className="px-6 py-3 border border-gray-300 rounded-lg hover:bg-gray-50"
>
Learn More
</Link>
</div>
<div className="mt-16 grid grid-cols-3 gap-8 max-w-3xl mx-auto">
<div className="p-6 bg-white rounded-xl shadow-sm">
<h3 className="font-bold text-lg">Plan</h3>
<p className="text-gray-500 mt-2">Create projects and assign tasks</p>
</div>
<div className="p-6 bg-white rounded-xl shadow-sm">
<h3 className="font-bold text-lg">Track</h3>
<p className="text-gray-500 mt-2">Monitor progress in real-time</p>
</div>
<div className="p-6 bg-white rounded-xl shadow-sm">
<h3 className="font-bold text-lg">Deliver</h3>
<p className="text-gray-500 mt-2">Ship projects on schedule</p>
</div>
</div>
</div>
</div>
);
}
预期输出:
在浏览器 http://localhost:3000 看到:
[TaskFlow 标题]
A collaborative project management platform built with Next.js 16.
Plan, track, and deliver projects together.
[Get Started] [Learn More]
┌──────┐ ┌──────┐ ┌──────┐
│ Plan │ │ Track│ │Deliver│
└──────┘ └──────┘ └──────┘
❓ 常见问题
create-next-app 必须加 --ts --tailwind 等参数吗?src/ 目录有什么好处?一定要用吗?src/ 目录把应用代码(src/)和配置文件(根目录)分开,项目结构更清晰。不是必须的,但本教程推荐使用。不使用也可以,app/ 直接在根目录。npm run dev(开发模式)。如果用的是 npm start,那是生产服务器,需要重新 npm run build。另外 Turbopack 默认只热更新,不整页刷新,修改样式/标签应即时生效。experimental.turbopack: false 回退到 Webpack。但 Next.js 16 官方推荐使用 Turbopack,后续版本可能会移除 Webpack 支持。.vscode/launch.json(调试配置)因人而异,可以不提交。^ 是什么意思?^16.2.0 表示允许 npm install 时安装 16.x.x 范围内的最新小版本(如 16.3.0、16.4.0),但不升级到 17.0.0。~16.2.0 只允许 16.2.x。锁版本用 16.2.0 不加前缀。📖 小节
create-next-app是官方脚手架,一条命令即可创建最佳实践项目- 推荐配置:TypeScript + ESLint + Tailwind + App Router + src/ 目录
src/app/存放路由页面,public/存放静态资源next.config.ts是核心配置文件(图片域名、PPR 开关等)npm run dev使用 Turbopack 热更新,比 Webpack 快 10-50 倍npm run build+npm start是生产环境的构建和启动流程- VS Code 推荐插件:Tailwind CSS IntelliSense、ES7+ React snippets、Prettier
npm run dev是开发专用,npm start必须先 build 再使用
📝 作业
-
基础题(⭐):使用 create-next-app 创建一个名为
my-next-app的新项目(启用 TypeScript + Tailwind + App Router),启动开发服务器,在浏览器打开 localhost:3000 截图首页。 -
进阶题(⭐⭐):在 next.config.ts 中配置 remotePatterns 允许加载
images.unsplash.com的图片,然后在app/page.tsx中使用<Image>组件加载一张 unsplash 图片(宽度 800, 高度 600)。 -
挑战题(⭐⭐⭐):创建
app/about/page.tsx和app/contact/page.tsx两个页面,配置.vscode/settings.json使保存时自动格式化,运行npm run build查看输出中的○和λ符号,解读每个路由的类型。