From 518de43fd14d0adae5b37a5f17493c39ed14c30a Mon Sep 17 00:00:00 2001 From: Jonas Braathen <jonas.braathen@usit.uio.no> Date: Tue, 7 Sep 2021 23:08:23 +0200 Subject: [PATCH] Add support for injecting configuration at runtime --- frontend/.env | 2 ++ frontend/docker-entrypoint.sh | 7 +++++++ frontend/package.json | 5 +++-- frontend/public/env.js | 1 + frontend/scripts/build-env.js | 17 +++++++++++++++++ frontend/src/App.tsx | 20 +++++++++++++++----- frontend/src/appConfig.ts | 22 ++++++++++++++++++++++ 7 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 frontend/.env create mode 100644 frontend/docker-entrypoint.sh create mode 100644 frontend/public/env.js create mode 100644 frontend/scripts/build-env.js create mode 100644 frontend/src/appConfig.ts diff --git a/frontend/.env b/frontend/.env new file mode 100644 index 00000000..60a2d2a2 --- /dev/null +++ b/frontend/.env @@ -0,0 +1,2 @@ +REACT_APP_VERSION=$npm_package_version +REACT_APP_NAME=$npm_package_name diff --git a/frontend/docker-entrypoint.sh b/frontend/docker-entrypoint.sh new file mode 100644 index 00000000..6160aaad --- /dev/null +++ b/frontend/docker-entrypoint.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env sh +set -eu + +ENV_JSON=$(env | grep '^REACT_APP_*' | jq -c '. | split("\n") | map(select(. != "")) | map(split("=") | { (.[0]) : .[1] }) | reduce .[] as $item ({}; . * $item)' -R -s) +echo "window.ENV = $ENV_JSON" > /app/build/env.js + +exec "$@" diff --git a/frontend/package.json b/frontend/package.json index ce69a4b7..dc174c30 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,8 +17,9 @@ "web-vitals": "^1.1.2" }, "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", + "start": "NODE_ENV=development HOST=0.0.0.0 npm run build:env && react-scripts start", + "build": "npm run build:env && react-scripts build", + "build:env": "node scripts/build-env.js", "clean": "rm -rf node_modules", "test": "react-scripts test", "eject": "react-scripts eject" diff --git a/frontend/public/env.js b/frontend/public/env.js new file mode 100644 index 00000000..3b8657b1 --- /dev/null +++ b/frontend/public/env.js @@ -0,0 +1 @@ +window.ENV = {"NODE_ENV":"development","PUBLIC_URL":"","FAST_REFRESH":true,"REACT_APP_VERSION":"0.1.0","REACT_APP_NAME":"greg"} \ No newline at end of file diff --git a/frontend/scripts/build-env.js b/frontend/scripts/build-env.js new file mode 100644 index 00000000..27a9429f --- /dev/null +++ b/frontend/scripts/build-env.js @@ -0,0 +1,17 @@ +const dotenv = require("dotenv"); +dotenv.config(); +const fs = require("fs"); +const clientEnv = require("react-scripts/config/env.js")( + process.env.PUBLIC_URL || "" +); + +const outFile = `./public/env.js`; +const content = `window.ENV = ${JSON.stringify(clientEnv.raw)}`; + +try { + fs.writeFileSync(outFile, content, "utf8"); + console.log("Wrote client environment to", outFile); +} catch (err) { + console.error("Error while writing client environment file:", err.message); + process.exit(1); +} diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index a53698aa..de30797d 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,8 +1,10 @@ -import React from 'react'; -import logo from './logo.svg'; -import './App.css'; +import React from "react"; +import logo from "./logo.svg"; +import "./App.css"; -function App() { +import { appTimezone, appVersion, appTheme } from "./appConfig"; + +const App = () => { return ( <div className="App"> <header className="App-header"> @@ -18,9 +20,17 @@ function App() { > Learn React </a> + <p> + Version {appVersion} + <br /> + Timezone {appTimezone} + <br /> + Theme {appTheme} + <br /> + </p> </header> </div> ); -} +}; export default App; diff --git a/frontend/src/appConfig.ts b/frontend/src/appConfig.ts new file mode 100644 index 00000000..4a5c9505 --- /dev/null +++ b/frontend/src/appConfig.ts @@ -0,0 +1,22 @@ +declare global { + /* tslint:disable */ + interface Window { + ENV: any; + } +} + +/* Locate the client environment */ +const isProduction = process.env.NODE_ENV === "production"; +const env = isProduction ? window.ENV : process.env; + +/* General settings */ +export const appTimezone: string = "Europe/Oslo"; + +/* Version */ +export const appVersion: string = process.env.REACT_APP_VERSION as string; +export const appName: string = process.env.REACT_APP_NAME as string; + +/* Theming */ +export const appTheme: string = env.REACT_APP_THEME + ? (env.REACT_APP_THEME as string) + : "default"; -- GitLab