React + TS + TDD 扫雷游戏学习心得
试玩地址:https://goldenaarcher.com/minesweeper,stroybook 的地址:https://www.chromatic.com/build?appId=63b2530f575ed5942cf105be&number=1
测试主要使用 jest(mock)+ RTL 实现的,覆盖率还行:
有些特别低的因为 storybook 没测试:
用到的技术栈有:
-
TypeScript
-
React + Redux + React Router
-
Jest + RTL + stryker
stryker 是一个 mutation test 的工具,这个我倒是用的不多,就稍微试着配置了一下
-
storybook + chromatic
storybook 是个 UI 的……我觉得算是文档化代码的工具?chromatic 是用来部署 storybook 的工具,大概效果如下:
这是 grid 组件:
大致上说配好一些假数据,就可以直接在 storybook 上看到该组件的使用方式,以及所接收的参数。
基本上来说是比较完整的一套流程了,项目结构如下:
components 主要的是 UI 组件,core 主要是 util,modules 则是分别用 hooks、useReducer(仍旧用了 redux,不过没有配置 store,以及完整的 redux(配置了 store)。
一些学习心得:
-
最难的部分还是写测试,使用 CRA 的一个坑就是,UI 一旦产生了变化,snapshots 测试的时候旧有的 snapshot 没删掉,然后就继续报错,这个配置之后还是得找一下怎么弄。
-
TS 的一些工具真的很好用
比如说 utility type 中的 record:
export type Cell = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12; export const CellState: Record<string, Cell> = { empty: 0, bomb: 9, hidden: 10, flag: 11, weakFlag: 12, };
这个时候指定的返回类型就是
{string: cell}
,在进行实现的时候,TS 也会检查后面使用的的 CellState 是否符合这个规范。比如说 redux 状态的类型,之前的写法将所有的状态全都枚举了出来,不过现在才发现这个小技巧:
export const store = configureStore({ reducer: { game: reducer, }, }); export type RootState = ReturnType<typeof store.getState>;
不知道这是不是 redux toolkit 新增添的,还是原本就有。
-
使用 memo 和 usecallback 的确可以大幅度的降低重复渲染的问题
不过 memo 和 usecallback 这两个使用的成本也挺大的,在什么时候应该正确的使用这两个 hooks 也是需要更加深入的研究一下才行。
-
jest + RTL 的搭配真的很好用
尤其是 jest 需要 mock 一些函数的时候:
const mockSetSearchParams = jest.fn(); jest.mock('../../core/Field'); jest.mock('react-router-dom', () => ({ useSearchParams: jest.fn(), })); beforeEach(() => { jest.clearAllMocks(); (useSearchParams as jest.Mock).mockReturnValue([ { get: () => null }, mockSetSearchParams, ]); });
测试这方面还是得多看一下啊。