Improving the structure of the frontend codebase #118
Replies: 3 comments 4 replies
-
After reviewing various opinionated guides on how to structure NextJS projects, here's the newly proposed structure. A global changeTo make it easier to distinguish project and configuration files, we will move most folders within a Note: we'll add special configuration so that import paths can avoid using the Simply move under
|
Beta Was this translation helpful? Give feedback.
-
Thinking about it, you're right about not creating the I see and agree with your point about administration vs personal settings. It might make sense for the two things to be completely separate. I was trying to think about how to frame this in our "pro-plurals" mode, but I'm struggling to find something I like. I'm kinda tempted to divide it between |
Beta Was this translation helpful? Give feedback.
-
Summary of changes to the initial proposal discussed so far:(Ms. Boba, I am assuming you agree with my suggestions from my last comment above, squeak if not :P)
Additional thing for discussion:In terms of where things currently in the utils folder are going, here are my thoughts: |
Beta Was this translation helpful? Give feedback.
-
Premise
The last "annoyances be gone sprint" has highlighted the less-than-ideal shape of our frontend codebase. While the structure of the backend codebase is generally appreciated, and the structure of the components codebase has been polished as part of the sprint itself, the structure of the frontend codebase is still full of puzzling choices, the logic of which mostly resides in my own head.
Goal
Improve the structure of the frontend codebase, making it easier for all contributors (especially beginners) to quickly find their footings.
This discussion starts with an overview of the current codebase structure (this post), and will continue with a proposed solution (next post). Comment as you see fit.
The current top-level folders
I've excluded the standard ones like
.circleci
/.github
.Shallow folders
This is an overview of the folders with a mostly-flat structure, or that otherwise don't require a lot of explanation.
cache/
This folder contains methods related to updating the values held in the "queryClient" cache. This is extremely tied to our usage of ReactQuery and would benefit from being colocated with the general handling of queries.
pages/
This is a NextJS-specific folder, and it will stay as it is. Files there map to the structure of the site itself.
public/
Also a Next-JS specific folder. These files are accessible as
http://[website-url]/file-path-without-public/
.Note that a lot (most?) of these files are not currently used by the software. We should do an effort to get rid of the useless ones at some point.
types/
The type definitions for the frontend, mostly shoved into a
types.tsx
file. The folder will likely stay, but we should consider splitting up the definition in more files. There's also type definitions generally scattered around the frontend, so we might need to discuss what we want to colocate and what we want to keep here.I have a general gut feeling we might eventually decide to get rid of this once the server publishes its own types and we can choose whether to derive the frontend ones from them. For now, however, I would consider it as here to stay.
queries/
The top-level
queries/
folder (as opposed to theutils/queries/
folder) contains hooks that abstract data fetching withreact-query
. This is AFAIU considered a best practice (see e.g. https://tkdodo.eu/blog/practical-react-query#create-custom-hooks, from one of the corereact-query
maintainers).utils/
Some people say that having a folder named "utils" is a code smell. This folder does nothing to convince me they're wrong (though they might be).
We might want to go through this file by file and see if there's a better place for them once our frontend structure is better defined, and consider putting something here only as a last resource.
utils/queries/
All the functions that do direct calls to the server and return data to the client, or at least all the ones I did before I started creating
react-query
hooks inqueries/
(see above). We should just fold these in thereact-query
hooks.Rabbit holes
This is an overview of the folders with a lost of nested folders within. These will likely require the most thought/refactoring.
contexts/
This folder contains only some of the Contexts we have around the codebase. I had moved these in their own folder because I felt that the concept of "context" doesn't really fit in the
components/
folder.The contexts defined outside of the
contexts/
folder are:components/Auth.tsx
: this doesn't even have context in the name, and it's indeed one of the first ones I've written. Should be killed with fire and rewritten. As for its placement, this is a global context for the app that wraps every page (and is indeed imported in_app.tsx
).components/editors/EditorsContext
: the whole "editors" folder is not exactly my proudest code (also a very old part of the codebase). This could also use a refactoring. This is not a global context, and it's specifically added to pages that can actually launch an editor. This might change once we allow opening an editor without a board selected, which makes it possible to create threads from any page.components/thread/ThreadContext.tsx:
this is used to provide components used in thethread/...
pages with computed information about the currently-displayed thread. I have mixed feelings about the necessity of this Context, but I do think it simplifies logic overall. It would do it more, however, is it was better documented AND more thought was given to the information it surfaces.components/
There are multiple categories of subfolders here:
boards/
,feed/
,thread/
,setting/
,realm/
(though I'd consider this latter as the "realm admin
" branch ofsetting/
)editors/
,options/
(arguablylayout/
)use
, all thrown together in the same pot":hooks/
An interesting case is the
ThreadPreview
component, which is used in bothboards/
andfeed/
, and thus stays in the perennial limbo ofcomponents/
itself. The top-level files here also include general components that have no specific place (LoadingSpinner
,UpdateNotice
,LoginModal
), and could have maybe gone inlayout/
.OpenGraphMeta
is a global component that handles the open graph definition for each page, andQueryParamNextProvider
is not a Context per se, but acts like one and is used globally in_app.tsx
.e2e/cypress/
Most of the folders here are
cypress
config folders, and are empty, even! The actual tests are in theintegration/home
folder, and we really don't have as many as we should. I'm strongly considering swappingcypress
forplaywright
, and this folder should go away with the change.The main sin of this folder is that we have both
e2e
andtests
as top-level folders, which is just confusing.tests/
This folder is all over the place. There are multiple categories of subfolders here:
board-utils/
,cache/
,location-utils
,thread-utils
data/
: this contain some standard data definition used across tests. I'm unsure how this is meaningfully different fromserver-mocks/data
.server-mocks/
: definitions for Mock Service Worker handlers, used to mock server requests. Only used by tests in theUI/
subfolder.UI/
: component tests, including a specialhooks/
folder for testing hooks, and autils/
folder with (1) jest custom matcher, some code to mock all the required contexts within pages, and some MSW utilities.We also have a top-level
utils.ts
file that contains questionable functions to generate a fake post/comment.Regardless of what we decide to do with tests (e.g. do we want to colocate them as much as possible with the files they're testing? what about e2e tests?), this is not an acceptable structure.
The current top level files
The ones I'd like to get rid off are:
.babelrc
: there has to be a better way, assuming this is even useful at allmgdns_proxies.js
: sunsetted in favor ofbonjour_proxies.js
. Everything related should be eliminated.This is all for the "describing current crimes" section. I'm going to absorb this and think about possible solutions, then I'll write an actual proposal in the next few days. Comments are open and encouraged for any questions/thoughts.
Beta Was this translation helpful? Give feedback.
All reactions