michael-s-molina opened a new issue #13632:
URL: https://github.com/apache/superset/issues/13632


   ## [SIP] 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:
   
   ```
   branding (old files)
   cypress-base (e2e tests)
   images (images)
   spec (unit and integration tests)
   stylesheets (less files)
   src
      addSlice (page)
      api (one service)
      chart (components)
      common (common components and hooks)
      components (common components)
      CRUD (components)
      dashboard (page)
      dataMask (action, reducer and type)
      datasource (components)
      explore (page)
      filters (components)
      logger (utilities)
      messageToasts (components)
      middleware (initialization)
      modules (utilities)
      profile (page)
      setup (initialization)
      showSavedQuery (utilities)
      SqlLab (page)
      staticPages (assets)
      types (generic types)
      utils (utilities)
      views (multiple pages)
         CRUD
            alert (page)
            annotation (page)
            annotationlayers (page)
            chart (page)
            csstemplates (page)
            dashboard (page)
            data 
               database (page)
               dataset (page)
               query (page)
               saved query (page)
            welcome (page)
      visualizations (components)
   ```
   
   As you can see I tagged each folder with its respective role in the 
application. This structure has some problems:
   - Lack of organizational consistency. We don’t know if the folders are 
organized by features, pages, technical layers, modules, etc. They are all 
mixed.
   - Lack of naming consistency. Some folder uses camel case pattern while 
others use snake case (`SqlLab`, `addSlice`, `annotationlayers`).
   - Lack of test coverage. We have separate folders for tests and components 
(`src` e `spec`). The `spec` folder tries to mimic the same structure of the 
`src` folder but has a lot of folders and components missing. This indirect 
relationship contributes to decreasing test coverage.
   - Lack of documentation about the structure and its justifications. New 
contributors don't know where to develop new features or have difficulty 
finding a particular feature.
   
   With that in mind, this PR tries to achieve the following:
   - Create an organizational structure based on common best practices but 
tailored to our project
   - Create a document about the organizational structure for the community
   - Remove conceptual conflicts
   - Fix folder naming inconsistencies
   - Create an organizational structure that encourages testing and reduces 
coverage problems
   - Guide new features
   
   ### Proposed Change
   
   The proposed change is based on a number of resources available. Here are 
some of them:
   - [A feature-based approach to React 
development](https://ryanlanciaux.com/blog/2017/08/20/a-feature-based-approach-to-react-development/)
   - [React Folder Structure in 5 
Steps](https://www.robinwieruch.de/react-folder-structure)
   - [How to better organize your React 
applications?](https://alexmngn.medium.com/how-to-better-organize-your-react-applications-2fd3ea1920f1)
   - [Why React developers should modularize their 
applications?](https://alexmngn.medium.com/why-react-developers-should-modularize-their-applications-d26d381854c1)
   - [React Project Structure Best Practices for Scalable 
Application](https://www.devaradise.com/react-project-folder-structure)
   - [React JS— Architecture + Features + Folder structure + Design 
Pattern](https://saurabhshah23.medium.com/react-js-architecture-features-folder-structure-design-pattern-70b7b9103f22)
   
   I took the liberty to paste some quotes from the sources:
   
   > Organizing your code by modules means you start thinking around a concept 
where you break down your code into related pieces and provide a public 
interface to use your module. It helps maximize code sharing and reusability in 
different sections of your application and even on other projects.
   
   > Another important attribute of a module-based structure is the ability to 
replace one by another, as long as both modules meet the same requirements.
   
   > In a world where everything moves fast and new features replace old ones 
in no time, breaking your code by modules will give you the freedom to build 
multiple versions of them to facilitate A/B testing and fully replace old ones 
when your team is satisfied with the result.
   
   > Each component, scene, or service (a feature) has everything it needs to 
work on its own, such as its own styles, images, translations, set of actions 
as well as a unit or integration tests. You can see a feature like an 
independent piece of code you will use in your app (a bit like node modules).
   
   > Code is structured in a way that reflects purpose.
   
   > Code is easier to refactor.
   
   > Organizing an application as a series of features can make feature flags 
easier to implement.
   
   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:
   
   ```
   cypress-base (e2e tests)
   src
      assets (common assets)
         images (images)
         staticPages (assets)
         stylesheets (less files)               
      components (common components)
         chart (components)
         dataMask (action, reducer and type)
         datasource (components)
            CRUD (components) - this folder won’t exist. It’s here just to show 
where the components went.
         messageToasts (components)
         visualizations (components)
            filters (components)
      hooks (common hooks)
      pages
         addSlice (page)
         alert (page)
         annotation (page)
         annotationLayers (page)
         chart (page)
         cssTemplates (page)
         dashboard (page)
         database (page)
         dataset (page)
         explore (page)
         profile (page)
         query (page)
         savedQuery (page)
         sqlLab (page)
            api (one service)
         welcome (page)
      setup (initialization)
         middleware (initialization)
      types (common types)
      utils (utilities)
         logger (utilities)
         modules (utilities)
         showSavedQuery (utilities)
   ```
   
   These are the changes:
   - All folders with camel case naming.
   - The majority of articles put the assets inside `src`, so we can move 
`images`, `stylesheets`, and `staticPages` to a folder named `asset` under 
`src`.
   - Only one image of the `branding` folder is referenced and the same image 
is present in the `images` folder. So we can remove the `branding` folder and 
update the reference.
   - All components that are shared across the application are inside the 
`components` folder. A component that is specific for a page should go inside 
that page.
   - All common hooks are inside the `hooks` folder.
   - The `pages` folder is the heart of the application. All the various 
features/screens/pages are defined here. Each page will have a `components` 
dir. This will hold all the components that are required by only this page.
   - The `setup` folder is responsible for the initialization code.
   - The `types` folder are common types used throughout the application. When 
possible we should define types in the same files of their components.
   - The `utils` folder contains all the utilities.
   - All the specs were moved to the `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.
   - I opted for leaving e2e tests outside of `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:
   ```
   src/components/Button
      Button.test.tsx
      Button.stories.tsx
      index.tsx
   ```
   
   An example of a page:
   ```
   src/pages/sqlLab
      actions
         sqlLab.ts
         sqlLabl_spec.tsx
      components
         QueryTable
            index.tsx
            QueryTable.test.tsx 
         ResultSet
            index.tsx
            ResultSet_spec.tsx
      reducers
         sqlLab.ts
         sqlLab.test.tsx
      utils 
   ```
   
   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:
   ```
   src/pages/sqlLab
      FeatureA
         actions
         components
         reducers
      FeatureB
         actions
         components
         reducers
   ```
   
   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 of CONTRIBUTING.MD size, 
another file like FRONTEND_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.
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to