首发于公众号 code进化论,欢迎关注。
依托CDD的开发提效
什么是CDD?
组件驱动开发(Component-Driven Development, CDD)是一种以组件为中心构建用户界面的开发方法。它从最小的 UI 单元入手,将页面拆解为多个可独立开发、复用、测试的小组件,并逐步组合成复杂的应用。这一开发模式提升了模块化、复用性,并且能让团队更高效地协作开发。
现状
随着前端项目规模的增长,组件数量也会随之增加。成熟的项目可能包含数百个组件,进而可能产生数千种离散的变体,而这些变体又纠缠于各自的业务场景,这就会出现下面两个问题:
-
效果验证等待时间长
一般本地开发项目都需要先本地启动项目,项目编译构建完之后最终才能在浏览器中进行预览,对于大型单体项目来说这个过程会推项目的体积变大而变长,除此之外频繁修改组件后需要重新编译整个应用,最后刷新页面才能看到效果,这会导致开发者等待时间过长。
-
效果验证流程长
在组件的开发过程中,一些组件可能需要在特定的路由页面或者特定交互下才会渲染,这些交互可能还存在数据的请求,这意味着开发者在组件开发阶段无法轻松验证其效果,开发者往往需要切换到实际页面或者手动进行交互才能验证组件效果。
因此如何在实际项目中真正发挥 CDD 的效果是至关重要的。
Storybook
Storybook 是一个开源工具,用于构建和展示UI 组件的独立开发环境。它让开发者可以在不依赖于项目启动的情况下开发、测试和调试组件,并将组件以不同状态和场景的形式展示。Storybook 支持多种前端框架(如 React、Vue、Angular 等),能够有效的提高组件驱动开发(CDD)的效率和体验:
- Storybook 提供了一个独立的环境,使得开发者可以专注于组件的开发,而无需考虑项目的其他依赖。这种独立性避免了项目编译和启动的时间浪费,提升开发效率。
- Storybook 让开发者可以直观地查看所有已开发的组件,并以故事(Story)的形式展示它们的不同状态。这种可视化库有助于团队了解现有组件的功能和样式,避免重复开发。
- 开发者可以在 Storybook 中预设组件的各种场景,并在这些场景下测试组件的表现。这减少了开发者在页面级调试时的等待时间,并确保组件能在各种状态下正确工作。
Nx如何集成Storybook
为了帮助开发者在项目中快速集成 Storybook,Nx 提供了相应的代码生成器,@nx/react、@nx/vue、@nx/angular 等插件都提供了对应框架的 Storybook 生成器,帮助开发者生成最佳实践的 Storybbok 配置,下面以 react 项目为例。
安装插件
jsx
pnpm add @nx/react -D
生成 Storybook 配置
首先需要打开 Nx Console 并选中 Generate(UI)中的 @nx/react -Storybook Configuration。


只需要在 project 选项中选择对应的库名称,然后点击生成代码的按钮,创建完成之后会增加如下配置文件:
jsx
libs/shop/
├──.storybook/
│ ├── main.ts
│ ├── preview.ts
├── src/
│ └── lib/
│ └── shop.stories.tsx
└── tsconfig.storybook.json
│
└── vite.config.ts
这里需要关注的是 main.ts 即 storybook 编译运行配置:
jsx
import type { StorybookConfig } from '@storybook/react-vite';
const config: StorybookConfig = {
stories: [
'../src/lib/**/*.@(mdx|stories.@(js|jsx|ts|tsx))'
],
addons: [],
framework: {
name: '@storybook/react-vite',
options: {
builder: {
viteConfigPath: 'vite.config.ts',
},
},
},
};
export default config;
- stories 表示 storybook 会在配置的路径中寻找 story 文件。
- framework 表示 storybook 运行的框架,对于 react 项目默认使用的 @storybook/react-vite,并读取当前库下面的 vite.config.ts 配置。
最终运行 stroybook 的启动命令就能在浏览器中进行预览:


