06 — 前端工具链:npm 与 Vite

5 分钟理解 npm、node_modules、Vite、import 怎么解析、构建做了什么。
这一章不算重要,但读源码时会遇到这些概念,不懂会卡住。


1. Node.js 与 npm 是什么?

1.1 Node.js

Node.js = 让 JavaScript 能在电脑本地(不只是浏览器)运行的环境

有了 Node.js,开发者可以用 JS:

  • 跑本地脚本(构建工具、测试等)
  • 起本地服务器
  • 操作文件

下载安装:https://nodejs.org (装 LTS 版本即可)。

1
2
node -v    # 查看 Node 版本
npm -v # 查看 npm 版本

1.2 npm(Node Package Manager)

npm = Node 包管理器,类似于 Java 的 Maven、Python 的 pip。

每个 React 项目都有一个 package.json 文件,记录:

  • 项目依赖的第三方库
  • 可运行的脚本命令

项目里的 package.json(节选):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name": "dodo-agent-frontend",
"private": true,
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"preview": "vite preview"
},
"dependencies": {
"react": "^18.3.1",
"react-dom": "^18.3.1",
"zustand": "^4.5.5",
...
}
}

1.3 常用 npm 命令

1
2
3
4
5
npm install                              # 安装 package.json 里所有依赖
npm install react-icons # 安装新依赖
npm uninstall react-icons # 卸载依赖
npm run dev # 运行 scripts.dev (vite)
npm run build # 运行 scripts.build

1.4 node_modulespackage-lock.json

  • node_modules/:装下来的所有依赖文件(占空间大,动辄几百 MB)
  • package-lock.json:锁版本号,确保团队成员装的依赖一致

⚠️ 不要把 node_modules 提交到 git(.gitignore 已经忽略)


2. Vite 是什么?

2.1 一句话

Vite 是一个前端构建工具,负责:

  • 启动开发服务器(带热更新)
  • 把 TS/JSX/CSS Module 编译成浏览器能跑的代码
  • 把所有文件打包成最终产物

2.2 对比其他工具

工具特点
Vite快、配置简单、ES Module 原生支持(现代项目首选)
Webpack老牌、功能强大但慢
Parcel零配置

2.3 启动开发服务器

1
npm run dev

背后执行 vite 命令,Vite 会:

  1. 启动一个本地服务器(默认 http://localhost:5173)
  2. 监听所有源文件改动
  3. 一旦改动,立即刷新浏览器(HMR = Hot Module Replacement 热更新)

2.4 构建生产版本

1
npm run build

背后执行 tsc -b && vite build

  1. tsc -b — TypeScript 检查 + 输出
  2. vite build — 打包、压缩、生成最终 HTML/CSS/JS

产物在 dist/ 目录。


3. ES Module 与 import 解析

3.1 ES Module 基础

现代 JavaScript 的模块系统

1
2
3
4
5
6
7
// math.js
export function add(a, b) { return a + b; }
export const PI = 3.14;

// app.js
import { add, PI } from './math.js';
console.log(add(1, 2)); // 3

3.2 浏览器原生支持

1
2
3
4
<script type="module">
import { add } from './math.js';
// 注意:必须带 .js 后缀(浏览器要求)
</script>

浏览器自己解析 import,按需下载对应文件。

3.3 Vite 的角色

开发时浏览器直接加载 .tsx 文件会报错(不认识 JSX)。
Vite 在中间做了翻译

1
2
3
4
5
6
7
浏览器请求 /src/App.tsx

Vite 拦截请求

把 .tsx 转译成 .js(编译 JSX、处理 TypeScript)

返回给浏览器

⚡ 这就是 Vite 快的秘诀——按需编译,不用一次性打包。

3.4 项目里的各种 import 写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 1. 相对路径
import { Sidebar } from './components/Sidebar/Sidebar';
// ↑ 从当前文件开始找

// 2. 路径别名 @/ (vite.config.ts 和 tsconfig.json 都配了)
import { useChatStore } from '@/store/chatStore';
// ↑ 指向 src/store/chatStore

// 3. 第三方包
import { create } from 'zustand';
// ↑ 从 node_modules 里找

// 4. 第三方包带子路径
import ReactMarkdown from 'react-markdown';

// 5. 只导入类型(编译时删除)
import type { ChatMessage } from '@/store/chatStore';

4. Vite 配置(vite.config.ts)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';

export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'), // @ 指向 src 目录
},
},
server: {
port: 5173,
proxy: {
'/api': {
target: 'http://localhost:8080', // 把 /api 代理到后端
changeOrigin: true,
},
},
},
});

