Level - Advanced. Read Time ~ <10-15 minutes.
Recently I set myself the goal of learning and gaining a better understanding of the following technologies: -
- SSR (server side rendering)
- Web Sockets
Some of the above I've worked with before and others are new to me. So, I thought the best way of learning the above was to author a simple todo application (could have been "Hello world!"), demonstrating the aforementioned technologies. I took this further in the end and decided to create a boilerplate. My motivations for doing this are to hopefully help others setting up a Hapi application with similar components and tech stack. It's also a useful reference for myself on how to server side render React and Redux.
The repo can be found on Github -> https://github.com/blairg/hapi-socket-react-boilerplate
The boilerplate is not the most beautifully engineered application out there (happy for criticism of how I can improve it and sharpen my skills). My main intention was to focus on developing shiny features and use it as an educational project. Saying that, I have tried to instill good practices and opinions. I am a firm believer in separating your concerns and having a solid folder structure in place, to ensure your application is both maintainable and extensible.
Once you clone the repo and dig into the code, which I advise you do. You will see the below folders in the root: -
My opinions here are to structure your test folders identically to your application folders. Others may disagree, but this synergy has worked for me. Having discipline and attention to detail allows your application to scale. It's also vital if you intend a small army of developers to support and develop it.
For this boilerplate,
client refers to the React/Redux code and
shared is the bridge between the client and server. All business logic and data access should live here.
Client Folder Structure
reducers house the Redux actions and logic.
components stores the React components. I've decided to break this down even further, by having
containers which houses components connected to the Redux store. The purpose of the
presentation folder is to separate your component with there sole purpose to render data passed through their props.
subscribers is used for connecting the React components to Web Sockets. Will go into more detail later on.
Server Folder Structure
The thought behind the folder structure on the server allows the concerns to be separated. So the
controllers folder will contain the concrete implementations. Such as in the
index controller which server side renders the React and Redux. I recommend breaking this open to gain a better understanding.
plugins is a nice to way to compartmentalise the Hapi plugins away from the main server implementation.
routes is an interface to the controller controller implementation. This makes the server very testable as the routes can be mocked.
In my implementation I have very little in the
shared folder. As this not a real world application and is contrived, there wasn't much scope for adding code here. But if you intend to create an isomorphic React/Hapi application, any code which is shared by the client and server should reside here. The rewards you reap from this separation will be great and force DRY principles.
When I first started developing this application. I had one
Webpack file. This quickly became unwieldy. So I split out into a client and server file to mirror the application separation. The main takeways from this are the following: -
- Client - Targets web and creates a
public\jsfolder. Entry point is the
- Server - Targets node and transpiles the ES6 Hapi implementation to ES5. With Node version 9, I'm actually not sure this is needed. Will have to check it out.
Got quite a primitive Dockerfile. This may need expanding for more advanced applications. The main gist of it is the following: -
- Use an official NodeJS base image unless you have very good reason not to.
- You'll see there are a few environment variables passed in. This allows the application to be 12 factor and can be run anywhere.
You will see in the Travis
yml where I actually push the built Docker image up to the Heroku container registry. My Travis file, serves the following purposes in order: -
- Use NodeJS environment running version 8.9.1.
- Run Docker.
- Install the
npmmodules from the
- Run the ESLint task.
- Run the code coverage using Mocha and Istanbul.
- Build the
- Then for
masterbranch on GitHub, login to the Heroku container regsitry and push up the built image.
- Heroku will then run a container based on this image.
- Push coverage stats to Coveralls.
I'd like to learn/add the following to this repo: -
Any questions about this, leave them below and I'll try my best to respond.
Subscribe to Hackerlite
Get the latest posts delivered right to your inbox