Git blog地址: github.com/asd0102433/…
喜欢的同学star支持一下,长期更新
项目的结构改过很多次,每次根据需求的复杂度慢慢的修改,总结下几种结构的特点。
按照文件类型划分,不是很复杂的项目可以这样规划。
|—— actions
|—— CommandActions.jsx
└── newAction.jsx <- here
|—— components
|—— Command.jsx
└── newComponent.jsx <- here
|—— containers
|—— Command.jsx
└── newContainers.jsx <- here
└── reducers
|—— command.jsx
└── newReducers.jsx <- here复制代码
上面这种是官方demo redux.js.org/docs/advanc…
结构,actions,reducers,containers中放着每个模块的对应的结构文件,看过去很清晰,但是有一个麻烦的地方,就是当你添加一个组件的时候你就需要在3个目录下操作,以及跨文件的管理对应的文件,有点不方便。
按照组件划分,一个组件包含自身action,reducers,style等相关的文件,这样在修改某些文件的时候就非常的容易。对于项目不存在很复杂的异步逻辑等可以参考这样的结构。
|—— app
|—— App.jsx
|—— reducers.jsx
|—— routes.jsx
|—— home
|—— index.jsx
|—— Home.jsx
|—— HomeActions.jsx
└── HomeReducer.jsx
|—— product
|—— index.jsx
|—— ProductList.jsx
|—— ProductActions.jsx
└── ProductReducer.jsx复制代码
如果项目十分的巨大,大量的模块用以上的2个方案不可行,首先复用模块和特定场景下的模块需要分开进行处理,页面的布局view必须整理出来,可以参考react boilerplate。
|——app
|—— component # 这里放的都是公共部分的组件
|—— Header # 使用 styled-components 来定义基础组件
└── Fotter
|—— containers # 页面容器
|—— HomePage
|—— ...
|—— index.js # 组织页面的结构, 私有模块和公共模块构成
|—— reducer.js # Home下的reducer逻辑
|—— component # 私有模块
|—— sagas.js # Home下的异步数据
|—— action.js
|—— ...
└── reducers.js # reducer复制代码
可以说这套项目结构很适合大型项目的组织,component下面包括了大量的通用组件,不管是项目的平台移植,模块复用都很好管理。containers下如HomePage/index.js有复用的模块以及页面场景下特殊的模块构成,同时index.js还负责模块跟redux store数据的链接,对应的每个场景都拥有自身saga,reducer等。构建大型的项目结构参考这个也是一个非常棒的。
react boilerplate 确实可以解决大型项目的结构问题,但是component 和布局结构混合在一起,并没有分离出去,下面这种结构分离了组件,布局模块,更好的管理项目(文件结构同时也增加了复杂度)。
|── src/
| |── views
| |—— Home.js # Home Page 页面
| |—— HomeRedux.js # Home Redux 集合
| └── Detail.js # Detail Page 页面
|—— redux
| └── reducers.js # 统一了views下的所有reducer
|—— layouts # layouts 负责整个app 的布局结构
| |—— Frame.js
| |—— Nav.js
|—— components
| |—— Common # 通用组件
| |—— Home # Home Page下用到的组件
| | |—— Preview.js
| | └── PreviewRedux.js # Preview组件用到的reducer, 以及action复制代码
layouts
代码
return (
<div className="frame">
<div className="header">
<Nav />
</div>
<div className="container">
// View下面的Page 都会在此
{ this.props.children }
</div>
</div>
);复制代码
有了layout页面的布局细分就更加直观,明晰了。在管理reducer的时候会相对的麻烦,views/ 下的主入口页面不但负责页面的结构,还需要整合 components/Home/ 文件下所有的模块的reducer,需要跨文件的处理。Home下Preview组件的reducer、action合并在一起,方便了修改同时控制自身的reducer业务逻辑(对于细分到组件的reducer,action本身逻辑也不会很庞大)。
比如 listReducer -> List ,确实很适合大型团队的分工合作。
接下来我们来看看react-starter-kit,
github.com/bodyno/reac…
github.com/bodyno/reac… 这个项目的结构使用的是 fractal(不规则碎片形:适合大型项目)*,方法的分组主要是依照特性而不是文件类型。注意,这个目录结构只是一个指引,并不一定要按这个来。这种结构谐在让程序更容易扩展
├── src # 程序源文件
│ ├── main.js # 程序启动和渲染
│ ├── components # 全局可复用的表现组件(Presentational Components)
│ ├── containers # 全局可复用的容器组件
│ ├── layouts # 主页结构
│ ├── store # Redux指定块
│ │ ├── createStore.js # 创建和使用redux store
│ │ └── reducers.js # Reducer注册和注入
│ └── routes # 主路由和异步分割点
│ ├── index.js # 用store启动主程序路由
│ ├── Root.js # 为上下文providers包住组件
│ └── Home # 不规则路由
│ ├── index.js # 路由定义和代码异步分割
│ ├── assets # 组件引入的静态资源
│ ├── components # 直观React组件
│ ├── container # 连接actions和store
│ ├── modules # reducers/constants/actions的集合
│ └── routes ** # 不规则子路由(** 可选择的)复制代码
routes 作为主入口,并且把所有路由对应的组件,assets, modules全部都集中在了一起,更像mvc的命名组织。reducer、action整合为modules, components作为view,container连接actions和store。
export const createRoutes = (store) => ({
path: '/',
component: CoreLayout,
indexRoute: Home,
childRoutes: [
CounterRoute(store),
ZenRoute(store),
ElapseRoute(store),
RouteRoute(store),
PageNotFound(),
Redirect
]
})复制代码
一个Counter模块包含如下:
Counter/
components/ # 页面的组件
containers/ # view 和 modules 数据对接
modules/ # 包含对应的 reducer, action
index.js # 页面入口,定义path复制代码
index.js 自动的注入reducer 到store,这样在顶层的store就无需要手动去整合每个模块自身的reducer。代码如下:
// 导入对应的redicer
const reducer = require('./modules/counter').default
/* Add the reducer to the store on key 'counter' */
injectReducer(store, { key: 'counter', reducer })复制代码
看完这套方案真的非常酷,个人觉得多人开发项目迭代产品更新,手动的修改整合顶层reducer是一件不好的事情。
项目的结构并非要跟上面相同,根据自己的需求和理解来构建自己的项目也是一件非常美好的事情。