From 3da8b226e5511ee8a892e1ee2073fd416b551ac8 Mon Sep 17 00:00:00 2001 From: Mars Hall Date: Tue, 6 Sep 2016 07:58:36 -0700 Subject: [PATCH 01/18] Render env vars with heroku-buildpack-mustache --- .buildpacks | 3 ++- README.md | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/.buildpacks b/.buildpacks index 103d8375..856f993c 100644 --- a/.buildpacks +++ b/.buildpacks @@ -1,3 +1,4 @@ https://github.com/heroku/heroku-buildpack-nodejs.git -https://github.com/mars/create-react-app-inner-buildpack.git#v1.3.0 +https://github.com/mars/create-react-app-inner-buildpack.git#stateless-build +https://github.com/heroku/heroku-buildpack-mustache.git https://github.com/heroku/heroku-buildpack-static.git diff --git a/README.md b/README.md index cdbf3cba..2ece729d 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,40 @@ git commit --allow-empty -m "Set REACT_APP_HELLO config var" git push heroku master ``` +#### Runtime configuration + +🚨 Experimental using [heroku-buildpack-mustache](https://github.com/heroku/heroku-buildpack-mustache). + +Create `mustache_templates.conf` with the following content: + +``` +build/index.html +``` + +Add script element to `index.html` to capture environment variable values: + +```html + + + + +``` + +Then, use these globals within the React app. + +```javascript +const hello = react_app_env.HELLO; +``` + +Globals are normally considered dirty, so you may build up a more acceptable pattern for using these values in an app, such as: + +* create a module to read the global values and make them available via `require` +* create a [higher order component [HOC]](https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750) that makes the values available via props + Version compatibility --------------------- From 690836f555147a5d874ad27e19abb3f8be8444c3 Mon Sep 17 00:00:00 2001 From: Mars Hall Date: Tue, 6 Sep 2016 08:24:48 -0700 Subject: [PATCH 02/18] Build is stateful when using runtime env vars --- .buildpacks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildpacks b/.buildpacks index 856f993c..4b087c6e 100644 --- a/.buildpacks +++ b/.buildpacks @@ -1,4 +1,4 @@ https://github.com/heroku/heroku-buildpack-nodejs.git -https://github.com/mars/create-react-app-inner-buildpack.git#stateless-build +https://github.com/mars/create-react-app-inner-buildpack.git https://github.com/heroku/heroku-buildpack-mustache.git https://github.com/heroku/heroku-buildpack-static.git From 4e6e24d8a145929a6e5e0cdc163e1d1124557315 Mon Sep 17 00:00:00 2001 From: Mars Hall Date: Tue, 6 Sep 2016 09:33:17 -0700 Subject: [PATCH 03/18] Setup default `mustache_templates.conf`; reduce manual config --- README.md | 29 ++++++++++++++++++----------- bin/compile | 9 +++++++++ 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 2ece729d..83858381 100644 --- a/README.md +++ b/README.md @@ -108,15 +108,23 @@ Create a `static.json` file to configure the web server for clean [`browserHisto ### Environment variables -[`REACT_APP_*`](https://github.com/facebookincubator/create-react-app/blob/v0.2.3/template/README.md#adding-custom-environment-variables) and [`NODE_*`](https://github.com/facebookincubator/create-react-app/pull/476) environment variables are supported on Heroku during the compile phase, when `npm run build` is executed to generate the JavaScript bundle. - Set [config vars on a Heroku app](https://devcenter.heroku.com/articles/config-vars) like this: ```bash heroku config:set REACT_APP_HELLO='I love sushi!' ``` -♻️ The app must be re-deployed for this change to take effect, because the automatic restart after a config var change does not rebuild the JavaScript bundle. +#### Compile-time configuration + +For variables that will not change between environments, such as: + + * version number + * commit sha or number + * browser support flags + +[`REACT_APP_*`](https://github.com/facebookincubator/create-react-app/blob/v0.2.3/template/README.md#adding-custom-environment-variables) and [`NODE_*`](https://github.com/facebookincubator/create-react-app/pull/476) environment variables are supported on Heroku during the compile phase, when `npm run build` is executed to generate the JavaScript bundle. + +♻️ The app must be re-deployed for compiled changed to take effect, because the automatic restart after a config var change does not rebuild the JavaScript bundle. ```bash git commit --allow-empty -m "Set REACT_APP_HELLO config var" @@ -125,13 +133,11 @@ git push heroku master #### Runtime configuration -🚨 Experimental using [heroku-buildpack-mustache](https://github.com/heroku/heroku-buildpack-mustache). - -Create `mustache_templates.conf` with the following content: +For variables that may change between releases or environments: -``` -build/index.html -``` + * Heroku add-on config vars + * URLs to APIs + * secret tokens Add script element to `index.html` to capture environment variable values: @@ -141,7 +147,6 @@ Add script element to `index.html` to capture environment variable values: ``` @@ -182,7 +187,9 @@ This buildpack composes three buildpacks (specified in [`.buildpacks`](.buildpac 2. [`mars/create-react-app-inner-buildpack`](https://github.com/mars/create-react-app-inner-buildpack) * generates the [default `static.json`](#customization) * performs the production build for create-react-app, `npm run build` -3. [`heroku/static` buildpack](https://github.com/heroku/heroku-buildpack-static) +3. [`heroku/heroku-buildpack-mustache`](https://github.com/heroku/heroku-buildpack-mustache) + * performs [runtime replacement of environment variables](#runtime-configuration) +4. [`heroku/static` buildpack](https://github.com/heroku/heroku-buildpack-static) * [Nginx](http://nginx.org/en/) web server * handy static website & SPA (single-page app) [customization options](https://github.com/heroku/heroku-buildpack-static#configuration) diff --git a/bin/compile b/bin/compile index 7664b394..ecf67285 100644 --- a/bin/compile +++ b/bin/compile @@ -35,6 +35,15 @@ rm -rf $dir # * Install `npm build` tooling. export NPM_CONFIG_PRODUCTION=false +# Ensure this config exists so the buildpack successfully detects +MUSTACHE_TEMPLATES_CONF="$BUILD_DIR/mustache_templates.conf" +if [ -f "$MUSTACHE_TEMPLATES_CONF" ]; then + echo 'Using existing `mustache_templates.conf`' | indent +else + echo 'Writing `mustache_templates.conf` to support create-react-app' | indent + echo "build/index.html" > "$MUSTACHE_TEMPLATES_CONF" +fi + echo "=====> Downloading Buildpack: $url" if [[ "$url" =~ \.tgz$ ]] || [[ "$url" =~ \.tgz\? ]]; then From f68f1ed3239a581277f8880c40a1939ccb3aeede Mon Sep 17 00:00:00 2001 From: Mars Hall Date: Tue, 6 Sep 2016 09:40:19 -0700 Subject: [PATCH 04/18] =?UTF-8?q?=F0=9F=93=9A=20any=20env=20var=20is=20acc?= =?UTF-8?q?essible=20at=20runtime?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 83858381..5831eddb 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,8 @@ For variables that may change between releases or environments: * URLs to APIs * secret tokens +Any environment variable is accessible at runtime, not just `REACT_APP_*`. + Add script element to `index.html` to capture environment variable values: ```html From 8738f4381ce43525e3d7e43ee4b6c2985d1fe112 Mon Sep 17 00:00:00 2001 From: Mars Hall Date: Tue, 6 Sep 2016 10:28:27 -0700 Subject: [PATCH 05/18] Move mustache template conf into inner buildpack --- .buildpacks | 2 +- bin/compile | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/.buildpacks b/.buildpacks index 4b087c6e..bfcbcab9 100644 --- a/.buildpacks +++ b/.buildpacks @@ -1,4 +1,4 @@ https://github.com/heroku/heroku-buildpack-nodejs.git -https://github.com/mars/create-react-app-inner-buildpack.git +https://github.com/mars/create-react-app-inner-buildpack.git#runtime-env-vars https://github.com/heroku/heroku-buildpack-mustache.git https://github.com/heroku/heroku-buildpack-static.git diff --git a/bin/compile b/bin/compile index ecf67285..7664b394 100644 --- a/bin/compile +++ b/bin/compile @@ -35,15 +35,6 @@ rm -rf $dir # * Install `npm build` tooling. export NPM_CONFIG_PRODUCTION=false -# Ensure this config exists so the buildpack successfully detects -MUSTACHE_TEMPLATES_CONF="$BUILD_DIR/mustache_templates.conf" -if [ -f "$MUSTACHE_TEMPLATES_CONF" ]; then - echo 'Using existing `mustache_templates.conf`' | indent -else - echo 'Writing `mustache_templates.conf` to support create-react-app' | indent - echo "build/index.html" > "$MUSTACHE_TEMPLATES_CONF" -fi - echo "=====> Downloading Buildpack: $url" if [[ "$url" =~ \.tgz$ ]] || [[ "$url" =~ \.tgz\? ]]; then From 8be1c227b03ce24b4a2bd0fb77eb6ee327c07e1f Mon Sep 17 00:00:00 2001 From: Mars Hall Date: Tue, 6 Sep 2016 10:31:30 -0700 Subject: [PATCH 06/18] =?UTF-8?q?=F0=9F=93=9A=20doc=20inner=20buildpack=20?= =?UTF-8?q?handling=20of=20mustache=20templates=20conf?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5831eddb..3b64943d 100644 --- a/README.md +++ b/README.md @@ -187,6 +187,7 @@ This buildpack composes three buildpacks (specified in [`.buildpacks`](.buildpac * complete Node.js enviroment to support the webpack build * `node_modules` cached between deployments 2. [`mars/create-react-app-inner-buildpack`](https://github.com/mars/create-react-app-inner-buildpack) + * generates the default `mustache_templates.conf` * generates the [default `static.json`](#customization) * performs the production build for create-react-app, `npm run build` 3. [`heroku/heroku-buildpack-mustache`](https://github.com/heroku/heroku-buildpack-mustache) From c49d71344ec61b4893d5dc5ffcbfabe3a6bf967f Mon Sep 17 00:00:00 2001 From: Mars Hall Date: Tue, 6 Sep 2016 10:32:38 -0700 Subject: [PATCH 07/18] =?UTF-8?q?=F0=9F=93=9A=20correction?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3b64943d..438226c3 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,7 @@ Usually, using master [as directed in the main instructions](#create-the-heroku- Architecture πŸ™ ------------ -This buildpack composes three buildpacks (specified in [`.buildpacks`](.buildpacks)) to support **no-configuration deployment** on Heroku: +This buildpack composes several buildpacks (specified in [`.buildpacks`](.buildpacks)) to support **no-configuration deployment** on Heroku: 1. [`heroku/nodejs` buildpack](https://github.com/heroku/heroku-buildpack-nodejs) * complete Node.js enviroment to support the webpack build From 1c62a3b9efc8e10dd05b7eff3c23e251ed229180 Mon Sep 17 00:00:00 2001 From: Mars Hall Date: Wed, 12 Oct 2016 17:53:42 -0700 Subject: [PATCH 08/18] Support runtime env vars via npm module `@mars/heroku-js-runtime-env` --- .buildpacks | 2 +- README.md | 32 +++++++++++++++----------------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/.buildpacks b/.buildpacks index bfcbcab9..45b5f389 100644 --- a/.buildpacks +++ b/.buildpacks @@ -1,4 +1,4 @@ https://github.com/heroku/heroku-buildpack-nodejs.git -https://github.com/mars/create-react-app-inner-buildpack.git#runtime-env-vars +https://github.com/mars/create-react-app-inner-buildpack.git#modular-runtime-env-vars https://github.com/heroku/heroku-buildpack-mustache.git https://github.com/heroku/heroku-buildpack-static.git diff --git a/README.md b/README.md index 438226c3..e76f4675 100644 --- a/README.md +++ b/README.md @@ -141,28 +141,26 @@ For variables that may change between releases or environments: Any environment variable is accessible at runtime, not just `REACT_APP_*`. -Add script element to `index.html` to capture environment variable values: - -```html - - - - -``` +Install the runtime vars npm package, and then require/import it to use the vars anywhere in the app: -Then, use these globals within the React app. +```bash +npm install @mars/heroku-js-runtime-env --save +``` ```javascript -const hello = react_app_env.HELLO; -``` +import React, { Component } from 'react'; +import runtimeEnv from '@mars/heroku-js-runtime-env'; -Globals are normally considered dirty, so you may build up a more acceptable pattern for using these values in an app, such as: +const env = runtimeEnv(); -* create a module to read the global values and make them available via `require` -* create a [higher order component [HOC]](https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750) that makes the values available via props +class App extends Component { + render() { + return ( + Runtime env var example: { env.REACT_APP_HELLO } + ); + } +} +``` Version compatibility --------------------- From 6029edeacc0bf83ab7925c9c8c428809e7deff18 Mon Sep 17 00:00:00 2001 From: Mars Hall Date: Wed, 12 Oct 2016 19:09:59 -0700 Subject: [PATCH 09/18] =?UTF-8?q?=F0=9F=93=9A=20improve=20runtime=20env=20?= =?UTF-8?q?docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e76f4675..dbb1c248 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,8 @@ Create a `static.json` file to configure the web server for clean [`browserHisto ### Environment variables +[`REACT_APP_*`](https://github.com/facebookincubator/create-react-app/blob/v0.2.3/template/README.md#adding-custom-environment-variables) are supported with this buildpack. + Set [config vars on a Heroku app](https://devcenter.heroku.com/articles/config-vars) like this: ```bash @@ -122,8 +124,6 @@ For variables that will not change between environments, such as: * commit sha or number * browser support flags -[`REACT_APP_*`](https://github.com/facebookincubator/create-react-app/blob/v0.2.3/template/README.md#adding-custom-environment-variables) and [`NODE_*`](https://github.com/facebookincubator/create-react-app/pull/476) environment variables are supported on Heroku during the compile phase, when `npm run build` is executed to generate the JavaScript bundle. - ♻️ The app must be re-deployed for compiled changed to take effect, because the automatic restart after a config var change does not rebuild the JavaScript bundle. ```bash @@ -139,9 +139,9 @@ For variables that may change between releases or environments: * URLs to APIs * secret tokens -Any environment variable is accessible at runtime, not just `REACT_APP_*`. +Runtime variables will be refreshed when setting new [config vars](https://devcenter.heroku.com/articles/config-vars), promoting through a [pipeline](https://devcenter.heroku.com/articles/pipelines), or [rolling back](https://devcenter.heroku.com/articles/releases#rollback) to a previous release. -Install the runtime vars npm package, and then require/import it to use the vars anywhere in the app: +Install the runtime vars npm package, and then require/import it to use the vars within components: ```bash npm install @mars/heroku-js-runtime-env --save From 1785a2d87a4ae1e9b4e5758f19fcff0a69020a8f Mon Sep 17 00:00:00 2001 From: Mars Hall Date: Fri, 14 Oct 2016 11:54:41 -0700 Subject: [PATCH 10/18] Remove Mustache templating --- .buildpacks | 1 - README.md | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.buildpacks b/.buildpacks index 45b5f389..5fb3ac8e 100644 --- a/.buildpacks +++ b/.buildpacks @@ -1,4 +1,3 @@ https://github.com/heroku/heroku-buildpack-nodejs.git https://github.com/mars/create-react-app-inner-buildpack.git#modular-runtime-env-vars -https://github.com/heroku/heroku-buildpack-mustache.git https://github.com/heroku/heroku-buildpack-static.git diff --git a/README.md b/README.md index dbb1c248..c8188121 100644 --- a/README.md +++ b/README.md @@ -185,12 +185,10 @@ This buildpack composes several buildpacks (specified in [`.buildpacks`](.buildp * complete Node.js enviroment to support the webpack build * `node_modules` cached between deployments 2. [`mars/create-react-app-inner-buildpack`](https://github.com/mars/create-react-app-inner-buildpack) - * generates the default `mustache_templates.conf` + * enables [runtime environment variables](#runtime-configuration) * generates the [default `static.json`](#customization) * performs the production build for create-react-app, `npm run build` -3. [`heroku/heroku-buildpack-mustache`](https://github.com/heroku/heroku-buildpack-mustache) - * performs [runtime replacement of environment variables](#runtime-configuration) -4. [`heroku/static` buildpack](https://github.com/heroku/heroku-buildpack-static) +3. [`heroku/static` buildpack](https://github.com/heroku/heroku-buildpack-static) * [Nginx](http://nginx.org/en/) web server * handy static website & SPA (single-page app) [customization options](https://github.com/heroku/heroku-buildpack-static#configuration) From 92334255471dc270594093731afede3874e0ce88 Mon Sep 17 00:00:00 2001 From: Mars Hall Date: Fri, 14 Oct 2016 18:08:55 -0700 Subject: [PATCH 11/18] =?UTF-8?q?=F0=9F=93=9A=20more=20about=20runtime=20c?= =?UTF-8?q?onfig?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c8188121..09c72686 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,8 @@ Set [config vars on a Heroku app](https://devcenter.heroku.com/articles/config-v heroku config:set REACT_APP_HELLO='I love sushi!' ``` +You may implement variables at [compile-time](#compile-time-configuration) or [runtime](#runtime-configuration). + #### Compile-time configuration For variables that will not change between environments, such as: @@ -124,7 +126,7 @@ For variables that will not change between environments, such as: * commit sha or number * browser support flags -♻️ The app must be re-deployed for compiled changed to take effect, because the automatic restart after a config var change does not rebuild the JavaScript bundle. +♻️ The app must be re-deployed for compiled changed to take effect, because the automatic restart after a config var change does not rebuild the JavaScript bundle. If this is not desired behavior, then use [runtime configuration](#runtime-configuration) instead. ```bash git commit --allow-empty -m "Set REACT_APP_HELLO config var" @@ -139,7 +141,7 @@ For variables that may change between releases or environments: * URLs to APIs * secret tokens -Runtime variables will be refreshed when setting new [config vars](https://devcenter.heroku.com/articles/config-vars), promoting through a [pipeline](https://devcenter.heroku.com/articles/pipelines), or [rolling back](https://devcenter.heroku.com/articles/releases#rollback) to a previous release. +Runtime variables will be refreshed for every release, when setting new [config vars](https://devcenter.heroku.com/articles/config-vars), promoting through a [pipeline](https://devcenter.heroku.com/articles/pipelines), or [rolling back](https://devcenter.heroku.com/articles/releases#rollback) to a previous release. Install the runtime vars npm package, and then require/import it to use the vars within components: @@ -151,10 +153,10 @@ npm install @mars/heroku-js-runtime-env --save import React, { Component } from 'react'; import runtimeEnv from '@mars/heroku-js-runtime-env'; -const env = runtimeEnv(); - class App extends Component { render() { + const env = runtimeEnv(); + return ( Runtime env var example: { env.REACT_APP_HELLO } ); @@ -162,6 +164,12 @@ class App extends Component { } ``` +These runtime values will be serialized as JSON, so their values must be compatible with JSON: + +* Quote `"` will be auto-escaped +* Backslash `\` is a control character, so the standard [JSON string rules](http://json.org) apply +* All other UTF-8 characters may be used freely. + Version compatibility --------------------- From 157cbc01517d0f1aba5947983e17ba4831d65996 Mon Sep 17 00:00:00 2001 From: Mars Hall Date: Sat, 15 Oct 2016 09:18:44 -0700 Subject: [PATCH 12/18] =?UTF-8?q?=F0=9F=93=9A=20improving=20compile-time?= =?UTF-8?q?=20vs=20runtime=20config=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 09c72686..beb6568b 100644 --- a/README.md +++ b/README.md @@ -110,53 +110,67 @@ Create a `static.json` file to configure the web server for clean [`browserHisto [`REACT_APP_*`](https://github.com/facebookincubator/create-react-app/blob/v0.2.3/template/README.md#adding-custom-environment-variables) are supported with this buildpack. +#### Setting + Set [config vars on a Heroku app](https://devcenter.heroku.com/articles/config-vars) like this: ```bash heroku config:set REACT_APP_HELLO='I love sushi!' ``` -You may implement variables at [compile-time](#compile-time-configuration) or [runtime](#runtime-configuration). +#### Compile-time vs runtime -#### Compile-time configuration +Two versions of configuration variables are supported. Note that compile-time is the standard way javascript apps are configured. We've implemented runtime configuration to take advantage of [Heroku Flow](https://www.heroku.com/continuous-delivery). + +Requirement | [Compile-time](#compile-time-configuration) | [Runtime](#runtime-configuration) +--- |:---:|:---: +never changes for the build | βœ“ | +updates immediately when setting new [config vars](https://devcenter.heroku.com/articles/config-vars) | | βœ“ +different values for staging & production (in a [pipeline](https://devcenter.heroku.com/articles/pipelines)) | | βœ“ -For variables that will not change between environments, such as: +Use-case | [Compile-time](#compile-time-configuration) | [Runtime](#runtime-configuration) +--- |:---:|:---: +build version number | βœ“ | +browser support flags | βœ“ | +external/API URL | | βœ“ +secret token | | βœ“ +Add-on config var | | βœ“ + +#### Compile-time configuration - * version number - * commit sha or number - * browser support flags +For **internal values** that *will not change* between releases or environments. -♻️ The app must be re-deployed for compiled changed to take effect, because the automatic restart after a config var change does not rebuild the JavaScript bundle. If this is not desired behavior, then use [runtime configuration](#runtime-configuration) instead. +♻️ The app must be re-deployed for compiled changes to take effect, because the automatic restart after a config var change does not rebuild the JavaScript bundle. ```bash +heroku config:set REACT_APP_HELLO='I love sushi!' + git commit --allow-empty -m "Set REACT_APP_HELLO config var" git push heroku master ``` #### Runtime configuration -For variables that may change between releases or environments: - - * Heroku add-on config vars - * URLs to APIs - * secret tokens +For **external values** that *may change* between releases or environments. -Runtime variables will be refreshed for every release, when setting new [config vars](https://devcenter.heroku.com/articles/config-vars), promoting through a [pipeline](https://devcenter.heroku.com/articles/pipelines), or [rolling back](https://devcenter.heroku.com/articles/releases#rollback) to a previous release. - -Install the runtime vars npm package, and then require/import it to use the vars within components: +Install the [runtime env npm package](https://www.npmjs.com/package/@mars/heroku-js-runtime-env): ```bash npm install @mars/heroku-js-runtime-env --save ``` +Then, require/import it to use the vars within components: + ```javascript import React, { Component } from 'react'; import runtimeEnv from '@mars/heroku-js-runtime-env'; class App extends Component { render() { + // Load the env object. const env = runtimeEnv(); + // …then use values just like `process.env` return ( Runtime env var example: { env.REACT_APP_HELLO } ); From 2500869a440c16a23bca467807b1f754e3f60b10 Mon Sep 17 00:00:00 2001 From: Mars Hall Date: Sat, 15 Oct 2016 18:02:09 -0700 Subject: [PATCH 13/18] =?UTF-8?q?=F0=9F=93=9A=20more=20revs=20to=20Compile?= =?UTF-8?q?-time=20vs=20Runtime=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 51 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index beb6568b..a37e5144 100644 --- a/README.md +++ b/README.md @@ -108,11 +108,11 @@ Create a `static.json` file to configure the web server for clean [`browserHisto ### Environment variables -[`REACT_APP_*`](https://github.com/facebookincubator/create-react-app/blob/v0.2.3/template/README.md#adding-custom-environment-variables) are supported with this buildpack. +[`REACT_APP_*`](https://github.com/facebookincubator/create-react-app/blob/v0.2.3/template/README.md#adding-custom-environment-variables) environment variable are supported with this buildpack. -#### Setting +🀐 *Be careful not to export secrets. These values may be accessed by anyone who can see the React app.* -Set [config vars on a Heroku app](https://devcenter.heroku.com/articles/config-vars) like this: +Set [env vars on a Heroku app](https://devcenter.heroku.com/articles/config-vars) like this: ```bash heroku config:set REACT_APP_HELLO='I love sushi!' @@ -120,27 +120,22 @@ heroku config:set REACT_APP_HELLO='I love sushi!' #### Compile-time vs runtime -Two versions of configuration variables are supported. Note that compile-time is the standard way javascript apps are configured. We've implemented runtime configuration to take advantage of [Heroku Flow](https://www.heroku.com/continuous-delivery). +Two versions of variables are supported. In addition to compile-time variables applied during [build](https://github.com/facebookincubator/create-react-app#npm-run-build), this buildpack supports runtime configuration as well. Requirement | [Compile-time](#compile-time-configuration) | [Runtime](#runtime-configuration) ---- |:---:|:---: -never changes for the build | βœ“ | +:--- |:---:|:---: +never changes for a build | βœ“ | +support for [continuous delivery](https://www.heroku.com/continuous-delivery) | | βœ“ updates immediately when setting new [config vars](https://devcenter.heroku.com/articles/config-vars) | | βœ“ different values for staging & production (in a [pipeline](https://devcenter.heroku.com/articles/pipelines)) | | βœ“ - -Use-case | [Compile-time](#compile-time-configuration) | [Runtime](#runtime-configuration) ---- |:---:|:---: -build version number | βœ“ | -browser support flags | βœ“ | -external/API URL | | βœ“ -secret token | | βœ“ -Add-on config var | | βœ“ +ex: `REACT_APP_BUILD_VERSION` (static fact about the bundle) | βœ“ | +ex: `REACT_APP_DEBUG_ASSERTIONS` ([prune code from bundle](https://webpack.github.io/docs/list-of-plugins.html#defineplugin)) | βœ“ | +ex: `REACT_APP_API_URL` (transient, external reference) | | βœ“ +ex: `REACT_APP_FILEPICKER_API_KEY` ([Add-on config vars](#add-on-config-vars)) | | βœ“ #### Compile-time configuration -For **internal values** that *will not change* between releases or environments. - -♻️ The app must be re-deployed for compiled changes to take effect, because the automatic restart after a config var change does not rebuild the JavaScript bundle. +♻️ The app must be re-deployed for compiled changes to take effect. ```bash heroku config:set REACT_APP_HELLO='I love sushi!' @@ -151,8 +146,6 @@ git push heroku master #### Runtime configuration -For **external values** that *may change* between releases or environments. - Install the [runtime env npm package](https://www.npmjs.com/package/@mars/heroku-js-runtime-env): ```bash @@ -184,6 +177,26 @@ These runtime values will be serialized as JSON, so their values must be compati * Backslash `\` is a control character, so the standard [JSON string rules](http://json.org) apply * All other UTF-8 characters may be used freely. +#### Add-on config vars + +🀐 *Be careful not to export secrets. These values may be accessed by anyone who can see the React app.* + +Use a custom [`.profile.d` script](https://devcenter.heroku.com/articles/buildpack-api#profile-d-scripts) to make variables visible to the React app by prefixing them with `REACT_APP_`. + +1. create `.profile.d/000-react-app-exports.sh` +1. make it executable `chmod +x .profile.d/000-react-app-exports.sh` +1. add an `export` line for each variable: + + ```bash + export REACT_APP_ADDON_CONFIG=${ADDON_CONFIG:-} + ``` + +For example, to use the API key for the [Filestack](https://elements.heroku.com/addons/filepicker) JS image uploader: + +```bash +export REACT_APP_FILEPICKER_API_KEY=${FILEPICKER_API_KEY:-} +``` + Version compatibility --------------------- From dc5dd78cc3435eab5bc6a9f7f78ab8a12488216c Mon Sep 17 00:00:00 2001 From: Mars Hall Date: Sat, 15 Oct 2016 18:07:58 -0700 Subject: [PATCH 14/18] =?UTF-8?q?=F0=9F=93=9A=20refine=20Compile-time=20vs?= =?UTF-8?q?=20Runtime?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a37e5144..2324ad92 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ Set [env vars on a Heroku app](https://devcenter.heroku.com/articles/config-vars heroku config:set REACT_APP_HELLO='I love sushi!' ``` -#### Compile-time vs runtime +#### Compile-time vs Runtime Two versions of variables are supported. In addition to compile-time variables applied during [build](https://github.com/facebookincubator/create-react-app#npm-run-build), this buildpack supports runtime configuration as well. @@ -171,11 +171,11 @@ class App extends Component { } ``` -These runtime values will be serialized as JSON, so their values must be compatible with JSON: +πŸ‘“ These runtime values will be serialized as JSON, so their values must be compatible with JSON: -* Quote `"` will be auto-escaped -* Backslash `\` is a control character, so the standard [JSON string rules](http://json.org) apply -* All other UTF-8 characters may be used freely. +* quote `"` will be auto-escaped +* backslash `\` is a control character, so the standard [JSON string rules](http://json.org) apply +* all other UTF-8 characters may be used freely. #### Add-on config vars @@ -190,6 +190,7 @@ Use a custom [`.profile.d` script](https://devcenter.heroku.com/articles/buildpa ```bash export REACT_APP_ADDON_CONFIG=${ADDON_CONFIG:-} ``` +1. set-up & use [Runtime configuration](#runtime-configuration) to access the variables For example, to use the API key for the [Filestack](https://elements.heroku.com/addons/filepicker) JS image uploader: From b56139cbe7fe3b997b062b54bb1f870c68f96d69 Mon Sep 17 00:00:00 2001 From: Mars Hall Date: Sat, 15 Oct 2016 19:07:42 -0700 Subject: [PATCH 15/18] =?UTF-8?q?=F0=9F=93=9A=20dotenv=20usage=20&=20creat?= =?UTF-8?q?e-react-app=200.7=20compatibility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 2324ad92..ac7146ae 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,8 @@ Set [env vars on a Heroku app](https://devcenter.heroku.com/articles/config-vars heroku config:set REACT_APP_HELLO='I love sushi!' ``` +For local development, use [dotenv](https://www.npmjs.com/package/dotenv) to load variables from a `.env` file. *Requires at least create-react-app 0.7.* + #### Compile-time vs Runtime Two versions of variables are supported. In addition to compile-time variables applied during [build](https://github.com/facebookincubator/create-react-app#npm-run-build), this buildpack supports runtime configuration as well. @@ -146,6 +148,8 @@ git push heroku master #### Runtime configuration +*Requires at least create-react-app 0.7.* + Install the [runtime env npm package](https://www.npmjs.com/package/@mars/heroku-js-runtime-env): ```bash From b648d4c2b3ce11aba813ce445b17d07f6c19df03 Mon Sep 17 00:00:00 2001 From: Mars Hall Date: Sun, 16 Oct 2016 09:18:17 -0700 Subject: [PATCH 16/18] Remove Runtime env var encoding notes (no longer necessary) --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index ac7146ae..371552d4 100644 --- a/README.md +++ b/README.md @@ -175,12 +175,6 @@ class App extends Component { } ``` -πŸ‘“ These runtime values will be serialized as JSON, so their values must be compatible with JSON: - -* quote `"` will be auto-escaped -* backslash `\` is a control character, so the standard [JSON string rules](http://json.org) apply -* all other UTF-8 characters may be used freely. - #### Add-on config vars 🀐 *Be careful not to export secrets. These values may be accessed by anyone who can see the React app.* From 16c78aec26b7e30884f9b87ca7f2c2425e90a3a1 Mon Sep 17 00:00:00 2001 From: Mars Hall Date: Sun, 16 Oct 2016 13:47:07 -0700 Subject: [PATCH 17/18] =?UTF-8?q?=F0=9F=93=9A=20Runtime=20config=20var=20b?= =?UTF-8?q?ackslash=20warning.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 371552d4..c03805d8 100644 --- a/README.md +++ b/README.md @@ -175,6 +175,8 @@ class App extends Component { } ``` +⚠️ *Avoid setting backslash escape sequences, such as `\n`, into Runtime config vars. Use literal UTF-8 values only; they will be automatically escaped.* + #### Add-on config vars 🀐 *Be careful not to export secrets. These values may be accessed by anyone who can see the React app.* From 70ad09d9c06b7f2a8d045b4de025a2271f068802 Mon Sep 17 00:00:00 2001 From: Mars Hall Date: Sun, 16 Oct 2016 17:46:03 -0700 Subject: [PATCH 18/18] Switch to runtime env release v2.0.0 of create-react-app-inner-buildpack --- .buildpacks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildpacks b/.buildpacks index 5fb3ac8e..d89e335b 100644 --- a/.buildpacks +++ b/.buildpacks @@ -1,3 +1,3 @@ https://github.com/heroku/heroku-buildpack-nodejs.git -https://github.com/mars/create-react-app-inner-buildpack.git#modular-runtime-env-vars +https://github.com/mars/create-react-app-inner-buildpack.git#v2.0.0 https://github.com/heroku/heroku-buildpack-static.git