借一步网
作者:
在
在数字世界的浩瀚宇宙中,OpenHands 前端项目如同一艘装备精良的太空飞船,承载着开发者们对高效、优雅与可靠的追求。它不仅仅是一个 React 应用,更是现代前端工程的缩影——Remix SPA、TypeScript、Redux、TanStack Query、Tailwind CSS、i18next、React Testing Library、Vitest、Mock Service Worker(MSW)……每一项技术都是这艘飞船上的关键部件。
但,如何让这艘飞船在开发、测试与部署的星际航道上畅行无阻?让我们一起踏上这场前端奇遇之旅,揭开 OpenHands 前端的神秘面纱。
OpenHands 前端的技术栈堪称“全副武装”:
想要启动这艘飞船,你需要准备好 Node.js 20.x 及以上版本,以及 npm、bun 等现代包管理工具。
git clone https://github.com/All-Hands-AI/OpenHands.git cd OpenHands/frontend npm install
开发时,MSW(Mock Service Worker)会化身为你的“后端幻影”,让你无需真实后端也能畅快开发:
npm run dev
打开 http://localhost:3001,你就能看到 OpenHands 前端的英姿。
注意:MSW 只“部分”模拟后端,部分功能需等到真后端上线才能体验。
当你准备好与真实后端“正面交锋”时:
make build make run
或者分开启动:
make start-backend make start-frontend # 或 cd frontend && npm start -- --port 3001
如果你还想在开发时体验 MSW 的 SaaS 模式:
npm run dev:mock # 或 npm run dev:mock:saas
每个前端项目都离不开一串串神秘的环境变量。OpenHands 也不例外:
VITE_BACKEND_BASE_URL
VITE_BACKEND_HOST
VITE_MOCK_API
VITE_MOCK_SAAS
VITE_USE_TLS
VITE_FRONTEND_PORT
VITE_INSECURE_SKIP_VERIFY
VITE_GITHUB_TOKEN
只需参考 .env.sample,创建属于你的 .env 文件即可。
.env.sample
.env
frontend ├── __tests__ # 测试用例 ├── public ├── src │ ├── api # API 调用 │ ├── assets │ ├── components # 组件 │ ├── context # 本地状态管理 │ ├── hooks # 自定义 Hook │ ├── i18n # 国际化 │ ├── mocks # MSW Mock │ ├── routes # 路由 │ ├── services │ ├── state # Redux │ ├── types │ ├── utils # 工具函数 │ └── root.tsx # 入口 └── .env.sample # 环境变量样例
组件根据“领域”、“功能”或“共享性”分门别类:
components ├── features # 领域组件 ├── layout ├── modals └── ui # 通用 UI 组件
npm run test # 或带覆盖率 npm run test:coverage
Mock Service Worker(MSW)是一位“网络幻术师”,它能在浏览器或 Node.js 环境下,拦截 HTTP/GraphQL/WebSocket 请求,并返回你自定义的“幻影”响应。这样,你无需真实后端,也能让前端开发和测试如虎添翼。
npm install msw@latest --save-dev
src/mocks/handlers.js
import { http, HttpResponse } from 'msw' export const handlers = [ http.get('https://example.com/user', () => { return HttpResponse.json({ id: 'c7b3d8e0-5e0b-4b0f-8b3a-3b9f4b3d3b3d', firstName: 'John', lastName: 'Maverick', }) }), ]
import { setupServer } from 'msw/node' import { handlers } from './handlers' export const server = setupServer(...handlers)
import { server } from './mocks/node' server.listen()
import { setupWorker } from 'msw/browser' import { handlers } from './handlers' export const worker = setupWorker(...handlers) worker.start()
import { http, HttpResponse } from 'msw' import { setupWorker } from 'msw/browser' const handlers = [ http.get('https://acme.com/product/:id', ({ params }) => { return HttpResponse.json({ id: params.id, title: 'Porcelain Mug', price: 9.99, }) }), ] const worker = setupWorker(...handlers) worker.start()
renderWithProviders()
getByRole
getByLabelText
getByTestId
userEvent
vi.fn()
toBeInTheDocument()
import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { describe, it, expect, vi } from "vitest"; describe("ComponentName", () => { it("should render correctly", () => { render(<Component />); expect(screen.getByRole("button")).toBeInTheDocument(); }); it("should handle user interactions", async () => { const mockCallback = vi.fn(); const user = userEvent.setup(); render(<Component onClick={mockCallback} />); const button = screen.getByRole("button"); await user.click(button); expect(mockCallback).toHaveBeenCalledOnce(); }); });
__tests__/components/chat/chat-input.test.tsx
__tests__/components/file-explorer/file-explorer.test.tsx
想要加入 OpenHands 的开发者行列?请阅读 CONTRIBUTING.md,了解贡献流程与行为准则。
OpenHands 前端项目用现代化的技术栈、科学的测试体系和强大的 Mock 能力,为开发者打造了一片自由探索的星空。无论你是初学者还是老手,这里都有值得你学习和借鉴的宝藏。愿你在前端的航道上,乘风破浪,代码无忧!
要发表评论,您必须先登录。
🏁 序章:一场现代前端的冒险
在数字世界的浩瀚宇宙中,OpenHands 前端项目如同一艘装备精良的太空飞船,承载着开发者们对高效、优雅与可靠的追求。它不仅仅是一个 React 应用,更是现代前端工程的缩影——Remix SPA、TypeScript、Redux、TanStack Query、Tailwind CSS、i18next、React Testing Library、Vitest、Mock Service Worker(MSW)……每一项技术都是这艘飞船上的关键部件。
但,如何让这艘飞船在开发、测试与部署的星际航道上畅行无阻?让我们一起踏上这场前端奇遇之旅,揭开 OpenHands 前端的神秘面纱。
🧰 装备清单:技术栈的魔法道具
OpenHands 前端的技术栈堪称“全副武装”:
🚀 起航:快速启动你的 OpenHands 前端
🛠️ 准备工作
想要启动这艘飞船,你需要准备好 Node.js 20.x 及以上版本,以及 npm、bun 等现代包管理工具。
🏃 开发模式:与 MSW 并肩作战
开发时,MSW(Mock Service Worker)会化身为你的“后端幻影”,让你无需真实后端也能畅快开发:
打开 http://localhost:3001,你就能看到 OpenHands 前端的英姿。
🏭 生产模式:直连真实后端
当你准备好与真实后端“正面交锋”时:
或者分开启动:
如果你还想在开发时体验 MSW 的 SaaS 模式:
🗝️ 魔法咒语:环境变量的奥秘
每个前端项目都离不开一串串神秘的环境变量。OpenHands 也不例外:
VITE_BACKEND_BASE_URL
VITE_BACKEND_HOST
VITE_MOCK_API
VITE_MOCK_SAAS
VITE_USE_TLS
VITE_FRONTEND_PORT
VITE_INSECURE_SKIP_VERIFY
VITE_GITHUB_TOKEN
只需参考
.env.sample
,创建属于你的.env
文件即可。🏗️ 结构探秘:项目目录的藏宝图
🧩 组件分区
组件根据“领域”、“功能”或“共享性”分门别类:
🌐 功能亮点:OpenHands 的超能力
🧪 测试的艺术:让代码无懈可击
🏹 测试武器库
🏃 一键测试
🧙 Mock Service Worker:API Mock 的魔法师
🪄 MSW 的魔法原理
Mock Service Worker(MSW)是一位“网络幻术师”,它能在浏览器或 Node.js 环境下,拦截 HTTP/GraphQL/WebSocket 请求,并返回你自定义的“幻影”响应。这样,你无需真实后端,也能让前端开发和测试如虎添翼。
MSW 的三步法术
npm install msw@latest --save-dev
src/mocks/handlers.js
中定义请求拦截与响应:import { http, HttpResponse } from 'msw' export const handlers = [ http.get('https://example.com/user', () => { return HttpResponse.json({ id: 'c7b3d8e0-5e0b-4b0f-8b3a-3b9f4b3d3b3d', firstName: 'John', lastName: 'Maverick', }) }), ]
import { setupServer } from 'msw/node' import { handlers } from './handlers' export const server = setupServer(...handlers)
在测试或开发入口调用:import { server } from './mocks/node' server.listen()
import { setupWorker } from 'msw/browser' import { handlers } from './handlers' export const worker = setupWorker(...handlers) worker.start()
MSW 的魔法优势
MSW 代码示例
🧑🔬 测试最佳实践:让每一行代码都经得起考验
🧪 组件测试
renderWithProviders()
包裹组件,自动注入 Redux 等上下文。getByRole
、getByLabelText
、getByTestId
查询元素,避免直接用 CSS 选择器。🕹️ 用户事件模拟
userEvent
模拟真实用户操作,如点击、输入、键盘事件。🧙 API Mock 与依赖 Mock
vi.fn()
创建 mock 函数,验证回调与事件处理。♿ 无障碍测试
toBeInTheDocument()
检查元素存在。🔄 状态与属性测试
🌍 国际化测试
📝 实战案例:测试代码片段
📚 测试文件赏析:真实案例
__tests__/components/chat/chat-input.test.tsx
__tests__/components/file-explorer/file-explorer.test.tsx
📈 测试覆盖率与持续集成
🤝 贡献与协作
想要加入 OpenHands 的开发者行列?请阅读 CONTRIBUTING.md,了解贡献流程与行为准则。
🧩 附录:参考文献
🎬 尾声:让前端开发与测试成为一场愉快的冒险
OpenHands 前端项目用现代化的技术栈、科学的测试体系和强大的 Mock 能力,为开发者打造了一片自由探索的星空。无论你是初学者还是老手,这里都有值得你学习和借鉴的宝藏。愿你在前端的航道上,乘风破浪,代码无忧!