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:
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
# 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 inpublic/index.htmlfile. -
REACT_APP_DESCRIPTION: will be added as the project meta description inpublic/index.htmlfile. -
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 thesrc/shared/config.tsfile. -
REACT_APP_DEFAULT_LOCALE_CODE: Default application locale code, will be added in the html tag aslangattribute inpublic/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 asdirattribute inpublic/index.html. -
REACT_APP_PRIMARY_COLOR: Primary Color for the app, will update the metatheme-colorinpublic/index.htmlfile. -
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.productionsettings instead of.envfile. -
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 command to update the project packages to latest updates. -
lint: Run the eslint command to check for errors based oneslintrc.jsonconfigurations. -
fix: will run the eslint to fix errors as could as possible based oneslintrc.jsonconfigurations. -
format: will run the prettier to properly format the files based onprettierrc.jsonconfigurations.
The second property will be _moduleAliases that stores the paths aliases thanks to link-module-alias.
In nutshell, this will allow us instead of setting the paths as relatives to be absolutes,
Before:
import BaseButton from './../../design-system/components/Button';
After:
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:
the src directory contains two important directories and one file:
-
apps: which contains all our project apps, i.efront-officeto the website and we can addadminapp 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:
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.
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 darkin 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.
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:
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 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
-
localizationCategory
Which sets Mongez Localization 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
directionis important as Mongez React uses it to update the application direction.
encryption: Category
It defines the Encryption Configurations, we defines the encryption key for encrypting and decrypting data and the encryption driver which is AES from 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, self explained but we will go deeper inside it when we react the Home page.
router Category
It defines the Router Configurations.
endpoint Category
It defines the Http Configurations.
- we set the api base url and the api key (if needed), the
putToPostproperty 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 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:
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.
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...


Top comments (0)