React + Redux + TypeScript 实践一:目录结构划分

最近自己在写项目的时候,尝试了一把 TypeScript,发现很有意思,相比于 Javascript 这种弱类型语言,Typescript 作为其扩展,在类型校验代码设计模式上更加有优势,作为 React + Redux + TypeScript 的实践系列第一篇,先简单地介绍下我对前端目录结构的划分(不是最优划分,仅供参考):

ts-dict.png

  • client/common

    1
    2
    3
    4
    5
    client
    ├── common
    │ ├── config.ts(全局配置)
    │ └── utils.ts(通用方法)
    │ └── ...

    该文件夹主要存放一些全局通用的方法配置,比如 config.ts 可以存放全局需要的配置参数,utils 则可以直接编写一些全局通用函数。

  • client/components

    没啥好说的,存放全局通用 React 组件。

  • client/pages

    平时以开发单页应用为主,client/pages 用来存放不同
    url 对应的页面组件。

  • client/public

    存放应用的静态资源文件。

  • client/router

    1
    2
    3
    client
    ├── router
    │ ├── index.tsx

    client/router/index.tsx 用于设置整个应用的路由系统,采用的技术栈是 react-router-dom

  • client/store

    1
    2
    3
    4
    5
    6
    7
    8
    client
    ├── store
    │ ├── global-reducer(通用 reducer)
    │ │ ├── user.ts
    │ │ └── ...
    │ └── create-immutable-reducer.ts(创建不可变 reducer)
    │ └── create-store.ts(创建 redux store)
    │ └── root-reducer.ts(每个页面依赖的 reducer 集合)

    client/store 主要用于存放 Redux store 相关的文件,Redux 这块的架构我采用的 Ducks 结构,希望能尽量少的切换上下文,关于 Redux 的设计会放到后续系列着重讲解

  • client/services

    1
    2
    3
    4
    5
    client
    ├── services
    │ ├── axios(axios 二次封装)
    │ │ ├── ...
    │ └── index.ts(axios 请求函数集合)

    client/services 用来充当前端 client 层和后端 server 层的中间层,前端所有发起的请求均通过 services/index.ts 中定义的请求函数,关于如何在 TypeScript 的基础上通过 axios 库定义前端需要的请求函数,会在后续文章说明。

  • client/types

    1
    2
    3
    4
    5
    6
    7
    8
    client
    ├── types
    │ ├── event.d.ts(事件类型)
    │ ├── error.d.ts(异常错误类型)
    │ └── model.d.ts(实体数据类型)
    │ └── http-api.d.ts(请求与响应类型)
    │ └── store.d.ts(redux store相关类型)
    │ └── index.d.ts(上述类型集合输出)

    client/types 用来存放 client 层相关的类型声明文件,每个文件的内容会随着后续文章的重点而展开。

  • client/app.tsxclient/app.less

    1
    2
    3
    4
    client
    ├── app.less(应用全局样式)
    └── app.tsx(应用入口组件)
    └── ...

    除了上述的几个重要目录,client 目录下还有一些其他与这些重要目录平级的文件,其中作为入口文件的 app.tsx 会通过 reference 方式一次性地导入所有样式供整个 client 层使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    // 应用入口文件
    /// <reference path="./types/index.d.ts" />
    import * as React from 'react'
    import * as ReactDOM from 'react-dom'
    import { Provider } from 'react-redux'
    import { Router, Route } from 'react-router-dom'
    import {LocaleProvider} from 'antd'
    import zhCN from 'antd/lib/locale-provider/zh_CN'
    import createStore from './store/create-store'
    import CoreRouter from './router'
    import './app.less'
    const w = window as any
    const store = createStore(w.__INITIAL_STATE__)
    ReactDOM.render(
    <LocaleProvider key="provider" locale={zhCN}>
    <Provider store={store}>
    <Router history={history}>
    <Route path="/" component={CoreRouter} />
    </Router>
    </Provider>
    </LocaleProvider>,
    document.getElementById('root') as HTMLElement
    )