nextjs 总体架构概览

142 阅读11分钟

项目性质

这是 Next.js 官方仓库/单体仓库(monorepo),不是一个单独的业务项目,而是「Next.js 框架本身 + CLI + 文档 + 示例 + 测试 + Rust 编译器(SWC/Turbopack)」的整体工程。

image.png

包管理 & 构建:

包管理:pnpm + workspaces 管理多包(packages/*)。

多包管理:lerna 用来跑子包脚本、清理构建产物等。

任务编排:turbo(turbo.json)负责并行/缓存构建、测试、lint 等。

技术栈:TypeScript + React 19 canary 版本 + Node.js 后端工具链 + Rust(SWC、Turbopack、Next core 等)。

核心子项目位置:

packages/next:Next.js 核心实现。

packages/create-next-app:create-next-app 脚手架工具。

packages/eslint-config-next / eslint-plugin-next 等:官方 ESLint 配置和插件。

apps/、examples/、test/:各种 demo、benchmark、示例项目和测试用项目。

crates/、turbopack/、rspack/:Rust 层面的编译/打包工具相关代码。

顶层目录说明(根目录下最重要的文件夹)

  • apps/

    • 包含一些实际运行的 app,用于演示框架功能或工具 UI。
    • 例如:apps/bundle-analyzer/ 是 bundle 分析工具的 UI 应用;apps/docs/ 是文档站点相关代码。
  • bench/

    • 各种性能 benchmark 工程,比如 app-router-server、rendering 等,用来测试、比较不同场景下的性能和体积。
  • crates/

    • Rust crate 集合,是 Next.js 低层能力(如构建、转换、API 服务器等)的实现。
    • 如:next-core/、next-api/、next-build/、next-custom-transforms/ 等。
  • docs/

    • 官方文档的源码(大量 .mdx),按 App Router / Pages Router / architecture 等分目录。
  • errors/

    • 维护各种错误码和对应的文档页面(.mdx),与 packages/next 的错误处理逻辑配合。
  • examples/

    • 各种 Next.js 示例项目(国际化、SSR、App Router、集成各种后端/数据库/第三方服务等),用于模板和测试。
  • packages/

    • monorepo 的核心:
      • packages/next:Next.js 框架核心。
      • packages/create-next-app:脚手架。
      • packages/next-bundle-analyzer、next-mdx、next-env、next-swc 等:官方插件、工具、polyfill、编译插件。
      • ESLint 相关、Routing 工具、第三方集成等都在这里。
  • patches/

    • pnpm 的 patchedDependencies 对应的补丁文件,对第三方依赖做小修改(用于临时修 bug 或定制行为)。
  • rspack/

    • 与 Rspack 集成相关的子工程(Rust + JS),包括它自己的 package.json、pnpm-workspace.yaml 等,用于打包器适配/实验。
  • scripts/

    • Node/TS/SH 脚本集合,用于:构建、打包、发布、检查预编译文件、生成 release 日志、同步 React、检查 examples、部署文档等。
  • test/

    • 超多自动化测试工程:unit/integration/e2e 测试,覆盖 packages/next 的各种场景。 tsconfig.json 里 paths、include 很多都是为这里服务。
  • turbopack/

    • Turbopack 本身的仓库部分:Rust crates、JS 包、基准项目等,是新一代打包器相关代码。
  • 其他目录:

    • contributing/:贡献指南的细分文档。
    • turb o/:和 turbo 生成器等相关的小工具。
    • test-config-errors/:专门用来测试错误配置行为的项目。
    • apps/docs、apps/bundle-analyzer 下又都有独立的 tsconfig/next.config 等本地配置。

根目录关键文件说明

  • package.json
    • monorepo 顶层 package.json。
    • 定义:
    • workspaces: ["packages/*"] → 将 packages/ 下所有包纳入 workspace。
    • 各种 scripts:dev / build / test-* / lint-* / next / next-with-deps / 发布相关脚本等,大多数通过 turbo、lerna、jest、tsc、eslint 等联动整个仓库。
    • devDependencies:几乎所有开发相关依赖,包括 React 19 canary、jest、eslint、playwright、tailwind、next 自己的 workspace 包等。
    • pnpm 字段:统一 overrides、patchedDependencies,锁定依赖版本并应用补丁。

可以理解为:这个仓库的一切开发流程都从这里的脚本起步。

  • tsconfig.json

    • 仓库级 TypeScript 配置,用于测试和脚本:
    • compilerOptions:noEmit、allowJs、esModuleInterop、jsx: react-jsx、types: ["react","jest","node"...] 等。
    • paths:给测试工具库(test/lib 下的若干工具)做别名,如 next-test-utils、e2e-utils 等。
    • include:主要包含 test//*.test.ts(x)、scripts//.ts|js、turbo/**/.ts。 对你来说:如果想在仓库里加 TS 脚本/测试,最好遵守这个配置。
  • tsconfig-tsec.json / tsec-exemptions.json

    • 与 tsec 安全类型检查有关:用来做额外的类型安全验证,以及标记豁免规则。
  • pnpm-lock.yaml / pnpm-workspace.yaml

    • pnpm-lock.yaml:锁定整个 monorepo 的依赖树。
    • pnpm-workspace.yaml:定义 workspace 范围(哪些文件夹算一个 workspace 包),确保整体依赖/脚本一致管理。
  • turbo.json

    • Turborepo 配置文件,定义 build / test / lint 等 pipeline、缓存策略、依赖关系。
  • eslint.config.mjs / eslint.cli.config.mjs

    • 新版 Flat 配置的 ESLint 主配置 & CLI 使用入口。
    • 定义哪些文件跑哪些规则、使用哪些插件(比如 eslint-plugin-next)等。
  • jest.config.js / jest.config.turbopack.js

    • Jest 单元测试配置:一个是普通 webpack 测试,一个是 Turbopack 相关测试。
    • 决定测试环境、匹配文件后缀、mock 等。
  • lint-staged.config.js

    • 与 husky 钩子配合,指定 git 提交前对暂存文件做哪些检查(prettier、eslint 等)。
  • lerna.json

    • lerna 的多包配置,项目内某些脚本会通过 lerna run 在所有包里运行某项任务(如 types、clean)。
  • vercel.json

    • 用于部署到 Vercel 时的一些全局配置(路由、构建设置等),针对整个仓库文档/站点的部署。
  • Rust 相关:Cargo.toml / Cargo.lock / rust-toolchain.toml

    • 定义 Rust workspace(主要围绕 crates/、turbopack/ 等),以及使用的 Rust toolchain 版本。

如果你需要编译本地的 SWC/Turbopack/Next 核心,就会用到这些文件。

  • 文档 & 规范类

    • readme.md:仓库总览 & 快速开始。
    • UPGRADING.md:升级相关说明。
    • CODE_OF_CONDUCT.md:行为规范。
    • contributing.md + contributing/:贡献指南细节。
    • license.md:开源协议。
  • CI / 工具配置

    • sgconfig.yml、socket.yaml:内部工具 / 监控 / 代码搜索等平台的配置(视 Next 团队内部工具而定)。
    • run-tests.js:辅助按分片、带统计地跑测试。
  • 其他杂项

    • test-config-errors/next.config.js:专门用于「错误配置」场景的测试。
    • test-file.txt:简单的测试文件。

packages

packages/ 是整个 monorepo 的「核心代码区」,里面每个子文件夹基本就是一个独立 npm 包,对外发布时会以 next、create-next-app 等包名存在,职责大致分为:框架本体、脚手架、ESLint 配置/插件、路由与打包集成、polyfill、字体/第三方集成、开发辅助工具 等。

packages 下各子文件夹作用

  • create-next-app/

    • 对应 npm 包:create-next-app。
    • 就是你平时 npx create-next-app 用到的脚手架代码,负责交互式创建新项目、模板选择、初始化依赖等。
  • eslint-config-next/

    • 对应 npm 包:eslint-config-next。
    • 封装官方推荐的 ESLint 配置,业务项目里 "extends": "next/core-web-vitals" 等就是用的这里的配置。
  • eslint-plugin-internal/

    • 内部使用的 ESLint 插件,主要是约束 Next.js 仓库自身的代码风格/规范,不是给普通用户直接用的。
  • eslint-plugin-next/

    • 对应 npm 包:eslint-plugin-next。
    • Next.js 专用 ESLint 规则:比如限制在 pages/ 里怎么写数据获取、next/link 的使用规范、Image 使用提示等等。
  • font/

    • 对应 npm 包:@next/font(以及相关实现)。
    • 实现 Next.js 的字体加载功能(早期的 @next/font、后来的 next/font),包括 Google Fonts、本地字体优化等。
  • next/

    • 对应 npm 包:next,框架的核心代码。
    • 包含:
      • 编译/打包(调用 SWC / webpack / Turbopack)的 JS 部分逻辑;
      • App Router & Pages Router 运行时代码;
      • next dev、next build、next start CLI 入口;
      • next/link、next/router、next/image、next/head 等核心组件/工具。

如果想深入了解 Next.js 的内部实现,这个目录是重点。

  • next-bundle-analyzer/

    • 对应 npm 包:@next/bundle-analyzer。
    • 提供 bundle 分析功能的插件(本质是对 webpack-bundle-analyzer 的封装),开发者在项目中配置后可查看构建体积分析报告。
  • next-codemod/

    • 对应 npm 包:next-codemod。
    • 一堆自动代码迁移脚本(codemod),用来帮助你从旧版本 Next.js 升级到新版本,自动做 API 迁移、文件结构调整等。
  • next-env/

    • 对应 npm 包:next-env。
    • 主要是一些类型声明/环境注入逻辑,配合 next-env.d.ts 使用,确保 TypeScript 项目里自动注入 Next 环境类型。
  • next-mdx/

    • 对应 npm 包:@next/mdx。
    • 提供 Next.js 官方 MDX 支持(集成 @mdx-js/*),让你可以在 Next 项目中写 .mdx 页面/组件。
  • next-plugin-storybook/

    • 对应 npm 包:@next/plugin-storybook。
    • Next.js 和 Storybook 集成的官方插件,用于在 Next 项目中顺畅地跑 Storybook,处理 webpack/打包配置等。
  • next-polyfill-module/

    • 对应 npm 包:@next/polyfill-module。
    • 提供给现代浏览器(ES module 模式)使用的一套 polyfill,保证在不支持某些新特性的浏览器上也能正常运行。
  • next-routing/

    • 与路由系统相关的工具包,用于抽象和复用 Next.js 路由逻辑(包含 App Router / Pages Router 的底层路由构建、匹配工具等)。
    • 更多是内部复用/拆分出来的模块,不是普通用户常直接依赖的。
  • next-rspack/

    • 与 Rspack 集成的适配包(Next + Rspack 的桥接层)。
    • 提供在 Next.js 中使用 Rspack 作为打包器所需的一些 glue code / 配置。
  • next-swc/

    • 对应 npm 包:@next/swc。
    • SWC 编译器在 Next.js 中的封装:JS 调用层、native 模块加载、平台差异处理等。
    • 配合 crates/ 里 Rust 实现一起工作,是 Next 编译和转译 TypeScript/JSX 的关键部分。
  • react-refresh-utils/

    • 对应的是 React Refresh(HMR 热更新)相关的工具包。
    • 封装了在 Next dev 模式下使用 React Fast Refresh 所需的工具/适配逻辑。
  • third-parties/

    • 对应 npm 包:@next/third-parties。
    • 提供常见第三方服务的集成组件/工具,比如分析脚本、广告、外部 SDK 等,统一封装成 Next-friendly 的用法。

总结

  • 想知道「Next.js 核心」:重点看 packages/next + packages/next-swc。
  • 想学「脚手架 & 项目创建」:看 packages/create-next-app。
  • 想看「升级工具 / 重构脚本」:看 packages/next-codemod。
  • 关心「Lint & 代码规范」:看 eslint-config-next + eslint-plugin-next + eslint-plugin-internal。
  • 关心「生态集成」:看 font、next-mdx、next-plugin-storybook、third-parties 等。

packages/next 核心作用

这是 Next.js 框架的核心包,对应 npm 包 next。包含:

  • CLI 入口(next dev、next build、next start)
  • 编译与构建(webpack/Turbopack/Rspack)
  • 运行时(App Router、Pages Router)
  • 核心组件与 API(next/link、next/image、next/router 等)
  • 服务器端渲染与路由
  • 开发工具(HMR、错误覆盖层等)

packages/next 目录结构详解

src/build/ — 构建系统

负责编译、打包、代码生成:

  • webpack/ → webpack 配置、plugins、loaders
    • webpack-config.ts → 主配置
    • plugins/ → 自定义插件(如 pages-manifest-plugin.ts、build-manifest-plugin.ts)
    • loaders/ → 自定义 loader(如 next-swc-loader.ts、next-flight-loader.ts)
  • turbopack-build/ → Turbopack 构建集成
  • babel/ → Babel 配置与插件(兼容/降级)
  • swc/ → SWC 编译器集成(调用 @next/swc)
  • entries.ts → 收集入口点(pages、app routes)
  • templates/ → 生成运行时模板(如 app-page.ts、pages.ts)
  • static-paths/ → 静态路径生成(getStaticPaths)
  • analysis/ → 静态分析(判断页面是否为静态)
  • compiler.ts → 编译器抽象层(统一 webpack/Turbopack)

src/server/ — 服务器运行时

处理请求、路由、渲染:

  • next-server.ts / base-server.ts → 服务器基类
  • next-dev-server.ts → 开发服务器(HMR、错误覆盖层)
  • app-render/ → App Router 渲染(React Server Components)
  • route-matchers/ → 路由匹配
  • route-modules/ → 路由模块加载
  • render.tsx → 页面渲染入口
  • image-optimizer.ts → 图片优化
  • dev/ → 开发工具(HMR、错误处理)
  • lib/ → 服务器工具函数
  • web/ → Web 标准 API 适配(Edge Runtime)
  • request/ → 请求处理
  • response-cache/ → 响应缓存(ISR)
  • normalizers/ → 路径规范化(国际化、前缀等)

src/client/ — 客户端运行时 浏览器端代码:

  • router.ts → Pages Router 客户端路由
  • components/ → 客户端组件
  • app-router.tsx → App Router 客户端入口
  • navigation.ts → App Router 导航(useRouter、usePathname)
  • router-reducer/ → 路由状态管理(类似 Redux reducer)
  • layout-router.tsx → Layout 路由处理
  • link.tsx → <Link> 组件实现
  • image-component.tsx → <Image> 组件实现
  • dev/ → 开发工具(错误覆盖层、HMR 客户端)
  • app-dir/ → App Router 客户端代码
  • page-loader.ts → 页面加载器(代码分割)

核心工作流程

开发模式(next dev)

  1. src/bin/next.ts 解析命令 → src/cli/next-dev.ts
  2. 创建 src/server/dev/next-dev-server.ts
  3. 启动编译:src/build/compiler.ts(webpack/Turbopack)
  4. 监听文件变化,触发 HMR
  5. 请求到达 → src/server/next-server.ts 处理路由
  6. 渲染:App Router → src/server/app-render/,Pages Router → src/server/render.tsx

构建模式(next build)

  • src/cli/next-build.ts 启动构建
  • src/build/entries.ts 收集所有入口
  • src/build/compiler.ts 编译(webpack/Turbopack)
  • src/build/analysis/ 分析静态性
  • src/build/static-paths/ 生成静态路径
  • 生成 manifest、路由映射等
  • 输出到 .next/

生产模式(next start)

  • src/cli/next-start.ts 启动生产服务器
  • src/server/next-server.ts 加载构建产物
  • 处理请求 → 路由匹配 → 渲染 → 返回 HTML

关键设计模式

  1. 模块化:按功能拆分(build、server、client、shared)
  2. 抽象层:compiler.ts 统一 webpack/Turbopack
  3. 代码分割:客户端按路由懒加载
  4. 类型安全:TypeScript 覆盖主要代码
  5. 平台适配:Node.js 与 Edge Runtime 分别处理

packages/next 总结

packages/next 是 Next.js 的核心实现,包含:

  1. CLI 入口与命令处理
  2. 构建系统(webpack/Turbopack/Rspack)
  3. 服务器运行时(SSR、路由、渲染)
  4. 客户端运行时(路由、组件、HMR)
  5. 公共 API(Link、Image、Router 等)
  6. 工具库(配置查找、类型检查、元数据处理)

next dev 之后会发生什么

  • 本地执行 next dev 会经历什么?

    • 启动 next CLI → 加载 next.config.js 等配置 → 决定用 webpack / Turbopack / Rspack 哪个打包器 → 启动 NextDevServer → 监听文件变化、做增量编译和 HMR → 每次请求时由服务器按路由渲染页面(App Router / Pages Router)。
  • 会不会经过 next-swc?

    • 会,几乎一定会。
    • 无论是 webpack 还是 Turbopack,Next 都默认用 SWC(@next/swc / next-swc)来编译 TS/JS/JSX/TSX 和 RSC 相关代码,Babel 只在你显式配置 .babelrc 或特殊场景下才会介入。
  • 如果用户在 next.config.js 里配置了 webpack 钩子,会不会还走 SWC / Turbopack?

    • 只要当前模式选的是 webpack 作为打包器:

      • JS/TS 仍然由 SWC 负责编译(通过 Next 内部配置好的 loader),你自定义的 webpack(config){...} 只是修改 webpack 配置(loader、plugin 等),不会把 SWC “关掉”。
    • 如果当前选的是 Turbopack:

      • 不会走 webpack(config) 这个钩子,因为那是 webpack 专用;
      • Turbopack 自己内部同样是基于 Rust/SWC 技术栈,但是暴露的配置面不再是 webpack(config),而是 experimental.turbo 等配置。

总结成一句话

  • next dev 一定会走到 Next 自己的 dev server 和构建系统,JS/TS 几乎总是通过 SWC(next-swc)来编译;

  • 你在 next.config.js 里写的 webpack 钩子,只在“选择了 webpack 作为打包器”的情况下生效,它会修改 webpack 配置,但不会关掉 SWC;

  • 如果启用 Turbopack,则不会再走 webpack(config) 这条路径,但 Turbopack 内部同样是基于 Rust/SWC 的编译链路。