Table of contents
Open Table of contents
1. 先建立分层思维
把开发 Web 应用类比为开餐厅:
| 技术层 | 生活化类比 | 代表概念 |
|---|---|---|
| 语言 | 厨师书写菜谱、交流做法的语言 | JavaScript、TypeScript |
| 运行时 | 真正可以点火做饭的厨房 | 浏览器运行时、Node.js |
| 软件包仓库 | 食材和厨具供应商的总仓库 | npm Registry |
| 包管理器 | 采购、核对和管理食材的系统 | npm、pnpm、Yarn |
| 项目清单 | 餐厅的采购单和基础资料 | package.json |
| 库 | 可按需使用的厨具或半成品 | React |
| 构建工具 | 洗切、备菜、打包的流水线 | Vite |
| 框架 | 餐厅整体分工、动线和工作规范 | Next.js、Express、NestJS |
| 应用 | 最终交付给顾客的餐厅 | 网站、后台系统、AI 产品 |
这些概念不处在同一层,不能简单地互相替代。例如,Node.js 不能替代 JavaScript,React 也不能替代 npm。
2. 最常用的关联关系
技术概念之间最常见的关系,可以归纳成下面六类:
| 关系 | 含义 | 示例 |
|---|---|---|
| 运行于 | 某段程序需要特定运行时执行 | JavaScript 运行于浏览器或 Node.js |
| 编译/转换为 | 开发时的源码被转换成可执行代码 | TypeScript 转换为 JavaScript |
| 安装自 | 包管理器从软件包仓库获取依赖 | pnpm 从 npm Registry 安装 React |
| 记录/管理 | 配置文件或工具维护依赖信息 | package.json 记录项目依赖 |
| 基于/封装 | 上层工具建立在下层能力之上 | Next.js 基于 React,并使用 Node.js 服务端能力 |
| 配合使用 | 两者职责互补,但不存在必然从属 | React 可以配合 Vite 构建前端应用 |
2.1 生态总关系图
flowchart TB
TS["TypeScript<br/>带静态类型的语言"] -->|"转换为"| JS["JavaScript<br/>Web 基础语言"]
JS -->|"运行于"| Browser["浏览器运行时<br/>DOM / Web API"]
JS -->|"运行于"| Node["Node.js<br/>服务端与工具运行时"]
Registry["npm Registry<br/>软件包仓库"] -->|"提供软件包"| PM["包管理器<br/>npm / pnpm / Yarn"]
Package["package.json<br/>项目清单"] -->|"告诉包管理器<br/>需要哪些依赖"| PM
PM -->|"安装"| Dependencies["项目依赖<br/>React / Vite / Next.js 等"]
React["React<br/>UI 库"] -->|"可配合"| Vite["Vite<br/>开发与构建工具"]
React -->|"被封装和扩展"| Next["Next.js<br/>React 全栈框架"]
Node -->|"承载服务端能力"| Next
Node -->|"承载"| Express["Express<br/>轻量 Web 框架"]
Node -->|"承载"| Nest["NestJS<br/>结构化后端框架"]
Next -->|"构建"| Fullstack["全栈 Web 应用"]
Vite -->|"常用于构建"| Frontend["浏览器端应用"]
Express -->|"常用于构建"| API["API / Web 服务器"]
Nest -->|"常用于构建"| Backend["大型结构化后端"]读图时要注意:箭头表达的是职责关系,不是“谁更高级”。越靠上层的工具通常集成越多,但也会带来更多约定。
3. 核心概念逐个理解
3.1 JavaScript
是什么
- 一门动态类型编程语言。
- Web 浏览器原生支持的核心编程语言。
- 也可以在 Node.js 等浏览器之外的运行时中执行。
不是什么
- 不是浏览器。
- 不是 Node.js。
- 不是只用于网页动画的脚本工具。
解决什么问题
- 表达程序逻辑。
- 响应用户操作、处理数据、调用网络服务。
- 同时支持浏览器端和服务端开发。
与其他概念的关系
- TypeScript 建立在 JavaScript 之上。
- 浏览器和 Node.js 都能执行 JavaScript,但提供的外部能力不同。
- React、Vite、Next.js 等生态工具主要由 JavaScript 或 TypeScript 构建。
3.2 TypeScript
是什么
- JavaScript 的超集:合法的 JavaScript 基本上也是合法的 TypeScript。
- 为 JavaScript 增加静态类型检查和开发工具支持。
不是什么
- 通常不是浏览器直接执行的最终代码。
- 不是独立的浏览器或服务器运行时。
- 不能替代运行时的数据校验。
解决什么问题
- 在运行前发现一部分类型错误。
- 让编辑器提供更可靠的补全、跳转和重构能力。
- 提升中大型项目的可读性和可维护性。
与其他概念的关系
flowchart LR
Source["开发者编写<br/>TypeScript"] --> Check["类型检查"]
Check --> Transform["移除类型并转换"]
Transform --> Output["JavaScript"]
Output --> Runtime["浏览器或 Node.js 执行"]function greet(name: string): string {
return `Hello, ${name}`;
}
其中 : string 是类型信息。通常在构建阶段被移除,运行时主要执行生成的 JavaScript。
TypeScript 只能检查开发阶段已知的类型。用户输入、API 返回值和数据库数据仍需要 运行时验证,常见方案包括手写校验或使用 Zod 等库。
3.3 浏览器运行时
是什么
- 浏览器提供的 JavaScript 执行环境。
- 除 JavaScript 引擎外,还提供 DOM、事件、网络请求、存储等 Web API。
不是什么
- 不是 JavaScript 语言本身。
- 不是 Node.js。
- 一般不能像 Node.js 服务端程序那样任意访问本机文件和系统资源。
解决什么问题
- 把代码变成交互式网页。
- 让程序操作页面、响应用户输入、请求服务器数据。
与其他概念的关系
- React 组件最终可在浏览器中形成并更新用户界面。
- Next.js 应用的一部分代码在浏览器执行,另一部分可能在服务器执行。
- 浏览器端代码必须遵守浏览器安全模型。
3.4 Node.js
是什么
- 浏览器之外的 JavaScript 运行时。
- 提供文件系统、进程、网络服务器等服务端和本地工具能力。
不是什么
- 不是编程语言。
- 不是包管理器;虽然安装 Node.js 时经常同时安装 npm。
- 不是 Express、NestJS 或 Next.js。
解决什么问题
- 使用 JavaScript 编写服务器、命令行脚本和开发工具。
- 为 Vite、Next.js、TypeScript 编译器等开发流程提供运行环境。
与其他概念的关系
- Express 和 NestJS 运行在 Node.js 之上。
- Next.js 的服务端能力通常需要兼容的服务端运行环境;具体部署时也可能使用其他受支持的运行时。
- npm、pnpm、Yarn 等包管理器通常与 Node.js 项目一起使用。
3.5 npm、pnpm 与 Yarn
是什么
- 三种包管理器,用于安装、更新、移除和发布软件包。
- 它们也负责执行
package.json中定义的脚本。
不是什么
- 不是前端框架。
- 不等于 npm Registry。
- 不负责替你设计应用架构。
解决什么问题
- 管理项目依赖及其版本。
- 生成锁文件,使不同机器尽可能安装相同版本的依赖。
- 支持多包仓库或工作区管理。
与其他概念的关系
sequenceDiagram
participant Dev as 开发者
participant PM as npm / pnpm / Yarn
participant PJ as package.json
participant R as npm Registry
participant Local as 本地依赖
Dev->>PM: 请求安装 React
PM->>R: 查询软件包和版本
R-->>PM: 返回包及元数据
PM->>Local: 安装或链接依赖
PM->>PJ: 记录依赖声明
PM->>PM: 更新对应锁文件常见锁文件:
- npm:
package-lock.json - pnpm:
pnpm-lock.yaml - Yarn:
yarn.lock
一个项目通常统一使用一种包管理器并提交对应锁文件。随意混用会增加依赖版本不一致的风险。
3.6 npm Registry
是什么
- 托管和分发 JavaScript 软件包的注册表服务。
- 默认情况下,npm、pnpm 和 Yarn 都可以从它获取公开软件包。
不是什么
- 不是安装在电脑上的 npm 命令。
- 不是 GitHub;GitHub 主要托管源码和协作记录,Registry 主要分发可安装的软件包。
解决什么问题
- 统一发布、查找、下载和版本化软件包。
与其他概念的关系
- React、Vite、Next.js 等通常以软件包形式发布到 Registry。
- 包管理器按照
package.json和锁文件确定需要下载的内容。
3.7 package.json
是什么
- Node.js/JavaScript 项目的项目清单文件。
- 使用 JSON 描述项目名称、版本、命令、依赖和部分工具配置。
不是什么
- 不是应用的固定入口文件。
- 不保存软件包的实际源码。
- 不能保证所有依赖都已经安装。
解决什么问题
- 让工具和协作者知道项目是什么、需要什么、可以执行哪些命令。
与其他概念的关系
{
"scripts": {
"dev": "next dev",
"build": "next build"
},
"dependencies": {
"next": "<具体版本>",
"react": "<具体版本>"
}
}
dependencies表示应用运行通常需要的依赖。devDependencies表示主要用于开发、测试或构建的依赖。scripts给常用命令设置统一名称。- 精确安装结果主要由包管理器的锁文件记录。
3.8 React
是什么
- 使用组件声明用户界面的 JavaScript 库。
- 组件把界面结构、状态和交互逻辑组织成可组合单元。
不是什么
- 不是完整的全栈框架。
- 不独自规定项目必须如何路由、构建、访问数据库或部署。
- 不是浏览器运行时。
解决什么问题
- 把复杂界面拆成可复用组件。
- 根据状态变化更新界面。
- 统一组织页面中的交互逻辑。
与其他概念的关系
- React 可以与 Vite 配合,构建以浏览器端为主的应用。
- Next.js 建立在 React 之上,补充路由、渲染、服务端和构建约定。
3.9 Vite
是什么
- 前端开发服务器与构建工具。
- 在开发阶段提供快速启动和模块热更新,在生产阶段完成构建。
不是什么
- 不是 React。
- 不是像 Next.js 那样的完整全栈框架。
- 不直接替你提供完整的业务后端。
解决什么问题
- 提高前端项目的开发反馈速度。
- 将源码和资源处理为适合部署的产物。
与其他概念的关系
- 常见组合是
React + Vite。 - Next.js 自带自己的开发、构建和生产约定,一般不再用 Vite 作为主要构建入口。
3.10 Next.js
是什么
- 建立在 React 之上的全栈 Web 框架。
- 提供文件系统路由、不同渲染方式、服务端逻辑、构建和部署约定。
不是什么
- 不是新的编程语言。
- 不只是 React 的打包工具。
- 使用 Next.js 不代表应用必然是单体,也不代表必须前后端分离。
解决什么问题
- 把 React 界面、路由、服务端能力和构建流程组织在同一个项目中。
- 减少开发完整 Web 产品时自行选型和拼装工具的工作量。
与其他概念的关系
- 使用 React 构建界面。
- 通常使用 JavaScript 或 TypeScript 开发。
- 开发工具和服务端部分通常依赖 Node.js 或其他受支持运行时。
- 可以直接访问数据库,也可以调用 Express、NestJS 或第三方 API。
3.11 Express
是什么
- Node.js 上轻量、灵活的 Web 服务端框架。
- 主要围绕 HTTP 路由、中间件、请求和响应工作。
不是什么
- 不是前端 UI 框架。
- 不是数据库。
- 不像 NestJS 那样默认提供强约束的整体工程结构。
解决什么问题
- 快速创建 API 和 Web 服务器。
- 让开发者自由组合中间件和项目结构。
与其他概念的关系
- 运行在 Node.js 上。
- 可以作为 Next.js 前端背后的独立 API 服务,但简单项目不一定需要额外引入。
3.12 NestJS
是什么
- 面向 Node.js 服务端的结构化框架。
- 强调模块、控制器、服务、依赖注入和可测试性。
不是什么
- 不是 React 或 Next.js 的替代品,因为主要职责是后端。
- 不是 Node.js 本身。
- 不是只能用于微服务;它同样可以构建模块化单体后端。
解决什么问题
- 为复杂后端提供统一的组织方式。
- 降低大型团队中代码结构不一致的问题。
与其他概念的关系
- 通常运行在 Node.js 上。
- 可以为 Next.js、React/Vite 前端提供独立 API。
- 底层 HTTP 平台常见选择包括 Express 或 Fastify;具体支持情况可能随版本变化。
4. 两种最常见的应用组合
4.1 React + Vite:以前端为中心
flowchart LR
User["用户"] --> Browser["浏览器"]
Browser --> UI["React 应用"]
Vite["Vite"] -->|"开发与构建"| UI
UI -->|"HTTP 请求"| API["独立 API<br/>Express / NestJS / 云服务"]
API --> DB[("数据库")]适合:
- 纯前端应用。
- 已经存在独立后端 API。
- 前后端由不同团队或系统管理。
4.2 Next.js:全栈单体起步
flowchart LR
User["用户"] --> Browser["浏览器"]
Browser --> Route["Next.js 路由"]
Route --> UI["React 页面与组件"]
Route --> Server["服务端逻辑"]
Server --> DB[("数据库")]
Server --> AI["AI 服务"]
Server --> External["第三方 API"]适合:
- 一个人或小团队快速验证产品。
- 页面与服务端逻辑关系紧密。
- 希望在一个项目中共享类型、验证规则和业务模块。
- AI 辅助编程时,希望减少仓库和技术栈切换。
5. Next.js 全栈单体应用中的请求路径
下面以“用户在 AI 应用里提交问题”为例:
sequenceDiagram
actor User as 用户
participant Client as 浏览器中的 React 组件
participant Next as Next.js 服务端
participant Auth as 身份验证
participant DB as 数据库
participant AI as AI 服务
User->>Client: 输入问题并提交
Client->>Next: 发送请求
Next->>Auth: 检查登录状态和权限
Auth-->>Next: 返回用户身份
Next->>DB: 读取上下文或额度
DB-->>Next: 返回数据
Next->>AI: 携带必要上下文调用模型
AI-->>Next: 返回生成结果
Next->>DB: 保存对话或用量
Next-->>Client: 返回结果
Client-->>User: 更新界面从这条路径可以看出:
- React 组件主要负责交互和显示。
- Next.js 服务端负责保护密钥、鉴权和协调业务流程。
- 数据库负责持久化,不属于 Next.js 本身。
- AI 服务通常是外部依赖,也可能是自托管模型服务。
- 不应把服务端密钥直接放进浏览器代码。
6. 单体应用不等于“所有代码堆在一起”
单体描述的是应用的主要组织和部署边界,不代表内部不能分层或模块化。
flowchart TB
App["一个 Next.js 应用"]
App --> UI["界面层<br/>页面与组件"]
App --> Actions["服务端入口<br/>Route Handlers / Server Actions"]
App --> Domain["业务逻辑层<br/>用例与规则"]
App --> Data["数据访问层<br/>ORM / SQL / Repository"]
App --> Infra["基础设施层<br/>鉴权 / AI / 邮件 / 存储"]
UI --> Actions
Actions --> Domain
Domain --> Data
Domain --> Infra对 Vibecoding 尤其重要:要求 AI 把业务规则放在独立模块中,而不是全部写进页面组件或接口函数。这样更容易测试、复用和审查。
7. 什么时候考虑拆分后端
优先从 Next.js 全栈单体开始,出现明确需求后再考虑独立的 Express/NestJS 后端。
| 继续使用 Next.js 单体 | 考虑拆分独立后端 |
|---|---|
| 产品仍在快速验证 | 多种客户端共同使用同一套 API |
| 团队较小 | 前后端由不同团队独立发布 |
| 页面与业务逻辑联系紧密 | 后端需要独立扩容或长时间任务 |
| 部署方式能满足需求 | 存在复杂领域逻辑或严格组织边界 |
| 希望减少技术和运维复杂度 | 需要与现有后端平台深度整合 |
拆分后可能形成:
flowchart LR
Web["Next.js Web 应用"] --> API["NestJS / Express API"]
Mobile["移动端"] --> API
Partner["第三方客户端"] --> API
API --> DB[("数据库")]
API --> Queue["任务队列"]
API --> AI["AI 服务"]微服务不是自然的“下一阶段”。很多产品长期使用模块化单体也能保持良好扩展性。是否拆分应由团队边界、部署需求和真实瓶颈决定。
8. 初学者最容易混淆的地方
“安装了 Node.js,就等于会运行 React 吗?”
不等于。Node.js 主要运行开发工具和服务端代码;React 界面的客户端部分最终通常在浏览器运行。
“npm 和 npm Registry 是同一个东西吗?”
不是。日常语境中的 npm 可能指命令行工具、Registry 或整个生态,但技术讨论时应明确区分:
npm命令:包管理器客户端。- npm Registry:远程软件包仓库。
- npm 生态:围绕软件包形成的整体社区和基础设施。
“React 和 Next.js 应该二选一吗?”
通常不是。Next.js 使用 React。更准确的选择是:
React + Vite:自行组合前端应用。React + Next.js:采用包含更多全栈约定的框架。
“Next.js 和 Node.js 应该二选一吗?”
不是。Node.js 是运行时,Next.js 是框架。它们处于不同层次。
“使用 Next.js 后还需要 Express 或 NestJS 吗?”
不一定。Next.js 自身已经能够承担许多 Web 应用的服务端需求。只有出现清晰的独立后端需求时,再引入 Express 或 NestJS。
“TypeScript 能保证程序运行时安全可靠吗?”
不能。它主要在开发阶段检查类型,不能自动保证权限正确、外部数据可信或业务逻辑无误。
9. 面向 AI Vibecoding 的实用原则
- 先说清技术层次:要求 AI 明确某个依赖是库、框架、工具还是运行时。
- 默认保持单体简单:早期不要让 AI 无理由拆成多个服务。
- 区分浏览器和服务端代码:密钥、数据库连接和管理员权限必须留在服务端。
- 要求输入验证:TypeScript 类型不能替代运行时验证。
- 统一包管理器:项目使用 pnpm,就不要让 AI 又生成 npm 或 Yarn 锁文件。
- 先解释再加依赖:让 AI 说明新软件包解决什么问题、是否已有能力可以复用。
- 保留人工审查:重点检查鉴权、权限、支付、数据库迁移、文件操作和外部 API 调用。
10. 推荐学习顺序
flowchart LR
A["HTML / CSS"] --> B["JavaScript 基础"]
B --> C["浏览器 / DOM / HTTP"]
C --> D["Node.js / 包管理器 / package.json"]
D --> E["TypeScript"]
E --> F["React"]
F --> G["Next.js"]
G --> H["数据库 / 鉴权 / 部署"]
H --> I["按需学习<br/>Express 或 NestJS"]不必先精通整个生态才能开始 Next.js,但要逐渐建立以下判断顺序:
- 我现在写的是哪种语言?
- 这段代码会在哪个运行时执行?
- 哪个工具负责安装和构建?
- 哪个库负责某项具体能力?
- 哪个框架规定了项目整体结构?
11. 版本变化与不确定性
以下内容可能随版本快速变化,实际开发时应查看对应版本的官方文档:
- Next.js 的路由、缓存、渲染、Server Actions 和部署行为。
- React Server Components 及相关服务端开发模式。
- Node.js 对 TypeScript 的直接运行支持范围。
- Vite 的插件、构建目标和配置方式。
- npm、pnpm、Yarn 的工作区与依赖解析行为。
- NestJS 支持的底层 HTTP 平台和适配方式。
本笔记刻意避免写死易过期的版本号。进入具体项目时,应同时记录 Node.js、包管理器、React 和 Next.js 的实际版本。
12. 相关概念
- JavaScript
- TypeScript
- 浏览器运行时
- Node.js
- npm
- pnpm
- Yarn
- npm Registry
- package.json
- node_modules
- 依赖与开发依赖
- React
- React 组件
- Vite
- Next.js
- Express
- NestJS
- 全栈开发
- 单体应用
- 模块化单体
- 前后端分离
- 服务端渲染
- React Server Components
- 运行时验证
- 身份验证与授权
- API
JavaScript 与 TypeScript 的区别、浏览器与 Node.js 的区别、npm pnpm Yarn 对比、React 与 Next.js 的关系、Next.js 全栈请求生命周期、Next.js 项目目录结构、Server Component 与 Client Component。