关于redux项目结构问题

用react搭配redux写项目时你们都怎么组织你们的目录结构的?
我知道写的时候又两种结构:
第一种:

——src
    ——actions
    ——client.js
    ——components
    ——containers
    ——reducers
    ——routes
    ——store
    ——views
    

里面的views是什么内容?

第二种:

——src
    ——auth
        ——actions
        ——components
        ——reducers
        ——views
    ——client.js
    ——components
    ——containers
    ——products
        ——actions
        ——components
        ——reducers
        ——views
    ——routes
    ——store
    

如果项目功能比较复杂,模块比较多可以考虑第二种目录结构。
但是这里为什么没有containers?你们是怎么组织的?能不能发一下你们的项目目录结构?

另外,看到一些人把组件都写在一个文件你的,这样好吗?还是说一个组件就一个文件?不过这样好像又很散

下面这样的结构好不好?哪里需要改进?

——src
        ——module1/page-1      #其中的一个功能模块,也可以是路由中的一个页面
            ——actions         #模块相关的action
            ——reducers        #模块相关的reducer
            ——components      #模块相关的component
                ——comp-1.js
                ——comp-2.js
            ——containers      ##模块相关的container
                ——cont-1.js
                ——cont-2.js
        ——module/page-2
            ——actions
            ——reducers
            ——components
            ——containers
        ——client.js
        ——actions             #最外层的action
        ——reducers            #最外层的reducer
        ——components          #最外层的component
        ——containers          #最外层的container
        ——routes              #路由
        ——store               #store

或者你们有没有推荐的目录结构方案?最好详细点,要不然都不知道那些文件和文件夹是干嘛的,有相关对的文章推荐也可以

阅读 9.2k
4 个回答

还是回答的详细一点吧,不然有点水的感觉

========================================================

你说的都挺好的,简单的项目就简单的架构,复杂的项目就复杂点的架构。

基本的东西离不开这几样:

1、action

2、reducer

3、store

4、components

5、router

搭建redux项目之前,要先读几遍redux文档,redux是一个架构框架,react是一个js组件库,如果没有理解框架和库的区别,那么搭建的项目就会不伦不类了。

1、搭建一个基本的redux框架,暂未关联react,相关链接 redux英文文档

+ src
    + actions
    
    + reducers
    
    + store

2、action本身的框架不复杂,只有3个部分,那么,react又该放在react的哪个位置呢?每个人对工程架构的看法不一样,我说说自己的看法,目前基本可以分为2种方案:

一是react单独放在redux框架之外管理,我看到有些人的答案是这样的;

另外一种方案是react放到redux框架内部管理 redux官方也是这种方案,也是我个人推荐的。

重点讲讲第二种方案吧。为什么我会选择第二种,不是因为迷信官方权威,从我们中国人的思想来说,redux是前端项目的基础框架,既然是框架,无论他和什么js库搭配,都要万变不离其宗,redux就像前端项目的阴阳两极,里面涵盖了所有零零碎碎的各种js、css等资源,我不觉得把react从redux剥离开来管理是一个很好的方案,虽然只是换了个位置,但是不符合框架的思想。就好比你建一栋房子,外层框架是redux,里面装修的各种家具是react组件和样式等。

那么结合react之后的redux框架是个怎样的结构呢。参考 官方todolist方案

+ src
    + actions
    
    + components
    
    + containers
    
    + reducers
    
    + store

看到这里,基本的react-redux框架已经出来了,接下来,就是考虑自定义js插件、json、css、图片等资源的管理问题。js库的管理比较容易,再多定义一个utils包管理各种js插件工具,json资源就定义一个data包管理,难点在于css和图片该如何管理,是单独建立一个包来统一管理还是放到具体的组件内部包去管理呢?

我认为放到具体的组件包去管理对于开发来说有更大的好处,react的核心是组件,在一个前端团队中,每个前端成员都维护自己的组件模块,这些组件不只是js,还有css、图片资源,一个单独的组件包管理维护这些组件对于团队来说非常有效率,每个人写的组件代码互相没有任何影响,你的组件写错了,你去维护你的组件包,我的组件不需要做任何修改,你也不用打开我的组件包去看代码。

说了这么多,具体来看是怎样的一个文件夹模型呢。

+ src
    + actions
        home.js
        login.js
        global.js
    + components
        + Commons
            + files
            + styles
            header.js
            footer.js
        + Home
            + files
            + styles
            content.js
        + Login
            + files
            + styles
            login.js
    + containers
        + Home 
            home.js
        + Login
            login.js
    + reducers
        home.js
        login.js
        index.js
    + store
        index.js
    + utils

在这样一个模型中,假如你负责登录页面的模块,我负责首页模块,那么你只需要维护这么几个部分
1、actions中的login部分
2、components中的login部分
3、containers中的login部分
4、reducers中的login部分