接下来对于 shop 库的开发我们只需要启动 storybook 就能快速完成开发。
依托TDD的开发提效
什么是TDD?
TDD 是测试驱动开发 (Test-Driven Development)的英文简称,旨在开发者在编写代码之前,首先编写测试代码,测试代码确定开发者对功能的预期,之后再编写实际功能代码,直到所有的功能代码都通过测试用例。
当前前端开发都以数据驱动为主,开发者通过声明式的方式编写 UI 代码,即开发者描述"渲染成什么样",而不需要详细描述"如何渲染",最终通过数据来控制和驱动用户界面的生成、更新和变化。而数据层作为应用的核心逻辑,承担了数据的获取、处理、存储和验证等多项职责,因此在数据层进行 TDD 开发是非常必要。
作者认为以 TDD 的方式开发数据层有几大核心作用:
- 前端开发者脱离面向 UE/UI 开发,转而面向功能逻辑开发。
- 避免头重脚轻的情况,即数据层逻辑少,UI层逻辑多。
- 确保代码的可测试性,提高代码质量和可维护性,长期减少回归 bug。
TDD工具现状
有效的测试框架对于构建可靠的 javascript 应用程序至关重要,可以帮助开发者最大限度的减少错误并尽早发现错误,而选择正确的测试框架可节省数小时的配置并改善开发者的体验。下面主要介绍当前使用率较高的三个测试框。
当前前端流行的测试框架有 jest、vitest、cypress 等,在 vitest 官方文档中对这几个框架都做了详细的介绍和对比。
Jest Vs Vitest
下面会从开发者体验、社区和生态系统方面比较一下 Jest 和 Vitest 两个测试框架,由于 jest 和 vitest 的重点区分点不在性能上而且官方也没有给出各自的对比数据,所以就不过多介绍了。
开发体验
Jest 和 Vitest 都拥有全面、组织良好且易于搜索的文档,大大降低了开发者的上手门槛,同时两者提供功能和 API 非常相近,为了便于开发者从 Jest 迁移到 Vitest,Vitest 提供了对大多数 Jest API 和生态系统库的兼容性,在大多数项目中,它应该可以直接替换 Jest 使用。
作者认为在开发体验上两者最大的差别还是在于对 ESM 的支持,Vitest 的 ES 模块支持使其比 Jest 具有显著优势,而 Jest 仅提供对 ES 模块的实验性支持,因此在 Jest 中使用 ESM 会存在很大的风险。
因此开发者在使用 Jest 时需要先使用Babel将 JavaScript ESM 模块转换为 CommonJS,这可以借助 @babel/plugin-transform-modules-commonjs
插件,但是在默认情况下,Babel 会将第三方依赖排除在外,如果开发者使用了仅支持 ESM 的依赖库,例如 react-markdown
,在这种情况下,Jest 会给开发者进行错误提示:
jsx
SyntaxError: Unexpected token 'export'
要解决此问题,需要在 jest.config.js 文件中的配置 transformIgnorePatterns 来指定那些依赖需要由 Babel 进行转译。除此之外 Jest 对于 TypeScript 的支持也需要进行额外的配置。
总体而言,Jest 需要一些配置才能与 ESM 模块和 TypeScript 配合使用,而 Vitest 是直接支持 ESM 模块和 TypeScript ,配置越少,开发人员就越开心。
社区生态

从统计数据来看,虽然 npm 下载量显示 Jest 要高于 Vitest,但是 Vitest 的增长趋势在迅速增长。根据JS 2023 年调查,Vitest 在 2021 年至 2023 年期间人气和正面评价迅速上升。相比之下,Jest 在 2016 年至 2020 年期间人气和正面评价迅速上升,但这种势头在 2021 年至 2023 年期间有所放缓,人们的看法也变得更加褒贬不一。这种转变可能是由于开发人员采用了 Vitest,它解决了 Jest 的主要痛点之一:ESM 模块支持。
Nx如何集成Vitest/Jest/Cypress
Nx 为了帮助开发者更好地在项目中搭建单测环境,为 Vitest、Jest、Cypress 都提供了相应的代码生成器,下面会以 Vitest 为例为项目添加单测配置。

使用代码生成器搭建Vitest环境
首先需要打开 Nx Console 并选中 Generate(UI)中的 @nx/vite - vitest。

在配置页开发者可以选择是否自动生成 vite 配置、运行环境(node/jsdom/happy-dom)、ui框架等:

最终 Nx 会在当前 package 下生成一个 vite.config.ts 文件,之后开发者就能正常的在项目中创建单测文件:

运行测试
运行 vitest 的测试 case 有两种方式,一种是通过 Nx 的命令去启动测试任务,开发者可以直接通过 Nx Console 运行指定 package 的 test 命令:

另一种则是直接使用 vitest 提供的 vscode 插件来执行测试 case,在插件中可以可视化的查看每个 package 下的测试用例:

总结
本章主要介绍了如何借助 CDD 和 TDD 来提高代码开发效率,CDD 能够帮助开发者在不依赖业务逻辑的情况下快速开发验证组件,而 TDD 能够让开发者的将关注点从 ui 层转移到逻辑层,同时保证逻辑层代码的可测性。Nx 为了支持项目 CDD 和 TDD 开发,提供了相应的代码生成器。