Skip to main content

App: Web App

The App Web App is a monolithic frontend application built with ReactJS and TypeScript. Using Vite as the bundling tool allows us to achieve high build performance, significantly enhancing the development experience. Utilizing Redux Toolkit Queries with both REST and GraphQL requests enables easy and predictable server interactions while maintaining consistent client-side state, providing a smooth user experience thanks to built-in caching mechanisms.

Additionally, the use of Service Workers and Progressive Web Application (PWA) capabilities enhances the user experience by preloading necessary data before the user even requests it, and leveraging request caching.

Despite the monolithic nature of our frontend application, it is divided into the following layers:

Diagram

Structure

Components

Components that are system-agnostic. These may include various enhancements to AntD and more complex forms like Calendars. The main requirement for this layer is that it cannot reference domain-dependent layers (core, redux, views).

Core

Domain-dependent but abstracted from ReactJS. This layer should not contain any .tsx files or use any React features (hooks, etc.), nor should it include presentational logic. This layer has no dependencies on other layers.

In the near future, we may phase out the core layer and merge it with the redux layer.

Redux

The core of server interaction and state management. This includes the configuration of our Redux Toolkit Queries, REST requests to the server, GraphQL queries, and type declarations for server responses. It is likely that this layer will eventually absorb our core layer.

Views

The most important layer of our application, consisting of what we call Panels (a more appropriate term would be "widget," as it better describes what a Panel does). These are components with a minimal set of props (ideally not exceeding an "id") and can be independently displayed as standalone widgets or in combination on a page.

Only components declared as Panels can interact with Redux (similar to Dan Abramov's Containers, but Panels also dictate a simplified API) and include Panels in their rendering tree. Panels can render other Panels within themselves, orchestrating more complex UIs without duplicating behavior.

Each folder within the "views" directory should contain only one Panel (with exceptions for Common folders or when one logical panel has two presentations). Thus, the "views" directory effectively serves as documentation for all the widgets in the system.

When writing "views," we recommend avoiding "wrapping" markup such as modal dialogs (), cards, or titles. This allows the same widget to be used in different presentations, for example:

  • An order list can be displayed on a standalone page and also on a dashboard as a card.
  • An order form can be displayed on a standalone page (Checkout) or in a modal dialog on the product page after clicking "Order Now."

Pages

Pages orchestrate panels and essentially define what the application will include by constructing pages from the building blocks in the views. Pages, and only pages, are aware of the URL context in which they are displayed and can extract parameters from the URL string. We recommend keeping them as simplified as possible, creating necessary widgets from building blocks. However, they may contain local components for code decomposition within the page.

Each page has its own separate folder, making the "pages" directory a reference point to view all pages within the application.

Including the configuration files located in the root src folder, pages along with them represent what is sometimes referred to as the app in monorepo projects.

Utils

Domain-independent library extensions or wrappers, as well as utilities that cannot be natively placed in components without being components themselves (e.g., useRandomColor()).

Assets

Static resources such as icons, localization files, or SCSS files. Note that SCSS files in assets are global and not tied to specific components or widgets declared in views and components. These should have a ComponentName.module.scss file located nearby.