Frontend application built with React + Webpack + BabelJS + Less + Mocha.
This project serves as a proof of concept of creating a React application, utilizing server side rendering capabilities, which is hosted on Amazon Lambda, and exposed to world utilizing Amazon API Gateway.
This section describes the architectural approaches to building this application.
React is used as the main application framework, with the whole application split into the components. Sources for the main part of the application are stored inside the src
directory. All sources, including those for the build pipeline are written using BabelJS to take advantage of new ES features, as well as potential optimizations implemented as Babel plugins.
BabelJS is configured with the use of .babelrc
file. It defines additional (experimental) options that are allowed within this repository.
Webpack is used as the main build tool responsible for compiling the sources written in BabelJS, Less and joining all files together. It has some internal magic as well, like making sure that files are split into chunks, css files contain vendor prefixes, names of the deployment packages are unique etc. It also sets up it's own development server with live reload possibilities, react components hot swapping and some other cool features. Most of that should be described in form of comments inside the configuration files for Webpack. Sources for those are available in the webpack
directory.
Project is also using "server-side rendering" of react components, so the HTML content is pre-generated and passed to the client side before starting the actual react application.
This application has two different modes for handling server side rendering. One is implemented using ExpressJS, and is utilized for development purposes, where developers can use the application in the same way it is later used in production.
Second one is a handler for Amazon Lambda, which is a simple pass through between server side rendering architecture, and Amazon Lambda input/output interface. To achieve this, application is packaged into a .ZIP archive as a build step, and uploaded to Amazon S3, from where it is picked up by Amazon Lambda.
The ExpressJS module + the rendering component live inside the server
directory.
So after the webpack development server is started, all requests made to it, are proxied straight to the ExpressJS application to perform the server-side rendering of the react components based on the path specified in the URL.
The styles for the application are written in Less, and live inside the styles
directory. Application style is mostly implemented utilizing a pre-made bootstrap template, with changes revolving mostly around applying the style to the layout designs. Customizations are kept in the styles/customizations
directory, and should be kept in particular files named after the components that use them. Additionally some small style fixes might be kept in react components directly. Some assets other than the style files, are also kept in the public
directory.
Project uses Mocha framework for unit testing, with Sinon and Chai libraries for stubbing and assertions respectively. Tests are kept inside the test
directory, with a structure of the test files reassembling the one from the src
directory.
All application sources are linted using Eslint which is configured with .eslintrc
file to understand BabelJS sources as well as React JSX sources. Additionally project contains .eslintignore
file which excludes the files that were generated by Webpack from linting.
This project is configured to use CircleCI build system on all branches. Configuration of the continuous deployment is defined in the circle.yml
file. It will run unit tests on each commit to the repository, and on merge to the master branch, it will perform deployment of the application to staging environment comprised of the following steps:
- Build deployment package using webpack production configuration,
- Deploy prepared package to Amazon S3 as a .ZIP archive named after the build number. This allows to keep the application versioned, and have builds immutable,
- Tag current version of the code in the repository, with the current build number,
- Trigger a code update inside Amazon Lambda to actually deploy new version of the code, to staging environment.
This section lists the required steps necessary to perform to get the application running in the development mode, as well as be able to prepare production packages by hand if necessary.
This project requires io.js as some components are not compatible with NodeJS. I recommend using and installing it through nvm, but in reality it doesn't matter how you will install it, as long as you are operating with the latest io.js binary.
Once your environment is configured, and you have the project files cloned, just go into the project directory and run command:
npm install
to download project dependencies.
To create a dist
directory with all the required files for the project, just run the command:
npm run release
There is a command for running the prepared project package locally, simply run the command:
npm run serve
And open http://localhost:9000 in your browser, to see the application.
To run the application in the development mode, with all the benefits of Webpack and its plugins, simply run the command:
npm start
This should automatically load the application in your browser. In case that doesn't happen, just go to http://localhost:9000.
Linting of the sources is automatically performed when you start the project in the development mode, or when you build the production package, as well as before running the unit tests, but if you want to do perform just this task, simply run:
npm run lint
Tests are automatically ran when you build project package, but in case you want to run only tests, just run:
npm test
To generate the test coverage report, simply run:
npm run coverage
Parts of the code, mostly the ones related to server side rendering inside ExpressJS, and webpack configuration, are taken from very smart people at GoCardless. Thank you guys for sharing your knowledge!