如何从零构建一个 AI + 全栈项目:前端路由篇
在接下来的系列文章中,我将系统地介绍如何完成一个融合人工智能(AI)能力的全栈项目。这类项目不仅包含传统的前端与后端开发,还需深度集成大模型、智能代理等 AI 技术,对开发者的技术广度和工程能力提出了更高要求。
本文作为系列的第一篇,将聚焦于项目整体架构设计与前端路由系统的搭建,为后续开发打下坚实基础。
一、项目技术栈概览
一个典型的 AI + 全栈项目需要覆盖三大模块:前端、后端与 AI 服务层。我们采用如下技术组合:
前端(Frontend)
- React + TypeScript:使用 React 构建用户界面,TypeScript 作为 JavaScript 的超集,通过静态类型系统在开发阶段捕获潜在错误,显著提升代码的可读性、可维护性与团队协作效率。
- react-router-dom:实现前端路由,支持页面无刷新切换。
- Zustand:轻量级状态管理库,用于集中管理应用状态。
- Axios:处理 HTTP 请求,与后端或 AI 服务通信。
💡 小贴士:JavaScript 写得快,TypeScript 写得稳。在中大型项目中,TypeScript 的优势尤为明显。
后端(Backend)
- Node.js + TypeScript
- NestJS:企业级 Node.js 框架,提供模块化、依赖注入、装饰器等特性,适合构建高内聚、低耦合的服务。
- PostgreSQL(PSQL) :关系型数据库,用于持久化核心业务数据。
- Redis:内存缓存数据库,提升高频读取性能,也可用于会话管理或消息队列。
AI 层(AI Server)
- LangChain:构建基于大语言模型(LLM)的应用框架。
- Coze / n8n:低代码/自动化工作流平台,可用于连接 AI 能力与业务逻辑。
- Trae / Cursor:AI 编程辅助工具,提升开发效率。
- 集成多种大模型 API(如 GPT、Claude、通义千问等),按需调用。
二、项目目录结构设计
清晰的目录结构是良好工程实践的第一步。我们采用如下分层结构:
text
编辑
project-root/
├── frontend/ # 前端代码(React + TS)
├── backend/ # 后端服务(NestJS + TS)
├── ai_server/ # AI 服务模块(LangChain 等)
└── admin/ # 后台管理系统(可选,独立前端)
这种划分方式职责分明,便于团队并行开发与独立部署。
✅ 此时应进行首次 Git 提交
在初始化项目目录后,立即执行:bash
编辑
git init git add . git commit -m "feat: initialize project structure" git push origin mainGit 提交原则:颗粒适中、语义清晰。避免过于频繁(产生噪音)或一次性提交(丢失上下文)。建议在完成一个逻辑完整的功能模块后提交,并撰写准确的提交信息。
三、前端路由系统详解
现代 Web 应用普遍采用前后端分离架构,前端不再只是“切图崽”,而是拥有独立路由控制能力的完整客户端。React 生态中,react-router-dom 是实现前端路由的事实标准。
路由模式选择
React Router 提供两种主要路由模式:
表格
| 模式 | URL 示例 | 技术原理 | 兼容性 | 适用场景 |
|---|---|---|---|---|
BrowserRouter | /about | 基于 HTML5 History API | 现代浏览器(IE11+ 不支持) | 主流选择,URL 更优雅 |
HashRouter | /#/about | 利用 URL hash 片段 | 兼容性极好 | 静态部署、简单 Demo |
📌 本项目采用
BrowserRouter,因其 URL 更干净、符合现代 Web 标准。
路由类型详解
-
普通路由
匹配固定路径,渲染对应组件。jsx
预览
<Route path="/" element={<Home />} /> -
动态路由
通过路径参数(如:id)传递数据,适用于详情页等场景。jsx
预览
<Route path="/user/:id" element={<UserProfile />} />组件内通过
useParams()获取参数:tsx
编辑
import { useParams } from 'react-router-dom'; export default function UserProfile() { const { id } = useParams(); return <div>User Profile: {id}</div>; } -
嵌套路由
父路由包含子路由,通过<Outlet />占位渲染子组件。jsx
预览
<Route path="/products" element={<Product />}> <Route path=":productId" element={<ProductDetail />} /> <Route path="new" element={<NewProduct />} /> </Route> -
重定向路由
使用<Navigate>实现路径跳转,常用于旧链接迁移或登录后跳转。jsx
预览
<Route path="/old-path" element={<Navigate replace to="/new-path" />} /> -
鉴权路由(Protected Route)
自定义高阶组件,在进入路由前校验用户权限(如是否登录),未授权则跳转至登录页。jsx
预览
<Route path="/pay" element={ <ProtectRoute> <Pay /> </ProtectRoute> } /> -
统配路由(404 页面)
匹配所有未定义路径,通常用于展示“页面未找到”提示。jsx
预览
<Route path="*" element={<NotFound />} />
路由代码实现(含懒加载)
为优化首屏加载性能,我们采用 React.lazy + Suspense 实现路由级别的代码分割(Code Splitting):
tsx
编辑
import { lazy, Suspense } from 'react';
import { Routes, Route, Navigate } from 'react-router-dom';
import LoadingFallback from '../components/LoadingFallback';
// 懒加载页面组件
const Home = lazy(() => import('../pages/Home'));
const About = lazy(() => import('../pages/About'));
const UserProfile = lazy(() => import('../pages/UserProfile'));
const Product = lazy(() => import('../pages/product'));
const ProductDetail = lazy(() => import('../pages/product/ProductDetail'));
const NewProduct = lazy(() => import('../pages/product/NewProduct'));
const Login = lazy(() => import('../pages/Login'));
const Pay = lazy(() => import('../pages/Pay'));
const NotFound = lazy(() => import('../pages/NotFound'));
const NewPath = lazy(() => import('../pages/NewPath'));
const ProtectRoute = lazy(() => import('../components/ProtectedRoute'));
export default function RouterConfig() {
return (
<Suspense fallback={<LoadingFallback />}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/user/:id" element={<UserProfile />} />
{/* 嵌套路由 */}
<Route path="/products" element={<Product />}>
<Route path=":productId" element={<ProductDetail />} />
<Route path="new" element={<NewProduct />} />
</Route>
<Route path="/login" element={<Login />} />
<Route path="/old-path" element={<Navigate replace to="/new-path" />} />
<Route path="/new-path" element={<NewPath />} />
{/* 鉴权路由 */}
<Route path="/pay" element={
<ProtectRoute>
<Pay />
</ProtectRoute>
} />
{/* 404 */}
<Route path="*" element={<NotFound />} />
</Routes>
</Suspense>
);
}
✨ 懒加载的优势:
- 减少初始包体积,加快首屏渲染
- 按需加载,节省带宽与内存
- 提升用户体验与应用性能
四、小结
本文完成了 AI + 全栈项目的开篇布局:明确了技术栈、设计了清晰的目录结构、规范了 Git 提交流程,并重点实现了现代化的前端路由系统。这为后续的页面开发、状态管理、API 对接以及 AI 功能集成奠定了坚实基础。
在下一篇中,我们将深入前端页面与组件开发,并开始对接后端接口,敬请期待!