As a developer, when it comes to your web application, you want to make sure that you have the best project setup that will enable you to focus on your development without any issues.
You probably will look for a boilerplate with a small example, a build-ready project that you can just take its result and deploy it.
When you look at the bigger picture, and you need to define the infrastructure for a project that will give you full flexibility to add features, a project that includes placeholders for core functionality, business logic, configuration, common functionality, routes, translations, state-management, and last but not least what about technologies? your research will take longer.
What are the questions that you should ask yourself when you need that kind of a project setup, a good boilerplate that will enable you all what you need.
Those are the questions that I am asking myself when I design a project:
- What are the technologies that I am going to use and why?
- Will the project scale?
- How many developers (scrums) are going to work on this project?
- How am I going to enable unit-testing, automation in this project?
- How am I making sure that my project is ready for infra pipeline, build, testing and deployment?
- How am I going to create boundaries in terms of code quality in my project?
I think that those endless list of questions but the main questions will be common for all of us.
When I started to develop my own small projects I was looking for open-source boilerplates that might fulfil my needs and in most of the cases they were lacking in at least one aspect that I consider basic need (or required) for a project. I found my self asking, why its not here, why this functionality is there and why they did not use this library? This journey ends with a decision to create an open-source boilerplate that will answer my questions, it will give the basics for a single developer and will enable teams to work on scalable projects.
What will be covered?
- Client Overview — Project Structure and Technologies
- Project Configuration
- Code Guards
- Code Generators
So what is Harmony?
Harmony Boilerplate is a TypeScript project template, based on react-redux. The boilerplate contains all the initial infrastructure to enable you fast on-boarding and let you start the development.
In general, when we look at the diagram above, it’s a typical react-redux data flow diagram, the additions in harmony is the redux-saga middleware, the integration with Redux-Form to enable easy handling of forms in our web-app, and a cool small feature that can be used (with minimal setup on your backend) to dispatch actions on client side from server via Websockets.
As you can see, the folder structure is designed to enable the developers to work on the project with full separation between the core “base” features and the business logic. The idea behind it is to enable the cross-work developers to add base features and capabilities to the project without affecting the other developers.
In the actions we will define the sagas and the redux. With saga we are handling all the side-effects, the APIs requests that the app is executing by throwing actions to the system.
Saga on a nutshell
Let’s assume we have a catalogue of devices. We will have an action to fetch the devices from backend so first we will define the function-generator that will be called once the action is being processed by the middleware.
Once we defined the function-generator, we will set the ACTION watcher to be mapped to the getDevices function.
By doing that, when we are dispatching GET_DEVICE_LIST the middleware will catch it and execute the getDevices function, which will end with an API request, modifying the state by calling another action (Dispatch Action, Reducer, State, Components).
In the redux folder we will define all the state-related modifiers (I am not calling them reducers but rather just redux) by using redux-sauce. There you will define your reducers, mappers, selectors, and the action types in a single file, this will reduce the number of files that you will create (In other architectures I saw that the reducers were placed in one folder, actions in another, and the selectors in yet another folder — this creates chaos when it comes to a big projects).
Lets take a look on simple example, slice in state that handle carts activities
We make sure that everything related to cart is defined in one place.
Now that we covered what we have in the actions folder, we can move to the next folders in our project structure.
In the base folder we have all the features that Harmony provide, e.g. Error Handling, Cart Management, Flow Management, Translations, Mobile Rendering, Global Spinner, and more.
If we are going over the rest of the folders, its pretty straight-forward to understand what we have there.
Here is the list of the modules being used in Harmony
- redux-saga — redux middleware that handles your web application side-effects, APIs requests.
- redux-sauce — different approach of managing your state definitions
- redux-flow-manager — redux middleware that enable management of complex flows
For every module you can hit the link and read the documentation.
In Harmony, and probably in other projects, we want that the entire configuration of the project will be defined in one place. In this configuration we set the base url of our HTTP requests, on/off flags, non-prod and production configurations, and more.
Code guards are crucial for a project, especially when there are multiple developers working simultaneously. We want to make sure that everyone is aligned with the coding standard of the project, and we want to reduce the potential performance defects, the time that the build is failing and the developer needs to work on fixes for it to pass.
What we focused in the project?
- TypeScript — Providing predictive development with static checks and code refactoring
- Immutable JS — Turn your application state into immutable box which prevent any non-standard modifications to the state.
- Linter — Provide better code scanning which improve the performance of the application and prevent bad practices while coding.
Here are the set of rules we decided to put in the boilerplate:
For example, passing all props from parent component to child is not allowed — what do you think? feel free to comment on it or on any other rule.
The most interesting part of Harmony are the features. We designed Harmony to be extensible, as an open-source project, we want to make sure that we can push more features so projects that already started to work can take them and plug it in for their needs.
Currently, Harmony provide the following:
- Cart Management — Ready to use setup for managing cart — this is cool feature for e-commerce websites.
- Requests — we have a unified class for all the requests in the system, so if you need to define a common header or handle, everything right before they are going out, this is the place.
- Flow Manager — How are you managing complex flows in your application? How do you navigate between pages? Where do you decide in which flow you are when you have common components? all the answers are right here — the idea is to take the state-machine concept and utilise it to our needs, for more information click here.
- Error Handling — Managing all the exceptions in one place, think about all the scenarios for your app exceptions — this can be managed with just a single configuration — handling API failures, functional exceptions can be mapped to a user friendly message, notification, or even a special page.
- Global Spinner — Subscribing to any XHR request with whitelisting option to turn the loader in your app and set it off automatically — no need to start your loader and turn it off in every place.
- Roles Based Auth — A way to show or hide components by implementing HoC pattern
- Translator — Turn your app to a multilingual web application by defining your messages for every label in your system, in configuration, and change the language by just dispatching an action.
- Mobile Ready — Most of the websites today are responsive and there are few scenarios that we want something special for mobile, a different look and feel, so for that we added another life-cycle method for mobile rendering. The render for mobile will be called only for mobile devices, in the end we want to reduce the number of bugs that will occur if something is changed in Desktop view and doesn’t have to be changed in Mobile.
As part of this boilerplate development we decided to have small cli activities to enable code injection. Need to create a new container? we will do it for you, not because you are lazy but to avoid human errors, anyone can forget to export something or to not configure something else, and then spent time to find it.
Let’s take a look on Redux creation
by invoking the following command using gulp
gulp createRedux --name myReducer
it will process the following template and inject it to the actions/redux folder
When it comes to testing, we choose to setup puppeteer for this boilerplate to enable the developers to write their own automation for their components.
The tests in the boilerplate here
Every project needs its own documentation. In the boilerplate template we have the markdowns for Harmony docs that can be enhanced for your needs. The idea is that new comers will read the docs to understand how to work with Harmony, what are its main features and how to inject code to start developing.
In the documentation you will find how to start your project. In fact its just npm install and npm start.
So what you are waiting for? go try it, feel free to ask your questions in the comments — https://github.com/harmony-framework/harmony-boilerplate/
This article should give you a high level understanding of harmony, what it does and how you can use the features it provides.
Now go and create your next blasting web application! if you like it, star it on Github.
Who am I?
I am Ofir Attia, a Web developer, focusing on design and architecture. Currently working at Amdocs as Software Architect.