当前位置: 首页 > news >正文

React 从入门到生产(八):测试与部署

创作者:Yardon |GitHub:github.com/YardonYan |版本:v1.0


为什么要写测试

测试是一种投资——短期成本是写代码的时间,长期回报是减少线上事故和重构恐惧。

测试金字塔:

/\ /E2E\ 少(关键路径) /------\ / 集成测试 \ 中(组件交互) /----------\ / 单元测试 \ 多(纯函数、组件、Hook) /--------------\

Vitest + Testing Library 入门

npminstall-Dvitest @testing-library/react @testing-library/jest-dom jsdom
// vitest.config.jsimport{defineConfig}from'vitest/config';exportdefaultdefineConfig({test:{environment:'jsdom',globals:true,// 无需 import describe/it/expectsetupFiles:'./test-setup.js',},});

组件测试实战

// Counter.jsx export function Counter({ initial = 0 }) { const [count, setCount] = useState(initial); return ( <div> <span>// Counter.test.jsx import { render, screen, fireEvent } from '@testing-library/react'; describe('Counter', () => { it('初始值正确', () => { render(<Counter initial={5} />); expect(screen.getByTestId('count')).toHaveTextContent('5'); }); it('点击 +1 增加', () => { render(<Counter />); fireEvent.click(screen.getByText('+1')); expect(screen.getByTestId('count')).toHaveTextContent('1'); }); it('点击 -1 减少', () => { render(<Counter initial={10} />); fireEvent.click(screen.getByText('-1')); expect(screen.getByTestId('count')).toHaveTextContent('9'); }); });

测试原则

  1. 测试行为,不测试实现——如果你改了组件内部代码但行为不变,测试应该仍然通过
  2. 不测试第三方库——React 是 Facebook 的责任,不是你的
  3. 每个测试只验证一件事

Hook 测试

import { renderHook, act } from '@testing-library/react'; it('useCounter: increment 增加计数', () => { const { result } = renderHook(() => useCounter(0)); act(() => result.current.increment()); expect(result.current.count).toBe(1); act(() => result.current.increment()); act(() => result.current.increment()); expect(result.current.count).toBe(3); });

E2E 测试:Playwright

npminstall-D@playwright/test npx playwrightinstall
// tests/smoke.spec.jsimport{test,expect}from'@playwright/test';test('首页加载正常',async({page})=>{awaitpage.goto('http://localhost:4173');awaitexpect(page.locator('h1')).toHaveText('欢迎');});test('导航到博客页',async({page})=>{awaitpage.goto('http://localhost:4173');awaitpage.click('text=博客');awaitexpect(page).toHaveURL(/\/blog/);});

构建与部署:Vite + Nginx

vite build# 产出 dist/ 目录
server { listen 80; server_name example.com; root /var/www/react-app/dist; index index.html; location / { try_files $uri $uri/ /index.html; # SPA 路由回退 } location /assets/ { expires 1y; # 静态资源缓存一年 add_header Cache-Control "public, immutable"; } }

CI/CD 流水线

# .github/workflows/deploy.ymlname:Deployon:push:branches:[main]jobs:deploy:runs-on:ubuntu-lateststeps:-uses:actions/checkout@v4-uses:actions/setup-node@v4with:{node-version:20}-run:npm ci-run:npm run lint-run:npm run test-run:npm run build-name:Deployrun:rsync-avz dist/ user@server:/var/www/app/

系列总结

欢迎来到「React 从入门到生产」系列的终点。

回顾我们这八章走过的路:

主题核心收获
1JSX 与组件思维React 的声明式范式、组件化思想
2状态与事件处理useState、受控组件、不可变更新
3副作用与数据获取useEffect、竞态处理、清理函数
4自定义 Hook封装可复用逻辑、Hook 组合模式
5状态管理选型Context vs Zustand vs Redux 的适用场景
6路由与导航React Router v6、嵌套路由、懒加载
7性能优化React.memo、虚拟滚动、代码分割
8测试与部署Vitest、Playwright、Nginx 部署

React 不是一门需要"学完"的技术——它是一个持续进化的生态系统。真正重要的是理解它的核心范式(声明式 UI、单向数据流、组件思维),然后不断在实践中打磨。

📌创作者:Yardon | 🏠个人网站:GlimmerAI.top

📖 本章是「React 从入门到生产」系列的终章。完整 8 章已完结!

🎉 恭喜你完成了 React 学习之旅!下一路线:「FastAPI 全栈后端」——从路由设计到生产部署。欢迎大家来观看!

http://www.jsqmd.com/news/874432/

相关文章:

  • 【论文复现】基于反步法-神经网络控制器、LOS制导和Lyapunov方法的多艘欠驱动水面船舶协调路径跟踪非线性控制Matlab代码
  • 2026年当前,江苏地区静电地板批发厂家深度解析与亚克基推荐 - 2026年企业推荐榜
  • 【独家】26电工杯a题b题完整版解答来啦!含论文与可执行代码
  • 通过Python快速调用Taotoken提供的多种大模型API
  • 从零到亿级调用量:电商客服Agent重构实录(含对话状态机+意图跳转图+人工接管SLA协议)
  • 2026年近期济宁地区专业水泥承插口管厂家盘点与选购指南 - 2026年企业推荐榜
  • 深圳鸿芯智谷·智启未来——以产教融合之力,点燃具身智能时代新引擎
  • Pico Neo3 XR开发实战:从黑屏闪退到真机运行的完整链路
  • Unity游戏多语言热更新实战:AutoTranslator核心机制与避坑指南
  • FAI-C-ST基准:基于基督教社会训导的AI价值观对齐评估实践
  • 2026年电磁加热回转窑应用白皮书烘干行业剖析:电蒸汽发生器厂家/电蒸汽炉厂家/电蒸汽锅炉厂家/电锅炉厂家/电加热回转窑厂家/选择指南 - 优质品牌商家
  • 掌握核心技术概念提升项目管理效能
  • Windows 本地 AI 智能体部署:不花一分钱,电脑自己干 80% 的重复活
  • 公差±0.005mm加工厂家有哪些?精密CNC稳定控差的工艺逻辑
  • 深度 | 昇腾NPU MoE算子实现:从TopKGating到Expert并行,稀疏激活的硬件适配
  • 2026年AI大模型API聚合站年度权威横评:五大主流平台全维度硬核实测数据选型指南
  • 基于计算机视觉与SLAM的无障碍机器人编程教学框架设计与实践
  • Unity云渲染本地部署实战:断网环境下的高保真实时交互方案
  • WSL2内存管理避坑指南:从Docker Desktop到.wslconfig,我的轻量开发环境搭建实录
  • 经典Gilbert算法如何挑战机器学习,绘制量子纠缠地图?
  • Sa-Token 单点登录(SSO)三种模式大白话详解:告别重复登录
  • Playwright 浏览器自动化完全指南:从入门到实战
  • DDSC在东阳修车哪家好
  • de风——【从零开始学Linu】 - 基础指令详解(二)
  • 【深度解析】制造业选AI Agent,应看重行业经验还是通用能力?
  • Win11当Linux用?手把手教你配置SSH服务实现远程开发与文件传输
  • 性价比高的生成式引擎优化GEO哪家专业
  • Git学习(四)
  • SQLmap Python环境配置避坑指南:从启动失败到稳定运行
  • IMPROVER系统:AI气象预报统计后处理的工程化实践