Clone this repository and start coding your React app right away. This project tries to give you the best setup and has only really needed dependencies installed. So no worries about configuration, it's all done!
Continuous integration and continuous deployments are configured as github workflow. The CD pipeline compiles and deploys the React app to an AWS S3 bucket triggered on every commit and merge to master.
Features
- Everything builds on top of latest React and webpack
- Local development with hot reloading using webpack dev server
- Linting and code formatting on the fly with ESLint and prettier
- Pre-configured test environment for component and snapshot tests using Jest
- Component styling with Less
- Docker to go! Build a production ready image including Nginx
- Continuous integration and automatic deployment to AWS S3 with Github actions
Demo
https://d2lk6w0egm4dxt.cloudfront.net/
Table of contents
# clone repo
git clone [email protected]:raoulus/react-to-go.git
# install dependencies
npm i
# build production bundle in /public
npm run build
# start webpack dev server with hot reloading
# visit http://localhost:9000
npm run dev
# start express server
npm start
This project uses prettier for code formatting in conjunction with ESLint for code linting and fixing.
npm run lint
When using Visual Studio Code the workspace will be automatically configured by .vscode/settings.json
.
settings.json
{
"[javascript]": {
"editor.formatOnSave": false
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.fixAll.stylelint": true,
"source.fixAll.tslint": true
},
"editor.formatOnSave": true,
"eslint.enable": true,
"eslint.validate": ["javascriptreact"],
"javascript.format.enable": false,
"javascript.validate.enable": false
}
This project uses Jest and supports Unit (DOM) Testing as well as Snapshot Testing.
Base Dependencies
jest
babel-jest
@babel/preset-env
@babel/preset-react
eslint-plugin-jest
# run all tests with jest
npm test
# run all tests in watch mode
npm test:watch
Snapshot tests are a very useful tool whenever you want to make sure your UI does not change unexpectedly. https://jestjs.io/docs/en/snapshot-testing
Dependencies
Snapshots are taken and compared with the previous version every time when the tests are executed.
Here's a step by step guide how to create and update snapshot tests.
- Write a new snapshot test, e.g.
/components/Footer/__tests__/Footer.spec.js
import React from 'react'
import Footer from '../index.jsx'
import renderer from 'react-test-renderer'
describe('<Footer /> ', () => {
test('matches snapshot', () => {
const component = renderer.create(<Footer />)
let tree = component.toJSON()
expect(tree).toMatchInlineSnapshot()
})
})
- Run initial test (
npm test
) to replace.toMatchInlineSnapshot()
with the actual content
test('matches snapshot', () => {
const component = renderer.create(<Footer />)
let tree = component.toJSON()
expect(tree).toMatchInlineSnapshot(`
<div>
<p>
<i
className="fab fa-github"
/>
<a
href="https://github.com/raoulus/react-to-go/"
>
react-to-go (v
)
</a>
</p>
</div>
`)
})
})
In addition to the actual test the snapshot content must be maintained separately. Meaning every time the content of a component changes then the snapshot needs to be updated as well.
- Change content
- Run tests again
npm test
- Snapshot tests will fail and needs to be updated with
npm test -- --updateSnapshot
Snapshot Summary
› 2 snapshots failed from 1 test suite. Inspect your code changes or run `npm test -- -u` to update them.
- Update snapshot
npm test -- -u
- Commit changes
This projects follows the recommendation from Jest to use react-testing-library
for Unit Testing also known as DOM Testing.
The React Testing Library is a very light-weight solution for testing React components. It provides light utility functions on top of react-dom and react-dom/test-utils, in a way that encourages better testing practices.
https://testing-library.com/docs/react-testing-library/intro
Dependencies
@testing-library/react
@testing-library/jest-dom
(custom Jest matchers)eslint-plugin-jest-dom
- Jest will set
process.env.NODE_ENV
to'test'
if it's not set to something else - Styles (
less
|css
) are mocked, see__mocks__/style.mock.js
There's a npm command to build docker image using Nginx.
# build image with tag react-to-go:1.0.0
npm run build:docker
# start image
docker run --name react-to-go --rm -p 3000:80 react-to-go:1.0.0
# go to http://localhost:3000
You find the working github workflow under .github/workflows/s3-upload.yml. This workflow contains two jobs namely build
and deploy
.
build
The job runs npm run build
and outputs static assets under /public
. To have a clean deployment this folder is saved as artifact for the next job.
deploy
The AWS credentials
needs to be configured in order to use AWS CLI (aws sync
) to recursively copy new and updated files to an S3 bucket.
Following secrets have to be created in github (repository -> settings -> secrets)
AWS_ACCESS_KEY_ID=xxx
AWS_SECRET_ACCESS_KEY=xxx
AWS_REGION=eu-central-1
AWS_S3_BUCKET=react-to-go
AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
can be found in AWS under IAM -> Users -> security credentials.
The access rights for the API user should be restricted for security reasons. Create an IAM policy with the following configuration. This policy can then be attached to a group to which a user belongs.
These permissions are needed to perform aws sync
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket",
"s3:DeleteObject",
"s3:GetBucketLocation"
],
"Resource": ["arn:aws:s3:::react-to-go", "arn:aws:s3:::react-to-go/*"]
}
]
}