Let's create a Clean React Js Project with Typescript And Mongez Part II: Project Structure
Tags: react, typescript, mongez
Published: 2022-09-02 14:55:39

---
title: Let's create a Clean React Js Project with Typescript And Mongez Part II: Project Structure
published: true
description: 
series: React Mongez
tags: reactjs, typescript, mongez
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
---

Let's continue with part two of the React Mongez app series with the project structure.

## The Project Structure

Once you open the editor, you'll see the following structure:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cipja6b2zt447phrt40k.png)

Let's go with the structure and the important files/directories.

### Dot Env Files

You'll notice there are two `.env` files, `.env` and `.env.production`, the purpose behind this is to separate the development configurations from the production configurations so you won't have to change the `.env` file each time you make a new build

For now the two files have the same content, but we 'll talk about `.env.production` in the production section, so let's see the `.env` file

```bash
# Disable ESlint error
ESLINT_NO_DEV_ERRORS=true

# App Name
REACT_APP_NAME="blog"

# App Description
REACT_APP_DESCRIPTION=

# App Code Name
REACT_APP_CODE_NAME="b"

# Branch Name
REACT_APP_BRANCH_NAME="main"

# App default locale code
REACT_APP_DEFAULT_LOCALE_CODE=en

# App Fallback locale code
REACT_APP_FALLBACK_LOCALE_CODE=en

# App default direction
REACT_APP_DEFAULT_DIRECTION=ltr

# App Primary Color
REACT_APP_PRIMARY_COLOR=#000

# App API URL
REACT_APP_API_URL=

# App API Key
REACT_APP_API_KEY=
```

Let's go through the file properties quickly:

- `ESLINT_NO_DEV_ERRORS`: will disable the unnecessary eslint errors that keeps popped up in the browser.
- `REACT_APP_NAME`: will be added as the project title by default in `public/index.html` file.
- `REACT_APP_DESCRIPTION`: will be added as the project meta description in `public/index.html` file.
- `REACT_APP_CODE_NAME`: Useful for caching prefixes and encryption keys.
- `REACT_APP_BRANCH_NAME`: can be used to distinguish between branches in the cache prefix, will be discussed later when we reach the `src/shared/config.ts` file.
- `REACT_APP_DEFAULT_LOCALE_CODE`: Default application locale code, will be added in the html tag as `lang` attribute in `public/index.html`
- `REACT_APP_FALLBACK_LOCALE_CODE`: Fallback language when a translation key is missing from language so it will search in the fallback language keywords list.
`REACT_APP_DEFAULT_DIRECTION`: Default direction, will be added in html tag as `dir` attribute in `public/index.html`.
- `REACT_APP_PRIMARY_COLOR`: Primary Color for the app, will update the meta `theme-color` in `public/index.html` file.
- `REACT_APP_API_URL`: Define the API Base Url.
- `REACT_APP_API_KEY`: Define the Api Authorization Key.

### Package.json File

In the `package.json` file we will look into sections, `scripts` and `_moduleAliases`

Scripts have some quite interesting commands other than the normal ones:

