Here is the link to the code if you are impatient: https://github.com/tahnik/react-expressjs
As mentioned before, the core of this project is ReactJS and ExpressJS. Among them, React depends on a lot of libraries. These are explained in details in the later part of this blog.
For React, we use:
- Redux for state management
- React Router v4 for routing inside the app
- Sass for decorating the app
For ExpressJS, we use EJS templates.
To bring all of these together, we use Webpack.
To know about how webpack compiles and creates the distributable files, please navigate to the last section of this blog.
As always, file structure depends a lot on personal preferences. I tried my best to structure it in a way that is acceptable for both ReactJS and ExpressJS community. Here it is:
Let’s discuss the 3 root directories first.
Client directory includes files for ReactJS (Redux, React Router v4) and static resources (images, sass etc). It has two subfolders — res and src. If you have used redux before then the structure inside the src folder should be familiar to you. res folder includes static resources and sass. Any other static files you have should also come here.
Server directory includes files for ExpressJS and EJS templates.
Webpack directory includes Webpack configurations for webpack-dev-server and production build for server and client.
Files in the root directory are typical for a npm project. We have two extra eslint configuration files.
Client Side (ReactJS)
In the client directory, we have a simple app which views a list of items and their description. The idea is to set you up with a very small amount of boilerplate code, that is the reason why I did not use a todo or a complex redux app.
Apart from the typical redux structure, we have a const directory. It holds some important constants like default states for reducers and action types for redux actions. It also contains the list items to be shown in the app (as illustrated in the picture above).
The application simply loads the list items from a file and shows them in the app. You can navigate the items and see a preview. Inside the preview, if you click “Read More”, it shows the full text in a separate route.
Again, as simple as possible just to set you up with the react router and redux structure.
Hot reloading is enabled in this project. So you can run
npm run dev and start developing with hot reload.
Server side is pretty simple. ExpressJS uses EJS templates for server-side rendering. An Important note is that the server side code is also compiled using webpack and babel. Which means that you can use es6 modules and other stage-1 features in the server side code.
When rendering on the server, we dispatch a redux action to add an item to list items. This is to demonstrate that we can add extra items in redux state during server-side rendering. This initial state for redux is then added as a global variable in window. This global variable called INITIAL_STATE is then used as the initial state for redux store in the client side application.
Build Tools (Webpack)
Webpack as always uses couple of libraries to get things done. I will highlight the important bits here. There is three different webpack configuration file:
client.dev.js: This is used to developing the react app with hot reloading. It uses:
- React Hot Loader for hot reloading
- HTMLWebpackPlugin for creating a index.html file to support the hot reload. Without this, the dev server will not have any html file to display. The reason behind this is that the hot reload is only for ReactJS application, it doesn’t include ExpressJS code. Our expressJS code renders and sends the client an index.html (not exactly but you get the idea if you know about expressJS). Because we don’t use express during the react app development, we have to create a temporary index.html file for hot reloading to work.
client.prod.js and server.prod.js: These two compiles server-side and client-side code for distributing in production. It uses:
- extract-text-webpack-plugin for extracting the css code from css-loader to a css file. It creates a
main.cssfile in the
- It uses file-loader for loading images and moving them in
- After compiling the application,
server/public/directory. This is the react app that will be served to public.
server/bin/. This is the expressJS server that will be run in production server.
That’s it folks! Please create an issue or pull request to improve the project. Or give it a start if you think it’s perfect!