A Base ReactJS web app and NestJS mock backend API server.
Organised as a Nx monorepo and composed using Domain Driven Design (DDD) principles to provides a best-practice starting point for developing modular and highly scaleable React apps.
The architectural approach implemented here is documented under my Scaleable Frontend Architectures guidelines
The codebase combines a number of separate 'applications' (apps) which are simple shells containing several 'libraries' (libs) to provide the real functionality, all within the same workspace in a NX Monorepo. There are only two applications:
-
Web-app
The main client application (ReactJS) as a simplified app with all functionality linked to in libs.
-
Mock-api
The Mock API server application (NestJS) which mocks interaction with teh real server during offline development.
The Web App (apps/web-app) uses axios to abstract common functionality around handling HTTP requests through the sample feature Axios API Service (UserAxiosApiService) class which is injected into the sample feature API Service (UserApiService) class to handle Axios configurations and common functionality.
Simple caching is included via the axios-cache-adapter library and customised cache invalidation functionality is defined in UserAxiosApiService, applied via custom HTTP interceptors which are managed by the injected shared Axios interceptor service (AxiosApiInterceptorsService).
A custom state manager class (ApiStateManager) provides an easy to use technique for updating and retrieving the current state of HTTP requests for use in containers which interact with APIs.
The 'mock-api' app contains a NestJS application which replicates the APIs requested to ensure development can continue in parallel to that of the Backend. This mock API can be enabled as the source of all HTTP requests within the web-app when serving in dev mode and when the environments property useMockInDev
is set to true
(located in src/environments/environment.ts
).
The app serves on the port defined in a variable in the .env file
(process.env.NX_MOCK_API_PORT
) and this matches the port number defined in the web-app's
proxy file (proxy.conf.json
), which is used to ensure all API calls within the app are
redirected to the mock API.
The codebase includes a Thunder Tests directory which contains configs for testing both the NestJS APIs as well as some sample fake data APIs. This uses the Thunder Client vscode extension listed in .vscode/extensions.json.
Use the below convenience methods to generate boilerplate code structure of the apps and libs.
nx g lib <some-lib> --directory=<some-domain>/<lib-type> --tags='type:<lib-type>, domain:<some-domain>' --dry-run
Example: nx g lib manage-users --directory=users/feature --tags='type:feature, domain:users'
Create storybook configs and storybook files for all components within a library.
Run nx g @nrwl/react:storybook-configuration <project-name>
where is
the name of the library in workspace.json.
Run all stories: npm run storybook
.
Run npm start
to serve both the frontend web-app
and mock API backend mock-api
simultaneously.
Or run each separately using npm run serve:web
for the frontend and npm run serve:api
for the mock API backend.
- Navigate to
http://localhost:4201/
for the main frontend. - Navigate to
http://localhost:3334/api/
for the mock API backend.
NB: You may need to kill the port previously run by Node if an error persists which claims the port is still in use
- Web app server:
kill $(lsof -t -i:4201)
- Mock API server:
kill $(lsof -t -i:3334)
Run npm run build
to build the project.
Run npm run build:prod
to build the production-ready project.
Run npm run serve:dist
to serve and test the built application which was generated using the BUILD command above using the live-server
library. Navigate to http://localhost:6600/
Run npm run graph
to see a diagram of the dependencies of your projects.
Run nx migrate latest
then nx migrate --run-migrations
. See Updating Nx.
Find a list in .vscode/extensions.json to ensure the best development experience.
Visit the Nx Documentation to learn more.