Compare commits

..

No commits in common. "7b6cd6d2864338832b178e927c917aa4c746736a" and "3324b299fd3568195d59159c447cb14fb068599a" have entirely different histories.

20 changed files with 1532 additions and 1478 deletions

2
.nvmrc
View File

@ -1 +1 @@
18.6.0
lts/*

View File

@ -2,13 +2,11 @@
"cSpell.words": [
"browserslist",
"camelcase",
"deepmerge",
"flexbugs",
"Immer",
"languagedetector",
"luxon",
"pmmmwh",
"preinstall",
"reduxjs",
"SVGR",
"tailwindcss",

View File

@ -4,12 +4,6 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.4.0] - 2022-07-25
- Added the possibility to override partial configs during deployments
- Added default output to jest (for terminal output...)
- Upgraded npm packages. Left jest on 27 because of breaking changes in 28
## [0.3.2] - 2022-07-19
- e2e step now starts a server before running tests

View File

@ -17,9 +17,6 @@ Includes:
- [Getting started](#getting-started)
- [Project structure](#project-structure)
- [Configuration](#configuration)
- [Using the `config.ts` file](#using-the-configts-file)
- [adding values](#adding-values)
<!-- tocstop -->
@ -39,11 +36,7 @@ Only the important files are shown
├── config # tool configuration
├── cypress # e2e tests
├── dist # production version
├── public
├── public # directory with public files (config, icons, etc), will be copied to dist
│ ├── i18n # directory to house i18n language files
│ ├── config.js # default runtime application config
│ └── configOverride.js # default config overrides.
├── public # directory with public files (config, icons, etc)
├── scripts # Modified default create-react-app scripts
├── src # application source
│ ├── app # redux-toolkit hooks + store
@ -55,40 +48,3 @@ Only the important files are shown
├── README.md # keep this up to date
└── tsconfig.json
```
## Configuration
This starter kit comes with runtime configuration out-of-the-box.
It achieves this with 2 config files in the public directory: `config.js` and `configOverrides.js`.
`config.js` is meant to be filled with a default for all of your application's runtime configurations.
`configOverrides.js` is meant to be replaced during deployment with environment specific runtime overrides.
### Using the `config.ts` file
To use the config you import `Config` from `config.ts` and use the typed object:
```tsx
import { Config } from "../config";
import { FunctionComponent } from "react";
export const Navbar: FunctionComponent<{}> = () => {
return <h1>{JSON.stringify(Config)}</h1>;
};
```
### adding values
To add a value to the runtime config you have to take 2 steps:
1. Add a type to the `RuntimeConfig` type in [src/infrastructure/config/RunTimeConfig.ts](./src/infrastructure/config/RunTimeConfig.ts)
```tsx
type RunTimeConfig = {
version: number;
name: string;
myNewKey: string;
};
```
2. Add a key (if required) to [public/config.js](./public/config.js)

View File

@ -4,7 +4,6 @@ const config = {
roots: ["<rootDir>/src"],
collectCoverageFrom: ["src/**/*.{js,jsx,ts,tsx}", "!src/**/*.d.ts"],
reporters: [
"default",
[
"jest-junit",
{

2789
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "react-starter-kit",
"version": "0.4.0",
"version": "0.2.0",
"description": "A modern, create-react-app-based, starter kit for React projects",
"keywords": [
"react",
@ -30,12 +30,12 @@
"e2e": "cypress open -d --e2e",
"e2e-ci": "start-server-and-test start http://localhost:3000 cypress-run",
"postinstall": "husky install",
"lint": "GLOBIGNORE='src/types' && eslint src/**",
"lint": "eslint src/**",
"lint-staged": "lint-staged --relative",
"organize-package-json": "npx format-package -w && npx sort-package-json",
"pretty-quick": "pretty-quick --staged",
"start": "node scripts/start.js",
"test": "node scripts/test.js --verbose",
"test": "node scripts/test.js",
"test-ci": "node scripts/test.js --ci --coverage",
"test-live-coverage": " concurrently --kill-others \"npm run test-with-coverage\" \"npx http-server -c-1 coverage/lcov-report\"",
"test-with-coverage": "node scripts/test.js --coverage",
@ -46,7 +46,6 @@
},
"dependencies": {
"@reduxjs/toolkit": "^1.8.3",
"deepmerge": "^4.2.2",
"i18next-http-backend": "^1.4.1",
"luxon": "^2.4.0",
"react": "^18.2.0",
@ -58,16 +57,16 @@
"tailwindcss": "^3.1.6"
},
"devDependencies": {
"@babel/core": "^7.18.9",
"@babel/core": "^7.18.6",
"@mastermindzh/prettier-config": "^1.0.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
"@svgr/webpack": "^5.5.0",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^14.3.0",
"@testing-library/user-event": "^14.2.5",
"@types/jest": "^28.1.6",
"@types/luxon": "^3.0.0",
"@types/node": "^18.6.1",
"@types/luxon": "^2.3.2",
"@types/node": "^18.0.6",
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6",
"babel-jest": "^27.4.2",
@ -78,13 +77,13 @@
"browserslist": "^4.21.2",
"camelcase": "^6.2.1",
"case-sensitive-paths-webpack-plugin": "^2.4.0",
"concurrently": "^7.3.0",
"concurrently": "^7.2.2",
"css-loader": "^6.7.1",
"css-minimizer-webpack-plugin": "^3.2.0",
"cypress": "^10.3.1",
"cypress": "^10.3.0",
"dotenv": "^10.0.0",
"dotenv-expand": "^5.1.0",
"eslint": "^8.20.0",
"eslint": "^8.3.0",
"eslint-config-prettier": "^8.5.0",
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-cypress": "^2.12.1",
@ -101,7 +100,6 @@
"identity-obj-proxy": "^3.0.0",
"immer": "^9.0.15",
"jest": "^27.4.3",
"jest-environment-jsdom": "^27.4.3",
"jest-junit": "^14.0.0",
"jest-resolve": "^27.4.2",
"jest-watch-typeahead": "^1.0.0",

View File

@ -1,13 +1,11 @@
const defaultConfig = {
const config = {
version: "0.1.0",
name: "React-starter-kit",
};
// ignore this :)
try {
window.defaultConfig = defaultConfig;
window.config = config;
if (module) {
module.exports = defaultConfig;
module.exports = config;
}
} catch {
// ignore

View File

@ -1,17 +0,0 @@
/**
* This is the config override file.
* This file is meant to be replaced during deployment with override values compared to the regular config.js
* For development purposes this file can be completely empty
*/
const configOverride = {};
// ignore this :)
try {
window.configOverride = configOverride;
if (module) {
module.exports = configOverride;
}
} catch {
// ignore
}

View File

@ -4,7 +4,7 @@
},
"navBar": {
"intro": "Our fancy header with navigation.",
"version": "version:",
"version": "App version:",
"currentDate": "Today's date: {{date, formattedDate}}"
},
"nav": {

View File

@ -4,7 +4,7 @@
},
"navBar": {
"intro": "Een fancy header met navigatie",
"version": "versie:",
"version": "Aplicatie versie:",
"currentDate": "De datum van vandaag: {{date, formattedDate}}"
},
"nav": {

View File

@ -1,22 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/icon/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="React base project" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/icon/apple-icon-180x180.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>React Base App</title>
<script src="%PUBLIC_URL%/config.js"></script>
<script src="%PUBLIC_URL%/configOverride.js"></script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/icon/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="React base project" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/icon/apple-icon-180x180.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>React Base App</title>
<script src="%PUBLIC_URL%/config.js"></script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>

View File

@ -0,0 +1,5 @@
type RunTimeConfig = {
version: number;
};
export const Config = (window as any).config as RunTimeConfig;

View File

@ -1,4 +0,0 @@
export interface RunTimeConfig {
version: number;
name: string;
}

View File

@ -1,15 +0,0 @@
import deepmerge from "deepmerge";
/**
* gets and merges both the regular config and the override config from the window
* into window.mergedConfig
*/
export const mergeConfigs = () => {
if (!window.mergedConfig) {
window.mergedConfig = deepmerge(window.defaultConfig, window.configOverride ?? {});
}
};
mergeConfigs();
export const Config = window.mergedConfig;

View File

@ -1 +0,0 @@
export * from "./config";

View File

@ -13,7 +13,7 @@ export const Navbar: FunctionComponent<Props> = () => {
<h1>{translate("navBar.intro")}</h1>
<p>
{/* trans can also be used to translate */}
{Config.name} <Trans i18nKey="navBar.version">version:</Trans>
<Trans i18nKey="navBar.version">App version:</Trans>
{JSON.stringify(Config.version)}
</p>

View File

@ -4,68 +4,68 @@
declare namespace NodeJS {
interface ProcessEnv {
readonly NODE_ENV: "development" | "production" | "test";
readonly NODE_ENV: 'development' | 'production' | 'test';
readonly PUBLIC_URL: string;
}
}
declare module "*.avif" {
declare module '*.avif' {
const src: string;
export default src;
}
declare module "*.bmp" {
declare module '*.bmp' {
const src: string;
export default src;
}
declare module "*.gif" {
declare module '*.gif' {
const src: string;
export default src;
}
declare module "*.jpg" {
declare module '*.jpg' {
const src: string;
export default src;
}
declare module "*.jpeg" {
declare module '*.jpeg' {
const src: string;
export default src;
}
declare module "*.png" {
declare module '*.png' {
const src: string;
export default src;
}
declare module "*.webp" {
const src: string;
export default src;
declare module '*.webp' {
const src: string;
export default src;
}
declare module "*.svg" {
import * as React from "react";
declare module '*.svg' {
import * as React from 'react';
export const ReactComponent: React.FunctionComponent<
React.SVGProps<SVGSVGElement> & { title?: string }
>;
export const ReactComponent: React.FunctionComponent<React.SVGProps<
SVGSVGElement
> & { title?: string }>;
const src: string;
export default src;
}
declare module "*.module.css" {
declare module '*.module.css' {
const classes: { readonly [key: string]: string };
export default classes;
}
declare module "*.module.scss" {
declare module '*.module.scss' {
const classes: { readonly [key: string]: string };
export default classes;
}
declare module "*.module.sass" {
declare module '*.module.sass' {
const classes: { readonly [key: string]: string };
export default classes;
}

View File

@ -4,5 +4,4 @@
// learn more: https://github.com/testing-library/jest-dom
import "@testing-library/jest-dom/extend-expect";
window.defaultConfig = require("./../public/config");
window.configOverride = require("./../public/configOverride");
(window as any).config = require("./../public/config");

View File

@ -1,11 +0,0 @@
import { RunTimeConfig } from "../infrastructure/config/RunTimeConfig";
declare global {
interface Window {
mergedConfig: RunTimeConfig;
defaultConfig: RunTimeConfig;
configOverride: Partial<RunTimeConfig>;
}
}
export {};