-
Notifications
You must be signed in to change notification settings - Fork 13.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SIP-61] Improve the organization of front-end folders #13632
Comments
Thanks for the thoughtful proposal and comprehensive reasoning, @michael-s-molina ! I think this totally makes sense. Let's do it! |
sgtm! |
This looks great! Thank you for the well organized and researched SIP. I suggest removing "utils" as a category. In my experience, utils usually ends up being a disorganized grab bag of random things. I'd move "logger" to a "services" category, and split out the rest into either their feature folders, or into files organized by their domain ( |
Love this! |
Awesome @michael-s-molina! What do you think about putting the redux actions and reducers outside of the folders for the pages or features as they will usually align with the structure of the store and not necessarily be that closely related to the rest of the folder structure? |
Thank you all for your feedback! I really like the spirit of this community!
@suddjian and @eschutho Your comments are great and couldn’t be more related! I was reviewing the articles and I think we can kill two birds with the same stone! Some quotes from React Folder Structure in 5 Steps:
This is a picture from the article showing the organization: We can see that the organization follows the same logic as the components but this time using a services folder. So if a service is shared among features then it belongs to the first level. If it's something specific then it should go to the feature level. We can apply the same concept to utilities, actions and reducers. We can see in the image that date formatting (utility) is treated as service and that any level can contain a service folder depending on reusability. The same pattern is present in How to better organize your React applications? Sounds good? |
Sounds great! |
I feel that "store" and "hooks" are two sides of the same coin. If we're going to put hooks in a folder, it would make sense to me to put all of the store reducers and actions in a folder together as well, beside the hooks. Depending on how we structure the store after the single page app transition, I'm not sure that each file would line up with a "service". It's also helpful to be able to see all the reducers and actions in one place to get a sense of the structure of the store, imo. Thoughts on that? |
There will be a few setup storybook files that need to go somewhere... would those go in setup? One other small nit, can we also move toward getting all the folder/file names to be nouns? (I think addSlice is the only one for now) |
@eschutho Thank you for your comments.
Redux official documentation has a very nice guide on best practices for code structuring and they also recommend using feature folders instead of having all the reducers and actions in one place:
I also think it’s helpful to view the structure of the store. I just think that the best way to view that is using tools that assemble the store structure, especially when we use feature flags that dynamically alter this structure. Think about feature substitution, I can replace a feature and all reducers and actions that are specific to that feature can be replaced. Maybe the new feature doesn’t even use redux. So the structure of the store really depends on which features are enabled at the moment.
I understand your point. Maybe we can treat them as services as well. Our current hooks include date formatting, string manipulation, URL handling, etc.
In this type of scenario where we still don't have all the information available, I tend to tackle the problem in steps and delay the decision to a better point in time. So I think we can aim to keep all organized for now and reevaluate after we finish the single page app transition. Simplifying even more we could have:
Since this is an iterative approach I think this is a good starting point. When we have all code organized, and all the baggage learned while refactoring, it will be easier to evaluate if we need to further break the
I'm assuming you're talking about the plugins storybook right? If that's the case I think that plugins should have the same structure as the
If you are talking about
Totally agree. |
I think it's OK to have an |
@ktmud Indeed the |
Thanks @michael-s-molina. In my experience with redux, the services don't always (or usually) line up with the services, but they somewhat do for us for the most part, so I'm good with us trying this out for now. I think we should be mindful not to let the folder structure influence our store design. The best store designs that I have seen have little to do with the code or feature structure, so just as long as we keep an open mind as this evolves. :) |
Totally agree with you @eschutho! The open mind principle will be applied to all the decisions made here. I really think that once we have the first wave of organization, more will come and that can include reviewing some decisions! 👊🏼 |
Thank you @michael-s-molina - it seems like the discussion has settled down here quite a bit, and people seem at ease with the general intent and organizational concepts of this plan. If we run into any situations that raise further concerns in how we organize certain pieces (e.g. redux store structure, or utils becomes a junk drawer), we can bring the discussion back here for further elaboration and alignment. I know that I, for one, see more value to this effort than risk, so with that, I'm happy to put it up for a vote. |
The vote has officially passed! 🎉 Thanks @michael-s-molina for all the fantastic work here! |
I have a question here, if I have some test utils relevant for only for some specific folder like integration tests for |
@simcha90 If it's specific for
|
I plan to add linting rules here to track the remaining technical debt here and/or reinforce these standards. Just FYI. |
Anyone know what the next step(s) here ought to be? |
[SIP-61] Proposal for improving the organization of front-end folders
Motivation
The major motivation of this PR is to propose a better organization for our front-end folders.
This is our current structure:
As you can see I tagged each folder with its respective role in the application. This structure has some problems:
SqlLab
,addSlice
,annotationlayers
).src
espec
). Thespec
folder tries to mimic the same structure of thesrc
folder but has a lot of folders and components missing. This indirect relationship contributes to decreasing test coverage.With that in mind, this PR tries to achieve the following:
Proposed Change
The proposed change is based on a number of resources available. Here are some of them:
I took the liberty to paste some quotes from the sources:
The idea is to better organize our code structure to reflect a more modular approach. Applying those concepts to our code base is an iterative process by nature, so the following proposed structure is the result of the first iteration:
These are the changes:
src
, so we can moveimages
,stylesheets
, andstaticPages
to a folder namedasset
undersrc
.branding
folder is referenced and the same image is present in theimages
folder. So we can remove thebranding
folder and update the reference.components
folder. A component that is specific for a page should go inside that page.hooks
folder.pages
folder is the heart of the application. All the various features/screens/pages are defined here. Each page will have acomponents
dir. This will hold all the components that are required by only this page.setup
folder is responsible for the initialization code.types
folder are common types used throughout the application. When possible we should define types in the same files of their components.utils
folder contains all the utilities.src
folder alongside each component/page/hook/etc. The same is valid for mocks. When restructuring we should verify if a mock is shared or belong to a specific module.src
because it seems to be the common practice and because these tests are designed to span across multiple pages and workflows.Looking at a more detailed view of the structure, we should strive to organize our code in a more modular way. Some examples here for demonstration purposes:
An example of a common component with storybook and tests:
An example of a page:
Here we can see that we can create nested folders when necessary to better organize our code. Also, the most important aspect here is that the tests are close to the component and this will help to spot coverage problems in our application.
In the future we can iterate more on this structure until we reach something like this:
When we reach this point, all related code will be grouped together and it will be even easier to work with feature flags and A/B feature substitutions.
The proposed structure is not final. It is the result of the first iteration following the organizational principles described here. As we move forward in the organization of the folders, we can make different decisions motivated by technical restrictions or a better understanding of a component. The idea is to start the code organization by taking an iterative approach and construct a guideline in which all organizational decisions are justified and can be easily understood by the community.
New or Changed Public Interfaces
The intent of this PR is to not change any public interface.
New dependencies
No new dependencies.
Migration Plan and Compatibility
The idea here is to promote this organization through small PRs, using an iterative approach, to avoid abrupt changes and reduce conflicts with open PRs. Similar to what we did in the components folder. After every step, we should assess and review the structure.
We should also create from the start the documentation about the structure. We can write a section in
CONTRIBUTING.MD
or, because ofCONTRIBUTING.MD
size, another file likeFRONTEND_STRUCTURE.MD
. This documentation will guide the efforts and serve as a reference for the community.Rejected Alternatives
Another popular way to structure projects is to group similar files together, by file type or technical layers. This could be applied to small to medium projects but doesn’t scale as well as grouping by features.
Keep the structure as it is was also rejected because of all the problems listed above.
The text was updated successfully, but these errors were encountered: