Directory Structure Strategy

Hi all,
Hoping to seed some discussion on what’s likely a fuzzy/opinionated/no right answer issue.

When your components/pages dir start to grow a bit unwieldy from running yarn rw g ... lots, have you developed strong preferences or suggestions or best practice with respect to maintainability and ease of onboarding?

  1. Do you think its better to build a directory structure that tries to map to user-flows with some utility folders?
  2. Or go with a utility approach eg, keeping cells together.
  3. Or just stick with the flat boiler-plate structure and ctrl+e (in VSC) and search by well named components (which I suppose would end up needing some structure anyway)
  4. Or something else?

Thanks in advance.

(I’m currently doing option three as below, but can sense it won’t stay viable with much more complexity (especially when trying to onboard a colleague))

wsl@tonysmachine:~/wsl/monsteraa$ find web/src/components -type d
web/src/components
web/src/components/GameCell
web/src/components/MyTicketDisplay
web/src/components/FullEditGameForm
web/src/components/OSMLocationPicker
web/src/components/CreateClubShortForm
web/src/components/ProfilePictureCell
web/src/components/OSMSearch
web/src/components/ClubGamesTab
web/src/components/GeneralGameForm
web/src/components/StatePagination
web/src/components/ClubProfileCell
web/src/components/Dashboards
web/src/components/Dashboards/DashboardHost
web/src/components/Dashboards/DashboardPlayer
web/src/components/MyClubsCell
web/src/components/FeatureComingSoon
web/src/components/SideBar
web/src/components/ClubMembersCell
web/src/components/FullScreenButton
web/src/components/Landing
web/src/components/Landing/subComponents
web/src/components/ProgressBar
web/src/components/ClubMembersTab
web/src/components/UploadEffectButton
web/src/components/FullNewGameForm
web/src/components/HeaderSideBar
web/src/components/ClubsCell
web/src/components/MyProfileCell
web/src/components/ClubGamesCell
web/src/components/ResponsivePopupWindow
web/src/components/PrettyToggle
web/src/components/LoaderCards
web/src/components/UserProfileCell
web/src/components/UploadClubProfileImageForm
web/src/components/UploadImageForm
web/src/components/HostClubsCell
web/src/components/EmailValidationCell
web/src/components/UserIcon
web/src/components/ClubInfoTab
web/src/components/UrlQueryPagination
web/src/components/ClubProfileImage
web/src/components/NewGameForm
web/src/components/GamesCell
web/src/components/AccountSettingsForm

I’m pretty much 3. I only use full text search/filenames, if it comes to me it could be flat. But my colleagues struggle with that.

1 Like

We have different “sides” to our website, e.g. part of it is for our customers (organizations) and another part is for our admin/superuser stuff. So everything that has to do with one side goes into a directory called that. We use the same structure in both the api/ and web/ (graphql/, services/, components/, and pages/) directories.

The components directory has a UI directory which holds our reusable components.

1 Like

I think it’s easier for onboarding and maintaining with option 1.
Because then you will easier recognize the structure.

On the other hand it can be a problem to decide where you want to place on component especially when it’s used on two sites.

We currently have some kind of a mix.

I’ve been moving towards #1 recently as the number of components and cells has grown a lot over the last year. I just prefer having some kind of hierarchical order. I tend to organize similarly to @lars - a separate directory in components/ and pages/ for things like admin and general purpose vs authenticated users. I worked through the tutorials and really wasn’t a fan of how the tutorial suggested naming cells/components differently for admin vs public-facing when they referred to the same underlying objects. As an app grows, it really becomes untenable having to think “wait, is this the model called ‘posts’ or ‘articles’?” I find it much easier to have cells and components reference the actual underlying Prisma model name, and differentiate them by hierarchy and naming. Page names in routes end up being like AdminBlog and then the userland page is Blog or whatever. Much more clean.

For the new RedwoodJS Studio, I’ve been placing some components within the cell that uses them (when not reused elsewhere). See: studio/web/src/components/GraphQLSchemaCell at main · redwoodjs/studio · GitHub

This cell imports:

import { GraphQLRelationshipsTable } from './GraphQLRelationshipsTable'
import { GraphQLSchemaDiagram } from './GraphQLSchemaDiagram'
import { GraphQLSchemaTables } from './GraphQLSchemaTables'

As these are components that use the data for the cell fetch. Each component here is in a TabPanel.

Other reused components, like basic LineCharts are in a separate component directory and used across cells/components.