Skip to content

Instantly share code, notes, and snippets.

@ryanflorence
Last active September 7, 2022 07:36
Show Gist options
  • Save ryanflorence/110d4538bf98694538de to your computer and use it in GitHub Desktop.
Save ryanflorence/110d4538bf98694538de to your computer and use it in GitHub Desktop.
.
├── actions
├── stores
├── views
│   ├── Anonymous
│   │   ├── __tests__
│   │   ├── views
│   │   │   ├── Home
│   │   │   │   ├── __tests__
│   │   │   │   └── Handler.js
│   │   │   └── Login
│   │   │   ├── __tests__
│   │   │   └── Handler.js
│   │   └── Handler.js
│   └── SignedIn
│   ├── __tests__
│   ├── lib
│   │   └── components
│   │   ├── __tests__
│   │   └── Avatar.js
│   ├── views
│   │   ├── Courses
│   │   │   ├── __tests__
│   │   │   ├── views
│   │   │   │   ├── Assignments
│   │   │   │   │   ├── __tests__
│   │   │   │   │   └── Handler.js
│   │   │   │   ├── Default
│   │   │   │   │   ├── __tests__
│   │   │   │   │   └── Handler.js
│   │   │   │   ├── Grades
│   │   │   │   │   ├── __tests__
│   │   │   │   │   └── Handler.js
│   │   │   │   └── Users
│   │   │   │   ├── __tests__
│   │   │   │   └── Handler.js
│   │   │   └── Handler.js
│   │   └── Dashboard
│   │   ├── __tests__
│   │   ├── components
│   │   │   ├── __tests__
│   │   │   ├── Stream.js
│   │   │   ├── StreamItem.js
│   │   │   ├── TodoItem.js
│   │   │   └── TodoList.js
│   │   └── Handler.js
│   └── Handler.js
└── main.js
@phaedryx
Copy link

Curious what all of these "Handler.js" files look like.

@joelhooks
Copy link

+1 to @kentcdodds's "tests next to unit being tested". This encourages looking at tests and makes them harder to ignore. Also easily filtered at build-time.

@ryanflorence
Copy link
Author

@phaedryx they're React Router RouteHandlers. Its a react component, but it represents the "entry" point into the app at that level.

@nb
Copy link

nb commented Jan 12, 2015

Cool, I love the recursive structure. Few things I am curious about:

  • How closely does the directory structure match your URL structure?
  • Is Default a semi-special name meaning the index page, or in this case it’s a domain-specific name we just don’t know about.
  • Do I understand correctly that components in views/Section/components/ should be used only in views/Section/Handler.js or in other components in the same directory?
  • Do handlers have UI-specific markup or usually just delegate to other components?
  • Where would be place components used by the whole system (imagine you needed Avatar.js in Anonymous/Home). Would it be in /lib/components/ (outside of /views), or in /views/lib/components (usually in views we don't have anything except dirs)?

Thanks!

@bsbeeks
Copy link

bsbeeks commented Jan 12, 2015

+1 on @nb's last point. How would you structure global components that would be used in to both Anonymous and SignedIn? I'm guessing a root 'lib' directory with a 'components' directory within that?

@mzabriskie
Copy link

@nb @bsbeeks shared stuff goes under /shared:

app
├── shared
│ ├── actions
│ ├── components
│ ├── lib
│ ├── stores
│ └── utils

@mrtnbroder
Copy link

Nice structure, I really like it!

What I don't like is that you call every component Handler.js that kinda makes file search a pain. That's why I give every component a proper name. Take a look at my fork if you like.

I also added an assets folder, where I would put static stuff like images, css and so on.

@irvinebroque
Copy link

This is rad.

I've also been splitting up views and components that render differently based on device type into separate entry points:

    ├── views
    │   ├── Navigation
    │   │   ├── __tests__
    │   │   ├── components
    │   │   │   ├── mobile.js
    │   │   │   ├── desktop.js
    │   │   │   │   ├── __tests__
    │   │   └── Handler.js

This makes it much easier to generate separate bundles for desktop vs mobile, and a lot more clarity within views (fewer ternary and if else statements based on environment -- just put them in Handler.js). Handler ends up behaving more like a controller -- it fetches data, checks permissions, etc., while the components handle the UI rendering.

I've found this really helps when views start growing past a few hundred lines of code, which happens fast when you write css in js.

@mrtnbroder
Copy link

Why don't you put the styles in a seperate file then @irvinebroque?
Also it's bad practice to separate desktop and mobile stuff. Better find a responsive solution.

No hating here, just a friendly tipp :)

@lesterzone
Copy link

What about structure by feature, LIFT principle:

.
├── app.js
├── categories
│   ├── categoryActions.js
│   ├── categoryStore.js
│   ├── categoryUtils.js
│   └── components
│       ├── form.js
│       └── list.js
├── core
│   └── dispatcher.js
├── router.js
├── routes.js

No more than 3 levels

@srph
Copy link

srph commented Apr 13, 2015

├── app
  ├── lib
  ├── components
  ├── handlers
    ├── home/
      ├── components/
        ├── ...
      ├── HomeView.jsx
      ├── styles.less
    ├── about
    ├── login
    ├── logout
  ├── index.js
  ├── routes.js
├── core
  ├── actions
  ├── stores
  ├── utils
  ├── config.js
├── dashboard
├── public
├── style

the app directory is basically similar to the dashboard directory. We're currently implementing this structure (having the app and dashboard in the same repo), and them have separate builds for them 😄

@samuelazran
Copy link

+1 to @kentcdodds

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment