Skip to content

Latest commit

 

History

History
192 lines (160 loc) · 7.02 KB

目录规范.md

File metadata and controls

192 lines (160 loc) · 7.02 KB

一个好的目录结构能够让你的开发效率事半功倍,也能够让新人快速熟悉项目,在合适的地方找到想要找到的东西。

为了达到这个目的,我认为一个好的目录结构应该遵循两个原则 - 分层与分类

首先分层与分类不是对立的,它们在目录组织中应该相辅相成。接下来我会用一个 简单的例子 来讲述它们之间的关系以及如何使用它们让你的目录结构更清晰。

directory-example
├─src
|  ├─App.tsx
|  ├─ui-components
|  |       ├─Header.tsx
|  |       ├─Table.tsx
|  |       ├─__tests__
|  |       |     ├─Header.test.tsx
|  |       |     └Table.test.tsx
|  ├─types
|  |   └some-globle-types.ts
|  ├─pages
|  |   ├─utils
|  |   |   ├─some-utils-cannot-be-a-model.ts
|  |   |   ├─__tests__
|  |   |   |     └some-utils-cannot-be-a-model.test.ts
|  |   ├─models
|  |   |   ├─Book.ts
|  |   |   ├─__tests__
|  |   |   |     └Book.test.ts
|  |   ├─book-list
|  |   |     ├─PageBookList.tsx
|  |   |     ├─models
|  |   |     |   ├─Books.ts
|  |   |     |   ├─__tests__
|  |   |     |   |     └Books.test.ts
|  |   |     ├─hooks
|  |   |     |   ├─usePageBookList.ts
|  |   |     |   ├─__tests__
|  |   |     |   |     └usePageBookList.test.ts
|  |   |     ├─constants
|  |   |     |     └some-reuseable-constants.ts
|  |   |     ├─components
|  |   |     |     ├─BookCard.tsx
|  |   |     |     ├─hooks
|  |   |     |     |   ├─useBookCard.ts
|  |   |     |     |   ├─__tests__
|  |   |     |     |   |     └useBookCard.test.ts
|  |   |     |     ├─__tests__
|  |   |     |     |     └BookCard.test.tsx
|  |   |     ├─__tests__
|  |   |     |     └PageBookList.test.tsx
|  |   ├─book
|  |   |  ├─PageBook.tsx
|  |   |  ├─hooks
|  |   |  |   ├─usePageBook.ts
|  |   |  |   ├─__tests__
|  |   |  |   |     └usePageBook.test.ts
|  |   |  ├─constants
|  |   |  |     └some-reuseable-constants.ts
|  |   |  ├─components
|  |   |  |     ├─BookDescription.tsx
|  |   |  |     ├─__tests__
|  |   |  |     |     └BookDescription.test.tsx
|  |   |  ├─__tests__
|  |   |  |     └PageBook.test.tsx
|  ├─modules
|  |    ├─utils
|  |    |   └.gitkeep
|  |    ├─request
|  |    |    └.gitkeep
|  |    ├─feature-toggle
|  |    |       └.gitkeep
|  |    ├─authorization
|  |    |       └.gitkeep
|  |    ├─authentication
|  |    |       └.gitkeep

pages

分类

首先是我们项目中的主体 pages 文件夹。在这个文件夹下我们的原则是每一个单独的 route path 作为一个单独的文件夹,文件夹的名字与 route path 保持一致,以 route path 来做页面的分类,并且在当前文件夹下以一个 PageXxx 的页面文件作为这个 route path 的入口。

pages
├─book-list
|     ├─PageBookList.tsx
|     |
├─book
|  ├─PageBook.tsx
|  |

这样做的好处是不论谁想找到哪一个页面,都可以轻易通过页面和 url 的对应关系快速找到这个 url 下的入口页面。

然后在当前文件下下,这个页面可能被拆分成不同的组件,于是有一个 component 文件夹来存放这些被拆分出来的组件。同理页面中用到的一个或多个组件将被存放在同级目录的 hooks 文件夹下。之前提到的业务建模将被存放于 models 目录下... 而每一个文件的测试将存放于该文件同级目录下的 __tests__ 目录下。

book-list
├─PageBookList.tsx
├─models
|   ├─Books.ts
|   ├─__tests__
|   |     └Books.test.ts
├─hooks
|   ├─usePageBookList.ts
|   ├─__tests__
|   |     └usePageBookList.test.ts
├─constants
|     └some-reuseable-constants.ts
├─components
|     ├─BookCard.tsx
|     ├─hooks
|     |   ├─useBookCard.ts
|     |   ├─__tests__
|     |   |     └useBookCard.test.ts
|     ├─__tests__
|     |     └BookCard.test.tsx
├─__tests__
|     └PageBookList.test.tsx

分层

同时我们不提倡页面间的相互引用,页面间如果出现了相互引用,那么也就意味着这个组件/方法/模型是一个多个页面可以共同使用的公共组件/方法/模型。我们会将它向上级目录“提取”,也就是分层。

这样做是为了让修改代码的人认识到,你正在修改的是一个不仅仅你在使用的东西,你需要保证自己的修改不破坏其他页面的功能。

pages 这个文件夹下还有可能产生一些其他的文件夹,比如 typesconstants 等。在不同的项目会有不同的叫法,只不过大原则不变 - route path 的页面作为分类,每一个类别中的东西大体相同,然后以引用者进行分层,自己的东西自己管理,大家的东西由上层管理

pages
├─utils
|   ├─some-utils-cannot-be-a-model.ts
|   ├─__tests__
|   |     └some-utils-cannot-be-a-model.test.ts
├─models
|   ├─Book.ts
|   ├─__tests__
|   |     └Book.test.ts
├─book-list
├─book
|

ui-components

聊完了 pages 目录,我们来看看大部分项目都会有的一些东西,首先是 src/ui-components 目录。如果已经理解了我们当前目录结构的思想,那么很显然这里的组件将会是全局通用的组件,这里的组件不应该包含任何业务逻辑。

那么为什么这些组件不遵循分类原则,由各个页面自己管理呢?

理论上每个项目都会有自己的 UI 设计,好的 UX team 还应该有自己的 design system。而 UI 组件就是这些设计的最终呈现,将它们维护在顶层符合“这是整个系统层面的设计实现”这一理念。既方便了管理和改动,又能够快速查看我们的组件哪些是已经有了的,哪些是还没有实现的。

更进一步,如果项目 B 也想使用同样的设计语言,这样的管理方式能够快速将其作为一个通用组件库剥离项目 A 将其应用的其它地方。

src
├─ui-components
|       ├─Header.tsx
|       ├─Table.tsx
|       ├─__tests__
|       |     ├─Header.test.tsx
|       |     └Table.test.tsx
|

modules

src/modules 下面则是全局通用的一些功能性方法,比如 request 的一些 client、config,比如用户的鉴权,比如项目中需要的一些功能开关等等。

src
├─modules
|    ├─utils
|    |   └.gitkeep
|    ├─request
|    |    └.gitkeep
|    ├─feature-toggle
|    |       └.gitkeep
|    ├─authorization
|    |       └.gitkeep
|    ├─authentication
|    |       └.gitkeep

到这里我们的例子就结束了,我并没有事无巨细地列出每一个文件夹,只是拿出一些典型的文件夹来解释我的目录结构的思想,如果大家需要的话,我可以在日后的更新中慢慢完善这个目录结构。