Structure the website code for better collaboration
Goals:
- Reduce merge conflicts in pull requests
- Avoid having to re-edit the same file and potentially break something that is working well enough
Some Suggestions in Component Styles
- 1 component per file
- 1 export per file except for Types/Models
- Limit any methods indentation to 4
- Limit Components implementation to 200 lines
- Break up any component into smaller functions if they become too large
- Components used in by more than 4 other components, they belong in a common folder.
Suggested File Hierarchy
.
└── src/
├── components/
│ ├── UI/ # this will hold basic reusable web components
│ │ ├── index.ts # import * custom components
│ │ ├── [Component].tsx # Small Component (Explained below)
│ │ ├── [Component]/ # Large Component (Explained below)
│ │ │ ├── index.ts # import * components below
│ │ │ ├── components/ # component pieces composing a bigger one
│ │ │ │ ├── [Component].tsx # small Component
│ │ │ │ └── ...
│ │ │ └── [Component].tsx
│ │ └── ...
│ └── common/ # this will hold custom shared components
│ └── .. (Same struct as UI)
├── hooks/
│ ├── index.ts
│ ├── contexts/
│ │ └── [ContextProvider].tsx
│ └── use/
│ └── [useHook].tsx
├── app/
│ ├── Layout.tsx # Shared layout acros multiple pages
│ ├── Template.tsx # Optional (works similar to Layout)
│ ├── Error.tsx # Suspense will show this on page error
│ ├── Loading.tsx # Suspense will show this till data arrives
│ ├── Page.tsx # Actual Content of the Page
│ ├── components/
│ │ ├── index.ts
│ │ ├── [Component].tsx
│ │ └── [Component]/
│ │ ├── index.ts
│ │ ├── components/
│ │ │ ├── [Component].tsx
│ │ │ └── ...
│ │ └── [Component].tsx
│ ├── [Sub-Page]/
│ │ ├── Layout.tsx
│ │ ├── Error.tsx
│ │ ├── Loading.tsx
│ │ ├── Page.tsx
│ │ ├── components/
│ │ │ └── ...
│ │ └── [Sub-Page]/
│ │ └── ...
│ └── ...
└── styles/
├── themes/ # IF USING CHAKRA-UI
│ ├── ThemeProvider.tsx # Theme and switching Logic
│ ├── [LightTheme].tsx
│ ├── [DarkTheme].tsx
│ ├── [CustomTheme].tsx
│ └── ...
└── colors/ # IF USING STITCHES/Styled-Components
├── [LightColors].tsx
├── [DarkColors].tsx
├── [CustomColors].tsx
├── stitches.config.ts # Theme and switching Logic
└── ...
Motivation
- generally we create first a suite of basic components with Chakra to apply our theming
- the common folder is usually dangerous so we limit how much the components are used
- Big Components usually create merge conflicts so we break it in multiple components
- Small Components are the usual custom component that follow all rules
- index.ts is OPTIONAL but recommended to keep imports relative and clean ( also good for tsconfig paths )
Pros
- We avoid conflicts between each other when working on different features on the same page
Cons
- Prepare to have lots of files in the project
Note: Most of this is pulled from this issue comment with some shortening.
My personal opinions:
- It's too early to adopt Server Components and NextJS's app layout. That's still in beta and contributors in general wont' be familiar with using it at all.
- Whatever directory structure we want to maintain should be heavily documented in to
website/README.md - However we want to maintain dark mode, it should be easy for others to stay consistent with that.
For directory structure, I like the idea of a structure that follows what RedwoodJS setup. I have a RedwoodJS template package that follows this. The core directories are:
-
components: Any re-usable component. Each component gets its own folder and exports whatever components are needed. Testing and Storybook code goes in the components folder. -
layouts: Any layouts that get used across pages. -
pages: User visible pages and API routes -
theme: Any Chakra-UI styling that applies to the app or specific components. -
lib: Any library code that isn't a react component -
hooks: Any custom react hooks we might need
I think it's too aggressive to jump to this in any single PR. Nor is this critical for an MVP. But any PR that migrates to some better component packaging and testing will be greatly aprpeciate.d
For directory structure, I like the idea of a structure that follows what RedwoodJS setup. I have a RedwoodJS template package that follows this.
I tried accessing the repo, looks like its private I'm afraid...
Whoops, just made it public. Forgot that it was private.
goodproject
We're slowly migrating towards this direction. I'm going to close this as we settled on a direction and later make some smaller focused issues around more scoped things to fix.