Next.js 项目搭建
这一篇把项目从零拉起来:向导怎么选、目录各自干什么、日常三条命令,以及初始化时经常碰到的三个概念。
创建项目
官方要求 Node.js ≥ 20.9。用最新脚手架:
npx create-next-app@latest
bash
向导会问一串问题。没有标准答案,按项目需要选即可。下面是一份常见的「自学 / 正式项目」组合,方便对照:
| 问题 | 常见选择 | 说明 |
|---|---|---|
| 项目名 | my-app | 必填 |
| 是否用推荐默认值 | 自定义 | 想看清每一项时选 No |
| TypeScript | Yes | 类型能拦住不少低级错误 |
| Linter | ESLint 或 None | 个人练习可以先关掉 |
| React Compiler | Yes | 让编译器帮你做 memo 一类优化 |
| Tailwind CSS | Yes | 和本站一样,写样式更快 |
src/ 目录 | Yes | 源码和配置分开 |
| App Router | Yes | 当前官方默认 |
| Turbopack | Yes | 开发时热更新更快 |
| 导入别名 | @/* | 默认就够用 |
选完后脚手架会装依赖。进目录跑 pnpm dev,打开 http://localhost:3000。
目录结构
以 src/app + TypeScript + Tailwind 为例:
public/ 静态资源,URL 从 / 开始
src/
└─ app/ App Router 约定目录
layout.tsx 根布局,必须有 <html> 和 <body>
page.tsx 首页,对应 /
globals.css 全局样式
next-env.d.ts Next 生成的类型声明,不要手改
next.config.ts 框架配置
tsconfig.json TypeScript
postcss.config.mjs 给 Tailwind 用
package.json
README.md
text
layout.tsx 是整站外壳,导航、字体、全局 CSS 通常放这里。page.tsx 只负责这一条路由的内容。
常用命令
pnpm dev # next dev,开发服务器
pnpm build # next build,生产构建
pnpm start # next start,跑构建产物
bash
开发看 dev,上线前必须能过 build。
Turbopack
Turbopack 是 Next 用来替换 webpack 的打包器,核心用 Rust,转译 JS/TS 走 SWC。开发模式下增量编译:改过的模块重算,没改过的尽量走缓存,所以热更新通常比 webpack 快一截。
create-next-app 勾选 Turbopack 后,next dev 默认就是它。生产构建是否走 Turbopack 以你当前 Next 版本说明为准。
React Compiler
以前要手写 useMemo、useCallback、memo 才能少重渲染。React Compiler 在编译期分析组件,自动插入等价优化,心智负担小很多。
脚手架里选了 Yes,一般不用再装插件。事后补开可以:
// next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
reactCompiler: true,
};
export default nextConfig;
ts
没在向导里勾选时,按当前 Next 版本装对应的 compiler 插件即可。
App Router 和 Pages Router
Next 现在有两套路由:
- Pages Router:
pages/index.tsx→/,pages/about.tsx→/about。组件不能随便丢进pages/,否则会变成路由。取数靠getServerSideProps/getStaticProps。 - App Router:
app目录按约定映射。page.tsx才是页面,同级可以放layout.tsx、loading.tsx、error.tsx。服务端组件里可以直接await fetch(...)。
Pages Router 取数:
export async function getServerSideProps() {
const res = await fetch("https://example.com/api");
const data = await res.json();
return { props: { data } };
}
export default function Home({ data }: { data: { name: string } }) {
return <div>{data.name}</div>;
}
tsx
App Router 取数:
export default async function Home() {
const res = await fetch("https://example.com/api");
const data = await res.json();
return <div>{data.name}</div>;
}
tsx
本笔记后面默认 App Router。新项目没有历史包袱时,不要再开 Pages Router。
下一篇从文件系统路由开始:page、layout、loading、error、not-found。