首页
/ Next.js hello-world 极简示例:用 create-next-app 起步一个最小可用的 App Router 项目

Next.js hello-world 极简示例:用 create-next-app 起步一个最小可用的 App Router 项目

2026-09-06 17:06:20作者:蔡丛锟

Next.js 官方仓库中的 hello-world 示例是整个 examples 集合里最精简的起点,它仅由 App Router 的布局与页面两个文件构成,展示了 Next.js 项目最低限度的目录结构与运行方式。本篇围绕 examples/hello-world/README.md 展开:先完整覆盖其中给出的三种包管理器引导命令,再结合示例目录内的真实文件(app/page.tsxapp/layout.tsxpackage.json)逐一剖析这个"最小工程"到底由哪些部分组成,最后结合 packages/create-next-app 的源码说明 --example 参数在底层是如何把示例仓库拉取并转换成本地项目的。读完本文,你可以独立跑通这个示例、读懂每个配置文件的作用,并知道 create-next-app --example 背后的完整调用链。

一、什么是 hello-world 示例

原文档的定位非常直接:

This is the most minimal starter for your Next.js project.

它自称是 Next.js 项目的"最简起步模板"。从源码结构看,这个"最简"确实名副其实——整个示例目录只包含:

examples/hello-world/
├── app/
│   ├── layout.tsx    # 根布局:声明 <html> 与 <body>
│   └── page.tsx      # 首页:渲染 <h1>Hello, Next.js!</h1>
├── next.config.ts    # 空配置占位
├── package.json      # 依赖与脚本
├── tsconfig.json     # TypeScript 编译选项
└── README.md

没有 public/ 静态资源、没有样式文件、没有额外依赖,是理解 Next.js App Router 项目骨架的最佳入口。

二、用 create-next-app 引导项目(原文档完整命令)

原文档给出的核心操作是通过 create-next-app CLI 以 hello-world 为模板引导新应用。三种包管理器的完整命令如下:

# npm
npx create-next-app --example hello-world hello-world-app

# Yarn
yarn create next-app --example hello-world hello-world-app

# pnpm
pnpm create next-app --example hello-world hello-world-app

其中 --example hello-world 指定使用官方示例集合中的 hello-world 模板,第二个参数 hello-world-app 是本地项目目录名。引导完成后即可在该目录中执行 npm run dev 启动开发服务器。

原文档还提示可以借助 Vercel 将示例一键部署到云端,这里保留该部署思路作为延伸选项,但本地验证只需依赖 Node.js 与任一种包管理器即可。

三、create-next-app 的 --example 是如何工作的

--examplecreate-next-app 提供的能力之一,其 CLI 参数定义见 packages/create-next-app/index.ts

  • -e, --example <example-name|github-url>:指定示例名(官方仓库中的示例)或 GitHub URL,URL 可以指向任意分支和任意子目录;
  • --example-path <path-to-example>:用于 GitHub URL 中分支名含有斜杠(如 bug/fix-1)时,单独指定示例路径以避免解析歧义。

从源码结构看,引导流程的关键调用链位于 packages/create-next-app/create-app.ts

  1. 若传入的 example 是 URL,则用 new URL(example) 解析出仓库地址,再交给 getRepoInfo 提取仓库信息;
  2. 若是裸示例名(如 hello-world),则调用 existsInRepo(example) 校验该示例是否存在于官方示例集合中,不存在时给出拼写提示(源码中对应 Could not locate an example named ... 的报错分支);
  3. 校验通过后执行 downloadAndExtractExample(root, example) 下载并解压示例文件到目标目录,且套用了重试逻辑(retry(...));
  4. 对 TypeScript 示例,还会额外复制 next-env.d.ts 到项目中(源码注释:Copy next-env.d.ts to any example that is typescript)。

示例存在性的校验逻辑在 packages/create-next-app/helpers/examples.ts 中实现:它会请求官方仓库 examples/ 目录的内容列表并检查 package.json 是否可下载,从而确认目标路径确实是一个合法的 Next.js 示例。这意味着 --example hello-world 之所以有效,正是因为当前仓库中确实存在 examples/hello-world/package.json

此外,README 中还列出了若干与示例引导配合常用的参数:--skip-install(跳过依赖安装)、--disable-git(跳过 git 初始化)、--use-npm / --use-pnpm / --use-yarn / --use-bun(显式指定包管理器)、--reset-preferences--yes(偏好控制)。这些参数与 --example 组合使用,可以完全无人值守地批量创建项目。

四、最小工程逐文件解析

app/page.tsx:首页即一个 React 函数组件