重点理解

4.1 路径别名 alias

1
'@': path.resolve(__dirname, './src')

之后 import xxx from '@/store/chatStore' 等价于 import xxx from 'src/store/chatStore'

4.2 代理 proxy

1
2
3
4
5
6
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
},
}

为什么需要代理?

前端在 localhost:5173,后端在 localhost:8080
浏览器同源策略禁止跨域请求。

解决:让 Vite 在中间做「转发」。

1
2
3
4
浏览器 → http://localhost:5173/api/chat/stream
↓ Vite 看到 /api 开头
↓ 转发到 http://localhost:8080/api/chat/stream
↓ 返回给浏览器

浏览器以为是同源请求(都是 5173),实际是 Vite 帮忙转发的。


5. TypeScript 配置(tsconfig.json)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// tsconfig.json
{
"compilerOptions": {
"target": "ES2020", // 编译到 ES2020 语法
"lib": ["ES2020", "DOM"], // 浏览器 API 类型
"jsx": "react-jsx", // 启用 JSX
"module": "ESNext", // 模块系统用 ES Module
"moduleResolution": "Bundler", // Vite/Webpack 用这个解析模块
"strict": true, // 严格模式
"paths": {
"@/*": ["./src/*"] // @ 别名(必须和 vite.config 一致)
}
},
"include": ["src"] // 编译 src 目录
}

关键配置解释

  • target:TS 编译成什么版本的 JS
  • jsx: "react-jsx":让 <div>...</div> 被识别为 JSX
  • strict: true:开启所有严格类型检查
  • paths:路径别名

6. 项目启动流程(从你按 npm run dev 开始)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1. 你执行 npm run dev

2. npm 读取 package.json 的 scripts.dev = "vite"

3. Vite 启动

4. Vite 读取 vite.config.ts

5. Vite 启动 HTTP 服务器(默认 5173 端口)

6. 浏览器访问 http://localhost:5173

7. Vite 返回 index.html

8. 浏览器解析 <script type="module" src="/src/main.tsx">

9. Vite 拦截请求,把 main.tsx 编译成 JS(处理 import、TSX)

10. 浏览器执行 main.tsx,挂载 React 到 #root

11. App 组件开始渲染

12. 后续 React 组件的 import 都按需由 Vite 编译返回

7. 构建产物(npm run build)

1
npm run build

执行后输出:

1
2
3
4
5
dist/
├── index.html ← 入口 HTML(已处理)
└── assets/
├── index-xxxxxxx.css ← 所有 CSS 合并
└── index-yyyyyyy.js ← 所有 JS 合并 + 压缩

关键点

  • HTML/CSS/JS 文件名带 hash(index-xxxxxxx.css)— 浏览器可永久缓存
  • 整个项目压缩后几百 KB
  • 部署时把 dist/ 整个上传即可

8. 常见命令速查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 开发
npm run dev # 启动开发服务器(热更新)

# 构建
npm run build # 构建生产版本到 dist/
npm run preview # 本地预览 dist/

# 类型检查
npm run typecheck # 只检查类型,不输出文件

# 依赖管理
npm install # 安装所有依赖
npm install xxx # 安装某个依赖
npm install -D xxx # 安装开发依赖(如测试库)
npm uninstall xxx # 卸载
npm update # 更新所有依赖

9. 一段话总结

npm 管理依赖(npm install 装包)。
Vite 是构建工具,开发时启动服务器并按需编译,生产时打包。
import 在浏览器由 Vite 解析、在 Node 由 TS 解析。
路径别名 @/ 指向 src/ 目录,让 import 更短。
代理 proxy 让前端开发时访问后端不跨域。


接下来

工具链概念搞定。现在开始讲 React 本身 — 07-React是什么与JSX.md