-
Star
(190)
You must be signed in to star a gist -
Fork
(25)
You must be signed in to fork a gist
-
-
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 |
My folder structure is similar to this and I totally agree with the philosophy. One difference I have is instead of a __tests__
folder, I put the test file next to what it's testing (like TodoList.test.js
). Totally love the idea of mini-standalone apps inside of a bigger app. I feel like it allows you to be more flexible.
Curious what all of these "Handler.js" files look like.
+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.
@phaedryx they're React Router RouteHandler
s. Its a react component, but it represents the "entry" point into the app at that level.
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 inviews/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
inAnonymous/Home
). Would it be in/lib/components/
(outside of/views
), or in/views/lib/components
(usually inviews
we don't have anything except dirs)?
Thanks!
+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?
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.
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.
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 :)
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
├── 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 😄
+1 to @kentcdodds
Traditionally an app has several root folders that files get organized into. Folders like
tests
andcomponents
get enormous and terrifying, they also don't make it clear which components are reused, and which are only used in one view.This new structure in the gist turns the your app into, quite literally, a bunch of mini apps, each with their own set of "root" folders like
tests
,components
,views
,stores
,actions
, etc.If a module is shared among child views, it moves into the parent's
lib
folder. It might make its way all the way to the rootlib
folder.Its just a big recursive structure because that's what an app is. Let's embrace it in our file system.
Etc.