React企业中台实战 - 第二章. 奠基:项目初始化与环境配置
React企业中台实战 - 第二章. 奠基:项目初始化与环境配置
Prorise第二章. 奠基:项目初始化与企业级配置
在本章中,我们将卷起袖子,开始 Prorise-Admin 的奠基工作。我们将从一个空目录开始,使用 pnpm create vite 初始化项目骨架。随后,我们将 立即 着手进行一系列至关重要的企业级配置,包括:规范化开发环境、配置 TypeScript 严格模式、实现 @/* 路径别名,并为项目注入现代化的 代码质量工具链。每一步都旨在为后续的高效、稳定开发铺平道路。
2.1. 项目初始化:一切的起点
2.1.1. pnpm create vite:选择最快的脚手架
我们的第一步,是使用 Vite 官方脚手架创建一个最小化的 React + TypeScript 项目。正如第一章所述,Vite 提供了无与伦比的开发体验,而 pnpm 以其高效的磁盘空间利用和快速的安装速度,成为我们的首选包管理器。
打开终端,执行以下命令:
1 | # 使用 pnpm 执行 vite 的创建命令 |
脚手架会引导我们完成创建。成功后,终端会提示我们进入项目目录并安装初始依赖:
1 | cd prorise-admin |
此刻,一个基础的 Vite + React + TS 项目已经诞生。但在我们编写任何业务代码之前,架构师的首要任务是建立规范和约束,确保项目在未来的迭代和协作中不会走向混乱。
2.1.2 环境一致性:根除“在我这儿是好的”
在企业级协作中,最常见的内耗源于环境不一致(如 Node.js 版本、包管理器混用)导致的各类诡异 Bug。我们必须在项目初始化的第一刻就通过配置来杜绝这种可能性。
锁定 Node.js 版本 (.nvmrc)
不同的 Node.js 版本可能导致依赖安装失败或运行时行为不一致。我们将通过 .nvmrc 文件来声明项目期望的 Node.js 版本。
我们在项目根目录 (prorise-admin/) 下创建 .nvmrc 文件。
文件路径: .nvmrc
1 | lts/iron |
为什么是 lts/iron?
我们不直接写 20,而是使用 LTS (长期支持版) 的代号 iron (Node.js 20.x 的代号)。这更具可读性,并且允许团队成员使用 20.x 系列中的任何最新稳定版,而不是强制锁定到一个特定的微小版本。
工作流提示:团队成员在首次拉取项目后,只需在项目根目录运行 nvm use 或 nvm install 命令。NVM (Node Version Manager) 会自动读取此文件,并下载或切换到指定的 Node.js 版本,从而无感地统一了环境。
2.1.3. 强制 pnpm 版本与使用 (package.json + .npmrc)
仅仅建议使用 pnpm 是不够的,我们需要强制执行。这分为两步:声明规则 和 开启执行。
第一步:在 package.json 中声明规则
我们打开 package.json,手动添加 engines 字段,这里是我们声明项目所依赖的 Node 和 pnpm 版本的地方。
文件路径: package.json
1 | { |
架构师视角:
engines字段本身只是一种“建议”。如果用户环境不匹配,默认情况下pnpm只会给出一个警告,而不会阻止安装。这对于强制规范来说是远远不够的。
第二步:在 .npmrc 中开启强制执行
为了让 pnpm 严格执行 engines 中的规则,我们需要创建 .npmrc 文件来改变 pnpm 的默认行为。
我们在项目根目录创建 .npmrc 文件。
文件路径: .npmrc
1 | # 这行配置是关键:它告诉 pnpm,必须严格检查 `engines` 字段。 |
通过这两步的结合,我们形成了一个完整的约束链:package.json 定义了版本规则,.npmrc 则赋予了这些规则强制执行的能力。
2.1.4. (可选但推荐) 脚本防御:阻止 npm 和 yarn
为了做到万无一失,我们可以利用 package.json 的 preinstall 脚本,在安装依赖前进行主动检查,彻底阻止团队成员误用 npm 或 yarn。
文件路径: package.json
1 | { |
为什么不直接写一个 preinstall 脚本来检查 process.env.npm_config_user_agent?
当然可以,only-allow 这个包本质上就是做了这件事。但直接使用它有两个好处:第一,意图明确,npx only-allow pnpm 这行代码的可读性远高于一个自定义的 JS 脚本。第二,社区最佳实践,它已经处理了各种边缘情况,我们无需重复造轮子。
至此,我们的项目环境规范化配置已经完成。任何试图使用错误环境的开发者都会被立即、明确地阻止,这为后续的顺利协作打下了坚如磐石的基础。
2.2. 核心配置 (一):tsconfig.json 与路径别名
环境规范只是我们的第一道防线。第二道防线,则是代码的“类型规范”。Vite 默认的 tsconfig.json 非常宽松,这对于企业级项目来说是不可接受的。
2.2.1. tsconfig.json 的企业级强化
我们打开项目根目录的 tsconfig.json,对其进行一次彻底的“加固”升级。
文件路径: tsconfig.json
1 | { |
这份配置比 Vite 默认的多很多,重点在哪里?
重点在三个方面:
开启严格模式 ("strict": true):这是 TypeScript 的精髓。它会开启一系列(如 strictNullChecks, noImplicitAny 等)检查,强迫我们编写更健壮、更可预测的代码。在项目初期就开启它,远比项目中期再去修复成百上千的类型错误要容易得多。
提升代码质量:"noUnusedLocals" 和 "noUnusedParameters" 会帮助我们发现代码中的“死代码”,保持项目的整洁。"forceConsistentCasingInFileNames" 则能避免在大小写不敏感的操作系统(如 Windows, macOS)上出现导入路径大小写混乱的问题。
- 配置路径别名 (
"paths"):这是本节的重点。我们定义了@/*作为src/*的别名。这意味着未来我们可以写import '@/components/Button'而不是import '../../components/Button'。
为什么 moduleResolution 要用 "bundler"?
这是 2024-2025 年的最佳实践。它最符合 Vite、Webpack 这类现代打包工具的模块解析逻辑,能更好地处理 package.json 中的 exports 字段。
2.2.2. 让 Vite 识别路径别名
仅仅在 tsconfig.json 中配置了 paths 是不够的。tsc(TypeScript 编译器)能看懂这个配置,但 Vite(我们的打包工具)看不懂。
我们需要一个“翻译官”插件,来读取 tsconfig.json 中的 paths 配置,并将其转换为 Vite 能理解的解析规则。
第一步:安装“翻译官”插件
这个插件就是 vite-tsconfig-paths。这是我们主动安装的第一个 开发依赖,因为它解决了我们“让别名在 Vite 中生效”这个迫切的基础设施需求。
1 | pnpm add -D vite-tsconfig-paths |
第二步:配置 vite.config.ts
我们打开 vite.config.ts,引入并使用这个插件。
文件路径: vite.config.ts
1 | import { defineConfig } from 'vite' |
2.2.3. 验证路径别名
配置完成后,我们必须立即验证它是否生效。
我们打开 src/main.tsx,将 App.tsx 和 index.css 的导入路径从相对路径改为别名路径。
文件路径: src/main.tsx
1 | import React from 'react' |
现在,我们清理一下 src 目录中其他默认文件:删除 src/App.css 和 src/assets/react.svg。并简化 src/App.tsx。
文件路径: src/App.tsx
1 | function App() { |
此时,再次运行 pnpm run dev。如果项目能正常启动并显示 “Prorise-Admin”,则证明我们的路径别名 @/* 已经成功生效!
2.3. 核心配置 (二):unplugin-auto-import 自动导入
我们已经解决了路径别名的问题。但作为架构师,我们还预见到另一个开发体验(DX)的痛点:重复的 import 语句。
在 React 项目中,我们几乎在每个文件都需要 import { useState, useEffect } from 'react'。未来引入 Antd 或其他库时,import { Button, Input, ... } from 'antd' 这样的语句也会变得非常繁琐。
我们可以在项目奠基阶段,通过“自动导入”插件来一劳永逸地解决这个问题。
2.3.1. 安装与配置 unplugin-auto-import
我们将使用 unplugin-auto-import,它是一个功能强大的 Vite/Webpack 插件。
第一步:安装插件
1 | pnpm add -D unplugin-auto-import |
第二步:配置 vite.config.ts
我们再次打开 vite.config.ts,添加 AutoImport 的配置。
文件路径: vite.config.ts
1 | import { defineConfig } from 'vite' |
第三步:配置 TypeScript 以识别类型声明
执行 pnpm run dev。插件会自动在项目根目录生成两个文件:
auto-imports.d.ts:这是给 TypeScript 看的类型声明文件,它告诉 TSuseState等是全局可用的,避免类型报错。.eslintrc-auto-import.json:这是给 ESLint/BiomeJS 看的,告诉它们这些是全局变量,避免 lint 报错。(我们将在下一章配置 Biome 时用到它)
重要提示:由于 auto-imports.d.ts 生成在项目根目录,而我们的 tsconfig.json 中 include 配置默认只包含 ["src"] 目录,TypeScript 编译器无法自动发现这个类型声明文件。我们需要手动将其添加到配置中。
打开 tsconfig.json,找到文件末尾的 include 配置,修改如下:
文件路径: tsconfig.json
1 | { |
修改完成后,在 VSCode 中 重启 TypeScript 服务器 以使配置生效:
- 按
Ctrl + Shift + P(macOS 为Cmd + Shift + P) - 输入并执行:
TypeScript: Restart TS Server
2.3.2. 验证自动导入
现在,最激动人心的一刻到来了。我们打开 src/App.tsx,直接使用 useState。
文件路径: src/App.tsx
1 | // 注意:文件顶部没有 import { useState } from 'react' |
刷新页面,你会发现计数器工作得非常好!useState 被自动注入了。