examples/hello-world/app/page.tsx 的全部内容:

export default function Page() {
  return <h1>Hello, Next.js!</h1>;
}

在 App Router 中,app/page.tsx 对应根路径 / 的页面。这里没有 export const dynamic、没有数据获取钩子,说明它就是一个静态可预渲染的页面——这也是 Next.js 的默认行为:能静态化的路由默认静态化。

app/layout.tsx:根布局是 App Router 的强制要求

examples/hello-world/app/layout.tsx

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

根布局(root layout)必须提供 <html><body> 标签,children 插槽承载路由页面的输出。该示例没有引入任何 metadata 导出,可见 Next.js 并不强制元数据——但实际项目中建议在此补充 export const metadata 来设置标题与描述。

package.json:三个脚本 + 四个运行时依赖

examples/hello-world/package.json 的关键内容:

{
  "private": true,
  "scripts": {
    "dev": "next dev --turbopack",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "next": "latest",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@types/node": "20.10.8",
    "@types/react": "18.2.47",
    "@types/react-dom": "18.2.18",
    "typescript": "^5.3.3"
  }
}

几个值得注意的细节:

  • private: true 防止示例项目被误发到包仓库;
  • dev 脚本带 --turbopack 标志,即用 Turbopack 作为开发服务器打包器,这是当前仓库中官方示例推荐的开发体验;
  • next 依赖固定为 latest 标签而非具体版本号,因为示例模板的定位是"跟随最新稳定行为",而生产项目应锁定具体版本;
  • React 为 ^18.2.0,类型包版本与之配套,typescript^5.3.3

典型的使用闭环:npm run dev 启动开发模式(热更新 + Turbopack),npm run build 产出 .next 构建产物并执行预渲染,npm run start 在本地以生产模式验证构建结果。

next.config.ts:零配置占位

examples/hello-world/next.config.ts

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  /* config options here */
};

export default nextConfig;

这是一个 TypeScript 类型的空配置占位文件。它印证了最小项目的另一个特征:Next.js 的所有功能(路由、预渲染、图片、字体等)都开箱即用,next.config.ts 只在需要定制(如 rewritesimagesoutput 等)时才需要填充。

tsconfig.json:Next.js 官方模板的编译器选项

examples/hello-world/tsconfig.json 是标准的 Next.js TS 项目配置,几个核心选项:

选项 说明
target es5 最低运行时目标;实际产物由 Next.js 工具链决定,此值主要影响类型检查
strict false 最小示例有意放宽严格模式以降低上手门槛;生产项目建议开启
jsx react-jsx 使用自动 JSX 运行时,无需 import React
moduleResolution node Node 风格模块解析
noEmit / isolatedModules true 编译由 Next.js 接管,TS 仅做类型检查
plugins [{ "name": "next" }] 启用 Next.js 语言服务插件,提供类型化路由提示
include .next/types/**/*.ts 纳入 Next.js 生成的类型文件(如 page.tsx 参数校验类型)

exclude 排除了 node_modules 与测试文件。include 中对 .next/dev/types 的覆盖说明 Next.js 在 dev 与 build 两个模式下都会生成路由级类型定义。

五、从最小示例出发的扩展路径

hello-world 的价值在于"最小可运行",而非功能完备。从该骨架出发,仓库中的示例集合提供了清晰的进阶方向,均可用同样的方式引导:

npx create-next-app --example <example-name> <project-dir>

例如需要 CMS 集成、认证(auth 系列示例)、样式方案(panda-css、with-sass 等)或数据库接入时,替换 --example 参数即可,引导机制与本文第三节的调用链完全一致。而当你需要完全自定义项目结构时,也可以不传 --example,直接使用 create-next-app 的默认模板(TypeScript + Tailwind 为默认选项)。

小结

  • examples/hello-world 是 Next.js 官方仓库中最精简的 App Router 起点:app/layout.tsx + app/page.tsx + 空 next.config.ts 构成可运行的最小工程;
  • 引导命令为 npx create-next-app --example hello-world hello-world-app(或 yarn/pnpm 等价形式),引导完成后 npm run dev / build / start 即构成完整开发生命周期;
  • packages/create-next-app 源码可确认,--example 会校验示例在官方仓库中的存在性,再下载、解压示例文件并对 TS 项目补齐 next-env.d.ts,整个过程带重试与拼写纠错提示;
  • 理解了这个最小骨架与引导机制后,即可按第三节所述参数灵活组合 create-next-app,或以 --example 切换到集合中任何更复杂的官方示例继续扩展。
登录后查看全文
热门项目推荐
相关项目推荐