2 |

3 |
This repository is the stable base upon which we build our React projects at Mirego.
We want to share it with the world so you can build awesome React applications too.
4 |
5 |
6 | ## Introduction
7 |
8 | To learn more about _why_ we created and maintain this boilerplate project, read our [blog post](https://shift.mirego.com/en/boilerplate-projects).
9 |
10 | ## Content
11 |
12 | This boilerplate comes with batteries included, you’ll find:
13 |
14 | - Tests with [jest](https://jestjs.io), with coverage
15 | - Linting with [tslint](https://palantir.github.io/tslint) and [stylelint](https://stylelint.io)
16 | - Formatting with [Prettier](https://prettier.io)
17 | - A [GraphQL](https://graphql.org) setup powered by [Apollo](https://www.apollographql.com)
18 | - Translations powered by [i18next](https://www.i18next.com)
19 | - [TypeScript](https://www.typescriptlang.org)
20 | - Styled components with [emotions](https://emotion.sh)
21 | - Routing with [react-router](https://reacttraining.com/react-router/)
22 | - A clean and useful `README.md` template (in both [english](./BOILERPLATE_README.md) and [french](./BOILERPLATE_README.fr.md))
23 |
24 | ## Usage
25 |
26 | ### With GitHub template
27 |
28 | 1. Click on the [**Use this template**](https://github.com/mirego/react-boilerplate/generate) button to create a new repository
29 | 2. Clone your newly created project (`git clone https://github.com/you/repo.git`)
30 | 3. Run the boilerplate setup script (`./boilerplate-setup.sh YourProjectName`)
31 | 4. Commit the changes (`git commit -a -m "Rename react-boilerplate parts"`)
32 |
33 | ### Without GitHub template
34 |
35 | 1. Clone this project (`git clone https://github.com/mirego/react-boilerplate.git`)
36 | 2. Delete the internal Git directory (`rm -rf .git`)
37 | 3. Run the boilerplate setup script (`./boilerplate-setup.sh YourProjectName`)
38 | 4. Create a new Git repository (`git init`)
39 | 5. Create the initial Git commit (`git commit -a -m "Initial commit"`)
40 |
41 | ## License
42 |
43 | React Boilerplate is © 2018-2020 [Mirego](https://www.mirego.com) and may be freely distributed under the [New BSD license](http://opensource.org/licenses/BSD-3-Clause). See the [`LICENSE.md`](https://github.com/mirego/react-boilerplate/blob/master/LICENSE.md) file.
44 |
45 | The science logo is based on [this lovely icon by Igé Maulana](https://thenounproject.com/term/science/2089589), from The Noun Project. Used under a [Creative Commons BY 3.0](http://creativecommons.org/licenses/by/3.0/) license.
46 |
47 | ## About Mirego
48 |
49 | [Mirego](https://www.mirego.com) is a team of passionate people who believe that work is a place where you can innovate and have fun. We’re a team of [talented people](https://life.mirego.com) who imagine and build beautiful Web and mobile applications. We come together to share ideas and [change the world](http://www.mirego.org).
50 |
51 | We also [love open-source software](https://open.mirego.com) and we try to give back to the community as much as we can.
52 |
--------------------------------------------------------------------------------
/boilerplate-setup.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | # -----------------------------------------------------------------------------
4 | # Configuration
5 | # -----------------------------------------------------------------------------
6 |
7 | pascalCaseBefore="ReactBoilerplate"
8 | snakeCaseBefore="react_boilerplate"
9 | kebabCaseBefore="react-boilerplate"
10 |
11 | # The identifiers above will be replaced in the content of the files found below
12 | content=$(find . -type f \( \
13 | -name "*.sh" -or \
14 | -name "*.json" -or \
15 | -name "*.js" -or \
16 | -name "*.jsx" -or \
17 | -name "*.ts" -or \
18 | -name "*.tsx" -or \
19 | -name "*.yml" -or \
20 | -name "*.md" -or \
21 | -name "Dockerfile" -or \
22 | -name "Makefile" \
23 | \) \
24 | -and ! -path "./boilerplate-setup.sh" \
25 | -and ! -path "./assets/node_modules/*" \
26 | )
27 |
28 | # The identifiers above will be replaced in the path of the files and directories found here
29 | paths=$(find . -depth 2 \( \
30 | -path "…" \
31 | \))
32 |
33 | # -----------------------------------------------------------------------------
34 | # Validation
35 | # -----------------------------------------------------------------------------
36 |
37 | if [[ -z "$1" ]] ; then
38 | echo 'You must specify your project name in PascalCase as first argument.'
39 | exit 0
40 | fi
41 |
42 | pascalCaseAfter=$1
43 | snakeCaseAfter=$(echo $pascalCaseAfter | /usr/bin/sed 's/\(.\)\([A-Z]\)/\1_\2/g' | tr '[:upper:]' '[:lower:]')
44 | kebabCaseAfter=$(echo $snakeCaseAfter | tr '_' '-')
45 |
46 | # -----------------------------------------------------------------------------
47 | # Helper functions
48 | # -----------------------------------------------------------------------------
49 |
50 | header() {
51 | echo "\033[0;33m▶ $1\033[0m"
52 | }
53 |
54 | success() {
55 | echo "\033[0;32m▶ $1\033[0m"
56 | }
57 |
58 | run() {
59 | echo ${@}
60 | eval "${@}"
61 | }
62 |
63 | # -----------------------------------------------------------------------------
64 | # Execution
65 | # -----------------------------------------------------------------------------
66 |
67 | header "Configuration"
68 | echo "${pascalCaseBefore} → ${pascalCaseAfter}"
69 | echo "${snakeCaseBefore} → ${snakeCaseAfter}"
70 | echo "${kebabCaseBefore} → ${kebabCaseAfter}"
71 | echo ""
72 |
73 | header "Replacing boilerplate identifiers in content"
74 | for file in $content; do
75 | run /usr/bin/sed -i "''" "s/$snakeCaseBefore/$snakeCaseAfter/g" $file
76 | run /usr/bin/sed -i "''" "s/$kebabCaseBefore/$kebabCaseAfter/g" $file
77 | run /usr/bin/sed -i "''" "s/$pascalCaseBefore/$pascalCaseAfter/g" $file
78 | done
79 | success "Done!\n"
80 |
81 | header "Replacing boilerplate identifiers in file and directory paths"
82 | for path in $paths; do
83 | run mv $path $(echo $path | /usr/bin/sed "s/$snakeCaseBefore/$snakeCaseAfter/g" | /usr/bin/sed "s/$kebabCaseBefore/$kebabCaseAfter/g" | /usr/bin/sed "s/$pascalCaseBefore/$pascalCaseAfter/g")
84 | done
85 | success "Done!\n"
86 |
87 | header "Importing project README.md and README.fr.md"
88 | run "rm -fr README.md && mv BOILERPLATE_README.md README.md && mv BOILERPLATE_README.fr.md README.fr.md"
89 | success "Done!\n"
90 |
91 | header "Removing boilerplate license → https://choosealicense.com"
92 | run rm -fr LICENSE.md
93 | success "Done!\n"
94 |
95 | header "Removing boilerplate changelog"
96 | run rm -fr CHANGELOG.md
97 | success "Done!\n"
98 |
99 | header "Removing boilerplate code of conduct and contribution information → https://help.github.com/articles/setting-guidelines-for-repository-contributors/"
100 | run rm -fr CODE_OF_CONDUCT.md CONTRIBUTING.md
101 | success "Done!\n"
102 |
103 | header "Removing boilerplate setup script"
104 | run rm -fr boilerplate-setup.sh
105 | success "Done!\n"
106 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # Build configuration
2 | # -------------------
3 |
4 | APP_NAME = `grep -m1 name package.json | awk -F: '{ print $$2 }' | sed 's/[ ",]//g'`
5 | APP_VERSION = `grep -m1 version package.json | awk -F: '{ print $$2 }' | sed 's/[ ",]//g'`
6 | GIT_REVISION = `git rev-parse HEAD`
7 | DOCKER_IMAGE_TAG ?= $(APP_VERSION)
8 | DOCKER_REGISTRY ?=
9 | DOCKER_LOCAL_IMAGE = $(APP_NAME):$(DOCKER_IMAGE_TAG)
10 | DOCKER_REMOTE_IMAGE = $(DOCKER_REGISTRY)/$(DOCKER_LOCAL_IMAGE)
11 |
12 | # Linter and formatter configuration
13 | # ----------------------------------
14 |
15 | PRETTIER_FILES_PATTERN = '{src,typings,__mocks__,scripts}/**/*.{js,ts,tsx}' '**/*.md'
16 | SCRIPTS_PATTERN = '{src,typings,__mocks__}/**/*.{js,ts,tsx}'
17 | STYLES_PATTERN = 'src/**/*.css'
18 |
19 | # Introspection targets
20 | # ---------------------
21 |
22 | .PHONY: help
23 | help: header targets
24 |
25 | .PHONY: header
26 | header:
27 | @echo "\033[34mEnvironment\033[0m"
28 | @echo "\033[34m---------------------------------------------------------------\033[0m"
29 | @printf "\033[33m%-23s\033[0m" "APP_NAME"
30 | @printf "\033[35m%s\033[0m" $(APP_NAME)
31 | @echo ""
32 | @printf "\033[33m%-23s\033[0m" "APP_VERSION"
33 | @printf "\033[35m%s\033[0m" $(APP_VERSION)
34 | @echo ""
35 | @printf "\033[33m%-23s\033[0m" "GIT_REVISION"
36 | @printf "\033[35m%s\033[0m" $(GIT_REVISION)
37 | @echo ""
38 | @printf "\033[33m%-23s\033[0m" "DOCKER_IMAGE_TAG"
39 | @printf "\033[35m%s\033[0m" $(DOCKER_IMAGE_TAG)
40 | @echo ""
41 | @printf "\033[33m%-23s\033[0m" "DOCKER_REGISTRY"
42 | @printf "\033[35m%s\033[0m" $(DOCKER_REGISTRY)
43 | @echo ""
44 | @printf "\033[33m%-23s\033[0m" "DOCKER_LOCAL_IMAGE"
45 | @printf "\033[35m%s\033[0m" $(DOCKER_LOCAL_IMAGE)
46 | @echo ""
47 | @printf "\033[33m%-23s\033[0m" "DOCKER_REMOTE_IMAGE"
48 | @printf "\033[35m%s\033[0m" $(DOCKER_REMOTE_IMAGE)
49 | @echo "\n"
50 |
51 | .PHONY: targets
52 | targets:
53 | @echo "\033[34mTargets\033[0m"
54 | @echo "\033[34m---------------------------------------------------------------\033[0m"
55 | @perl -nle'print $& if m{^[a-zA-Z_-\d]+:.*?## .*$$}' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-22s\033[0m %s\n", $$1, $$2}'
56 |
57 | # Build targets
58 | # -------------
59 |
60 | .PHONY: build
61 | build: ## Build the Docker image
62 | docker build --build-arg APP_NAME=$(APP_NAME) --build-arg APP_VERSION=$(APP_VERSION) --rm --tag $(DOCKER_LOCAL_IMAGE) .
63 |
64 | .PHONY: push
65 | push: ## Push the Docker image to the registry
66 | docker tag $(DOCKER_LOCAL_IMAGE) $(DOCKER_REMOTE_IMAGE)
67 | docker push $(DOCKER_REMOTE_IMAGE)
68 |
69 | # Development targets
70 | # -------------------
71 |
72 | .PHONY: dependencies
73 | dependencies: ## Install dependencies required by the application
74 | npm install
75 |
76 | .PHONY: build-app
77 | build-app: ## Build the application
78 | npm run build
79 |
80 | .PHONY: test
81 | test: ## Run the test suite
82 | npm test
83 |
84 | # Check, lint and format targets
85 | # ------------------------------
86 |
87 | .PHONY: check
88 | check: check-format check-code-coverage check-types ## Run various checks on project files
89 |
90 | .PHONY: check-format
91 | check-format:
92 | npx prettier --check $(PRETTIER_FILES_PATTERN)
93 |
94 | .PHONY: check-code-coverage
95 | check-code-coverage:
96 | npm test -- --coverage
97 |
98 | .PHONY: check-types
99 | check-types:
100 | npx tsc
101 |
102 | .PHONY: format
103 | format: ## Format project files
104 | npx prettier --write $(PRETTIER_FILES_PATTERN)
105 | npx tslint -c tslint.json --fix $(SCRIPTS_PATTERN)
106 |
107 | .PHONY: lint
108 | lint: lint-scripts lint-styles ## Lint project files
109 |
110 | .PHONY: lint-scripts
111 | lint-scripts:
112 | npx tslint -c tslint.json $(SCRIPTS_PATTERN)
113 |
114 | .PHONY: lint-styles
115 | lint-styles:
116 | npx stylelint --config .stylelintrc.json $(STYLES_PATTERN)
117 | npx stylelint --config .stylelintrc-components.json $(SCRIPTS_PATTERN)
118 |
--------------------------------------------------------------------------------
/BOILERPLATE_README.md:
--------------------------------------------------------------------------------
1 | # react-boilerplate
2 |
3 | | Section | Description |
4 | | ----------------------------------------------------- | --------------------------------------------------------------- |
5 | | [🎯 Objectives and context](#-objectives-and-context) | Project introduction and context |
6 | | [🚧 Dependencies](#-dependencies) | Technical dependencies and how to install them |
7 | | [🏎 Kickstart](#kickstart) | Details on how to kickstart development on the project |
8 | | [🏗 Code & architecture](#-code--architecture) | Details on the application modules and technical specifications |
9 | | [🔭 Possible improvements](#-possible-improvements) | Possible code refactors, improvements and ideas |
10 | | [🚑 Troubleshooting](#-troubleshooting) | Recurring problems and proven solutions |
11 | | [🚀 Deploy](#-deploy) | Deployment details for various enviroments |
12 |
13 | ## 🎯 Objectives and context
14 |
15 | …
16 |
17 | ### Browser support
18 |
19 | | Browser | OS | Constraint |
20 | | ------- | --- | ---------- |
21 | | … | … | … |
22 |
23 | ## 🚧 Dependencies
24 |
25 | - Node.js
26 | - NPM
27 |
28 | Canonical versions of dependencies are located in `Dockerfile` and `.tool-versions`.
29 |
30 | ## 🏎 Kickstart
31 |
32 | ### Environment variables
33 |
34 | All required environment variables are documented in [`.env.development`](./.env.development).
35 |
36 | When running scripts or `npm` commands, it is important that these variables are present in the environment. You can use `source`, [`nv`](https://github.com/jcouture/nv) or any custom script to achieve this.
37 |
38 | ### Initial setup
39 |
40 | 1. Create `.env.development.local` from empty values in [`.env.development`](./.env.development)
41 | 2. Install NPM dependencies with `make dependencies`
42 |
43 | ### Run the application in development mode
44 |
45 | To start a development server:
46 |
47 | ```bash
48 | $ npm start
49 | ```
50 |
51 | ### Build the application for production
52 |
53 | To create a production-ready build:
54 |
55 | ```bash
56 | $ make build-app
57 | ```
58 |
59 | ### Tests
60 |
61 | Tests can be ran with the following script and do not need any environment variables as they should not create side effects (eg. they should not make any network calls, they should not read cookies, etc.)
62 |
63 | ```bash
64 | $ make test
65 | ```
66 |
67 | ### Code coverage
68 |
69 | Tests can also be ran while calculating test coverage level.
70 |
71 | ```bash
72 | $ make check-code-coverage
73 | ```
74 |
75 | ### Linting
76 |
77 | Several linting and formatting tools can be ran to ensure coding style consistency:
78 |
79 | - `make lint-scripts` ensures TypeScript code follows our best practices
80 | - `make lint-styles` ensures CSS code follows our best practices
81 | - `make check-format` ensures all code is properly formatted
82 | - `make check-types` ensures types match
83 | - `make format` formats files using Prettier
84 |
85 | ### Continuous integration
86 |
87 | To ensure the project and its code are in a good state, tests and linting tools can be ran all at once:
88 |
89 | ```bash
90 | $ ./scripts/ci-check.sh
91 | ```
92 |
93 | ## 🏗 Code & architecture
94 |
95 | …
96 |
97 | ## 🔭 Possible improvements
98 |
99 | | Description | Priority | Complexity | Ideas |
100 | | ----------- | -------- | ---------- | ----- |
101 | | … | … | … | … |
102 |
103 | ## 🚑 Troubleshooting
104 |
105 | …
106 |
107 | ## 🚀 Deploy
108 |
109 | ### Versions & branches
110 |
111 | Each deployment is made from a Git tag. The codebase version is managed with [`incr`](https://github.com/jcouture/incr).
112 |
113 | ### Container
114 |
115 | A Docker image running a Node.js server can be created with `make build`, tested with `docker-compose up application` and pushed to a registry with `make push`.
116 |
--------------------------------------------------------------------------------
/BOILERPLATE_README.fr.md:
--------------------------------------------------------------------------------
1 | # react-boilerplate
2 |
3 | | Section | Description |
4 | | ------------------------------------------------------- | ------------------------------------------------------------------ |
5 | | [🎯 Objectifs et contexte](#-objectifs-et-contexte) | Introduction et contexte du projet |
6 | | [🚧 Dépendances](#-dépendances) | Dépendances techniques et comment les installer |
7 | | [🏎 Départ rapide](#-départ-rapide) | Détails sur comment démarrer rapidement le développement du projet |
8 | | [🏗 Code et architecture](#-code-et-architecture) | Détails sur les composantes techniques de l’application |
9 | | [🔭 Améliorations possibles](#-améliorations-possibles) | Améliorations, idées et _refactors_ potentiels |
10 | | [🚑 Problèmes et solutions](#-problèmes-et-solutions) | Problèmes récurrents et solutions éprouvées |
11 | | [🚀 Déploiement](#-deploiement) | Détails pour le déploiement dans différents environnements |
12 |
13 | ## 🎯 Objectifs et contexte
14 |
15 | …
16 |
17 | ### Support de navigateurs
18 |
19 | | Navigateur | OS | Contrainte |
20 | | ---------- | --- | ---------- |
21 | | … | … | … |
22 |
23 | ## 🚧 Dépendances
24 |
25 | - Node.js
26 | - NPM
27 |
28 | Les versions canoniques des dépendances sont spécifiées dans les fichiers `Dockerfile` et `.tool-versions`.
29 |
30 | ## 🏎 Départ rapide
31 |
32 | ### Variables d’environnement
33 |
34 | Toutes les variables d’environnement requises sont documentées dans [`.env.dev`](./.env.dev).
35 |
36 | Ces variables doivent être présentes dans l’environnement lorsque des commandes `npm` ou `make` sont exécutées. Plusieurs moyens sont à votre disposition pour ça, mais l’utilisation de [`nv`](https://github.com/jcouture/nv) est recommandée puisqu’elle fonctionne _out of the box_ avec les fichiers `.env.*`.
37 |
38 | ### Mise en place initiale
39 |
40 | 1. Créer `.env.development.local` à partir des valeurs vides de [`.env.development`](./.env.development)
41 | 2. Installer les avec `make dependencies`
42 |
43 | ### Lancer l’application en mode _développement_
44 |
45 | Pour démarrer un serveur de développement :
46 |
47 | ```bash
48 | $ npm run start
49 | ```
50 |
51 | ### Bâtir l’application pour la production
52 |
53 | Pour créer une _build_ prête pour la production :
54 |
55 | ```bash
56 | $ npm run build --prod
57 | ```
58 |
59 | ### Tests
60 |
61 | La suite de tests peut être exécutée à l’aide de la commande suivante et ne nécessite pas de variables d’environnements puisqu’elle ne devrait pas créer d’effets de bord (eg. pas de requêtes _networking_, pas de lecture de cookies, etc.)
62 |
63 | ```bash
64 | $ make test
65 | ```
66 |
67 | ### Couverture des tests
68 |
69 | La suite de tests peut aussi être exécutée en calculant le niveau de couverture.
70 |
71 | ```bash
72 | $ make check-code-coverage
73 | ```
74 |
75 | ### _Linting_ et _formatting_
76 |
77 | Plusieurs outils de _linting_ et de _formatting_ peuvent être exécutés pour s’assurer du respect des bonnes pratiques de code :
78 |
79 | - `make lint-scripts` s’assure que le code TypeScript respecte nos bonnes pratiques
80 | - `make lint-styles` s’assure que le code CSS respecte nos bonnes pratiques
81 | - `make check-format` valide que le code est bien formatté
82 | - `make format` formatte les fichiers en utilisant Prettier
83 |
84 | ### Intégration continue
85 |
86 | Pour s’assurer que le projet et son code sont en bon état, les outils de _linting_ et de tests peuvent être exécutés en une seule commande :
87 |
88 | ```bash
89 | $ ./scripts/ci-check.sh
90 | ```
91 |
92 | ## 🏗 Code et architecture
93 |
94 | …
95 |
96 | ## 🔭 Améliorations possibles
97 |
98 | | Description | Priorité | Complexité | Idées |
99 | | ----------- | -------- | ---------- | ----- |
100 | | … | … | … | … |
101 |
102 | ## 🚑 Problèmes et solutions
103 |
104 | …
105 |
106 | ## 🚀 Deploiement
107 |
108 | ### Versions et branches
109 |
110 | Chaque déploiement est effectué à partir d’un tag Git. La version du _codebase_ est gérée avec [`incr`](https://github.com/jcouture/incr).
111 |
112 | ### _Container_
113 |
114 | Un _container_ Docker exposant un serveur Node.js peut être créé avec `make build`, testé avec `docker-compose up application` et poussé dans un registre avec `make push`.
115 |
--------------------------------------------------------------------------------