Next.js 项目搭建

2026年9月6日

这一篇把项目从零拉起来:向导怎么选、目录各自干什么、日常三条命令,以及初始化时经常碰到的三个概念。


创建项目

官方要求 Node.js ≥ 20.9。用最新脚手架:

npx create-next-app@latest
bash

向导会问一串问题。没有标准答案,按项目需要选即可。下面是一份常见的「自学 / 正式项目」组合,方便对照:

问题常见选择说明
项目名my-app必填
是否用推荐默认值自定义想看清每一项时选 No
TypeScriptYes类型能拦住不少低级错误
LinterESLint 或 None个人练习可以先关掉
React CompilerYes让编译器帮你做 memo 一类优化
Tailwind CSSYes和本站一样,写样式更快
src/ 目录Yes源码和配置分开
App RouterYes当前官方默认
TurbopackYes开发时热更新更快
导入别名@/*默认就够用

选完后脚手架会装依赖。进目录跑 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

以前要手写 useMemouseCallbackmemo 才能少重渲染。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 Routerpages/index.tsx/pages/about.tsx/about。组件不能随便丢进 pages/,否则会变成路由。取数靠 getServerSideProps / getStaticProps
  • App Routerapp 目录按约定映射。page.tsx 才是页面,同级可以放 layout.tsxloading.tsxerror.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。

下一篇从文件系统路由开始:pagelayoutloadingerrornot-found


参考文档