我维护home相关部分的包,完全不会有冲突,要是你的组件出问题了,CTO就会找你算账,不会找到我头上,偶买噶,祝你好运!

先提出基础概念供参考: 组织代码的四大策略

以下说明组织Redux代码的一些组织说明。首先,根据Redux官方的这篇有关如何组职代码的问答文章中(中文的翻译在此),一共列了三种常见的方式:

Rails风格

又可以称为"依照类型(by type)"的集中组织方式。用actions, constants, reducers, containers, components等目录区分,文档名可以依功能或应用命名区分,这大概是最常见的一种。范例如下:

actions/
    CommandActions.js
    UserActions.js
components/
    Header.js
    Sidebar.js
    Command.js
    User.js
    UserProfile.js
    UserAvatar.js
containers/
    App.js
    Command.js
    User.js
reducers/
    index.js
    command.js
    user.js
routes.js
index.js
rootReducer.js

应用领域风格(Domain)

又可以称为"依照功能(by feature)"的集中组织方式。先以功能或应用领域不同的目录区分,目录里有各自的reducer、action等等文档,可以用文档命名再作类型区分。范例如下:

app/
    Header.js
    Sidebar.js
    App.js
    rootReducer.js
    routes.js
product/
    Product.js
    ProductContainer.js
    ProductActions.js
    ProductList.js
    ProductItem.js
    ProductImage.js
    productReducer.js
user/
    User.js
    UserContainer.js
    UserActions.js
    UserProfile.js
    UserAvatar.js
    userReducer.js

鴨子(Ducks)

鸭子是一种模组化Redux的代码组识方法,它是把reducers, constants, action types与actions打包成模组来用。鸭子可以减少很多目录与文档结构,例如下面的目录:

|_ containers
|_ constants
|_ reducers
|_ actions

改用鸭子后就会变成只有两个目录,也就是说把constants, reducers, actions都合并为模组就是:

|_ containers
|_ modules

鸭子有一些优点,也有一些明显的缺点。它在小型应用中是很理想的作法,你不用为了要加一个功能,至少需要开三、四个代码文档。它仍然有自订的空间,详细请参考这篇文章

结论

很明显的,并没有最好的一种代码组识法,实际上认真考虑起来,每种都有它的优点与缺点。代码组织方法是为了人而定的,只要对共享的与要重覆使用的代码文档能区分得清楚,团队间协同都能充份理解,实际上用哪一种都可以。官方的文档只有说要同时考量actions与reducers,以及selectors与reducers最好在一起声明,并没有说一定要用哪一种或哪一种比较好。以上的组识方式都可以混用,但最好以其中一种为主要组织方式。

CSS 用了 CSSModules

// 展示组件
—— components
        Question
            Index
                index.js
                styles.css
            List
                index.js
                styles.css
            index.js
                export * from './Index/'; // 到 webpack alias 配个名为 components
        Job
            index.js
            styles.css                

// 容器组件 - connect

—— containers
        Question
            index.js
                import { Question } from 'components'; // 全局引用
            constants.js
            actions.js
            reducer.js
            sagas.js
            selectors.js
        Job
            index.js
            constants.js
            actions.js
            reducer.js
            sagas.js
            selectors.js

我喜欢这个样子的:

—— app
    —— assets // 负责图片之类的静态文件
    —— views
        PageA.js
        PageB.js
        app.js
    —— containers
        —— PageA
        —— PageB
    —— components
        —— PageA
        —— PageB
    —— redux
        —— actions
            pageA.js
            pageB.js
        —— middlewares
            middlewareA.js
            middlewareB.js
            index.js // 整合middlewares,返回applyMiddleware
        —— reducers
            pageA.js
            pageB.js
            index.js // 负责整合reducers,返回combineReducers
        —— types
            PageA.js // 负责action用的types
            PageB.js
        index.js  // 负责整合上面的,返回store
    —— router
    —— styles // 负责公用的样式
    —— utils  

关于Views这个文件夹:

所谓的views,我这里应该理解为页面,一般是一个view就代表一个页面。主要负责把这个页面主要结构加入,然后返回一个页面。

举个栗子可能会说得明白点:
比如说ToDos这个项目,如果主体部分作为一个页面,应该分为三个容器Header, Section, Footer。那么这个项目的结构就是这个样子的:

—— components
    —— Todos
        Item.js
—— containers
    —— Todos
        Header.js
        Section.js
        Footer.js
—— views
    Todos.js

Todos.js的代码就是这个样子:

import React from 'react';
import Header from 'containers/Todos/Header';
import Footer from 'containers/Todos/Footer';
import Section from 'containers/Todos/Section';

export default class ToDos extends React.Component {
  render(){
    return (
      <div id="TODO">
        <Header />
        <Section />
        <Footer />
      </div>
    )
  }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题