- `build:prod`: will make a build for production using `.env.production` settings instead of `.env` file.
- `postinstall`: will remake the aliases after each install.
- `dev`: can be used to make your application's packages up to date then start the project.
- `update`: will run [npm-check-updates](https://www.npmjs.com/package/npm-check-updates) command to update the project packages to latest updates.
- `lint`: Run the eslint command to check for errors based on `eslintrc.json` configurations.
- `fix`: will run the eslint to fix errors as could as possible based on `eslintrc.json` configurations.
- `format`: will run the prettier to properly format the files based on `prettierrc.json` configurations.

The second property will be `_moduleAliases` that stores the paths aliases thanks to [link-module-alias](https://www.npmjs.com/package/link-module-alias).

In nutshell, this will allow us instead of setting the paths as relatives to be absolutes,

Before:

```tsx
import BaseButton from './../../design-system/components/Button';
```

After:

```tsx
import BaseButton from 'design-system/components/Button';
```

This will make your code neat and if you move your file from directory to another you won't have to update your imports.

What you will usually is `design-system` which contains your styling components and themeing, `app` for base project app which is located in `src/apps/front-office` and `user` for managing current user (if the application has a user management system).

### The src Directory

Now we are done with the outside files, let's dive into the `src` directory, which will look like:

![Mongez React Src Directory](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/izgh5p7qth0wx0l8rmfk.png)

the src directory contains two important directories and one file:

- `apps`: which contains all our project apps, i.e `front-office` to the website and we can add `admin` app for the admin panel.
- `shared`: contains the shared data, files, styles and assets between all apps.
- `index.ts`: The application bootstrap file.

### src/index.ts file

If we look at the file, it will be something like this:

```ts
import startApplication from "@mongez/react";
import "./shared/apps-list";
import "./shared/config";

startApplication({
  debug: true,
});
```

The `startApplication` function will be the anchor function to fire up our application, alongside with the `apps-list` file which defines our apps structure (for lazy loading) and lastly the base configurations file `src/shared/config.ts`.

These are the available configurations that can be passed to `startApplication` function.

```ts
import { ReportHandler } from "web-vitals";

declare  type ApplicationOptions = {
    /**
     * Determine whether to enable debugging mode or not
     *
     * @default false
     */
    debug?: boolean;
    /**
     * Debug method that is passed to reportWebVitals function
     *
     * @default console.log
     */
    debugMethod?: ReportHandler;
    /**
     * Detect current used device and browser such as google chrome, ipad, tablet and so on
     *
     * @default true
     */
    detectDeviceAndBrowser?: boolean;
    /**
     * Detect Dark Mode based on user's preferences, if found then a `dark` class will be added to body
     *
     * @default true
     */
    detectDarkMode?: boolean;
    /**
     * Determine whether to use the application in strict mode
     *
     * @default true
     */
    strict?: boolean;
}
```

Keep in mind that the `debug` feature works with debugMethod which by default is set to `web-vitals` reporting system, you may of course enable or disable or even change the debugger, totally up to you.

When setting `strict` to true **which defaults to true** it will wrap the application in `React.StrictMode`

If `detectDarkMode` is enabled, the `dark` class will be appended to html tag.

> By default Mongez React will try to detect the browser name and the device type, so you may see classes like `chrome desktop dark` in the html tag.

### The Shared directory

Mainly this folder contains two files and one directory `config.ts` `apps-list.ts` and `assets` directory, let's go quickly over it.

We can import any file from it using its direct alias `shared/file-path-to-import` for example to import the config file.

```ts
import 'shared/config'; 
```

### src/shared/config.ts file

It will contain the main application configurations that can be used with any sub application from `src/apps` apps, it looks like:

```ts
import { EncryptedLocalStorageDriver } from "@mongez/cache";
import { ApplicationConfigurations, setAppConfigurations } from "@mongez/react";
import uk from "assets/images/flags/uk.png";
import AES from "crypto-js/aes";
import Root from "design-system/layouts/Root";

const appConfigurations: ApplicationConfigurations = {
  localization: {
    defaultLocaleCode: process.env.REACT_APP_DEFAULT_LOCALE_CODE,
    fallback: process.env.REACT_APP_FALLBACK_LOCALE_CODE,
    locales: {
      en: {
        direction: "ltr",
        name: "English",
        flag: uk, // optional
      },
    },
  },
  encryption: {
    key: process.env.REACT_APP_CODE_NAME,
    driver: AES,
  },
  cache: {
    // make the cache prefix with the app code name, append the branch name (if exists)
    prefix:
      process.env.REACT_APP_CODE_NAME +
      ((process.env.NODE_ENV === "development" &&
        process.env.REACT_APP_BRANCH_NAME) ||
        ""),
    driver: new EncryptedLocalStorageDriver(),
  },
  helmet: {
    appName: process.env.REACT_APP_NAME,
    appendAppName: true,
    appNameSeparator: " | ",
    translatable: true,
    translateAppName: true,
  },
  router: {
    // used for production
    basePath: process.env.REACT_APP_PRODUCTION_BASE_PATH,
    notFound: {
      mode: "redirect",
      route: "/404",
    },
    // to set a preloader between the router navigation, pass it to the `preloader` property
    // preloader: Preloader,
    // will wrap the entire application
    rootComponent: Root,
  },
  endpoint: {
    // will convert any PUT request to a POST request with a body of the form: and append _method=PUT to the body
    // whether the request body is object, FormElement or FormData
    putToPost: true,
    baseUrl: process.env.REACT_APP_API_URL,
    apiKey: process.env.REACT_APP_API_KEY,
  },
};

setAppConfigurations(appConfigurations);
```

Before we go down to what are these configurations and their usage, the `setAppConfigurations` uses [Mongez Config](https://github.com/hassanzohdy/mongez-config) under the hood to manage the configurations between the other packages.

> You can also add any configurations to the configurations list which can be used using `config.get('your.object.key')`

Let's split it down int categories to illustrate what's going on in this file

1. `localization` **Category**

 Which sets [Mongez Localization](https://github.com/hassanzohdy/mongez-localization#configuration-setup) configurations for translation

- `defaultLocaleCode`: defines the default locale code for translation.
- `fallback`: defines the fallback locale code that will be used if the keyword doesn't exist in the current locale code.
- `locales`: contains the localization settings such as the locale code, direction and flag (optional but can be useful if you're having a multilingual application to display the locale name with its flag).

> The `direction` is important as Mongez React uses it to update the application direction.

 `encryption`: **Category**

 It defines the [Encryption Configurations](https://github.com/hassanzohdy/mongez-encryption#encryption-configurations), we defines the encryption key for encrypting and decrypting data and the encryption driver which is `AES` from [Crypto JS](https://www.npmjs.com/package/crypto-js)

 `cache` **Category**

 which is also known as `Local Storage`, we provide a prefix key for all cached items and the cache driver which is Encryption local storage (**Requires encryption settings that we mentioned**).

 The `prefix` key is a useful way to separate each project local storage keys without the need to clean it every time we start developing a project, so each project has its own prefix so do the local storage keys.

 The cache `driver` sets the default cache handler that will be used later with the `cache` manager instance among the application runtime.

 `helmet` **Category**

 It defines the [Helmet Configurations](https://github.com/hassanzohdy/mongez-react-helmet#helmet-configurations-list), self explained but we will go deeper inside it when we react the Home page.

 `router` **Category**

 It defines the [Router Configurations](https://github.com/hassanzohdy/react-router#router-configurations).

`endpoint` **Category**

It defines the [Http Configurations](https://github.com/hassanzohdy/mongez-http#http-configurations-list).

- we set the api base url and the api key (if needed), the `putToPost` property will transform any **PUT** request to **POST** and append _method=PUT to the request payload, the reason behind this property to allow us uploading files and images as PUT requests do not allow such a request.

### src/shared/apps-list.ts file

Here we will define our apps list, oh i forgot to tell you what are the apps list.

[Mongez React Router](https://github.com/hassanzohdy/react-router) provides a way to split the application code into apps/modules based.

What does that mean?

Let's say we have two apps `admin` with base route `/admin` for the admin dashboard and `front-office` with base route `/` for the public website.

`MRR` will build each application module routes inside each app as standalone files, so the files of the admin will not be loaded until you hit `/admin` route, same applies to front-office main route `/` and vice versa.

This will deduct the unnecessary loaded contents and decrease the bundle size as long as you don't hit that route.

For more information about the apps and modules i suggest you pay a visit to `MRR` documentation, we'll re-touch the apps/modules concept again later though.

Back to our apps-list, now we'll define what apps do we have, our `apps-list.ts` file will look like:

```ts
import { setApps } from "@mongez/react-router";
import frontOfficeApp from "apps/front-office/front-office-modules.json";

setApps([frontOfficeApp]);
```

Not too much to say here we just imported the app module configurations file `front-office-modules.json` and passed it to `setApps` which allows the route to know what apps and base paths for each app will be to load the proper module accordingly.

Of course if we want to create another app we'll have to import the app configurations file to `setApps` function as well.

### The assets directory

As mentioned earlier, the `assets` directory contains our shared images, icons, videos and so on, in other words our application media files.

`assets` directory has an alias `assets` to import files quickly from it.

```ts
import myLogo from 'assets/images/logo.png'; // equivalent to `src/shared/assets/logo.png`
```

In our next article, we'll talk about the the apps structure and the modules structure.

Stay tuned...