mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-25 22:37:18 +10:00
Harmonize client & server env handling
* Remove defaults from multiple places in code. Put them to .env-template instead * Do not use imported config.js in server. Access process.env directly instead * Instruct using .env for local development, not .env.development.local
This commit is contained in:
parent
5ae25e2e62
commit
6380d7569f
14 changed files with 128 additions and 49 deletions
33
.env-template
Normal file
33
.env-template
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
# Mandatory configuration
|
||||
#
|
||||
REACT_APP_SHARETRIBE_SDK_CLIENT_ID=
|
||||
REACT_APP_GOOGLE_MAPS_API_KEY=
|
||||
REACT_APP_STRIPE_PUBLISHABLE_KEY=
|
||||
|
||||
# Defaults
|
||||
#
|
||||
|
||||
REACT_APP_SHARETRIBE_SDK_BASE_URL=http://localhost:8088
|
||||
|
||||
REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY=USD
|
||||
REACT_APP_CANONICAL_ROOT_URL=http://localhost:3000
|
||||
PORT=4000
|
||||
|
||||
# This is overwritten by configuration in .env.development and
|
||||
# .env.test. In production deployments use env variable and set it to
|
||||
# 'production'
|
||||
REACT_APP_ENV=production
|
||||
|
||||
|
||||
# Options. Uncomment and set to test.
|
||||
#
|
||||
|
||||
# REACT_APP_SHARETRIBE_USING_SSL=true
|
||||
# SERVER_SHARETRIBE_TRUST_PROXY=true
|
||||
# REACT_APP_PUBLIC_SENTRY_DSN=change-me
|
||||
# SERVER_SENTRY_DSN=change-me
|
||||
# REACT_APP_CSP=report
|
||||
# BASIC_AUTH_USERNAME=sharetribe
|
||||
# BASIC_AUTH_PASSWORD=secret
|
||||
# REACT_APP_GOOGLE_ANALYTICS_ID=change-me
|
||||
|
|
@ -1,2 +1 @@
|
|||
NODE_ENV=development
|
||||
REACT_APP_ENV=development
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
NODE_ENV=test
|
||||
REACT_APP_ENV=test
|
||||
REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY=USD
|
||||
REACT_APP_CANONICAL_ROOT_URL=http://localhost:3000
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -13,4 +13,4 @@ build
|
|||
.DS_Store
|
||||
.env
|
||||
npm-debug.log
|
||||
/.env.development.local
|
||||
yarn-error.log
|
||||
|
|
|
|||
|
|
@ -24,13 +24,16 @@ Clone this repository and install dependencies:
|
|||
|
||||
## Development
|
||||
|
||||
**First, you need to configure Client Id, Google Maps API key and
|
||||
Stripe publishable API key via [environment
|
||||
variables](./docs/env.md).** The quickest way to do this is to copy
|
||||
.env-template -> .env, and edit the file to add the three mandatory
|
||||
configuration values.
|
||||
|
||||
To develop the application and to see changes live, start the frontend development server:
|
||||
|
||||
yarn run dev
|
||||
|
||||
**You need to configure Client Id, Google Maps API key and Stripe
|
||||
publishable API key via [environment variables](./docs/env.md).**
|
||||
|
||||
**Known issues:**
|
||||
|
||||
* Adding/changing `import`s may not be synced properly with ESLint. You may see an error
|
||||
|
|
|
|||
47
docs/env.md
47
docs/env.md
|
|
@ -3,27 +3,32 @@
|
|||
The following configuration variables can be set to control the Starter App behaviour. Most of them
|
||||
have defaults that work for development environment. For production deploys most should be set.
|
||||
|
||||
| Variable | Must be set? | Default | Description |
|
||||
| ----------------------------------------- | ------------ | ----------------------- | ------------------------------------------------------------------------------------------------------- |
|
||||
| REACT_APP_GOOGLE_MAPS_API_KEY | X | - | See: [Google Maps API key](./google-maps.md) |
|
||||
| REACT_APP_SHARETRIBE_SDK_CLIENT_ID | X | - | Client ID (API key). You will get this from the Sharetribe team. |
|
||||
| REACT_APP_STRIPE_PUBLISHABLE_KEY | X | - | Stripe publishable API key for generating tokens with Stripe API. |
|
||||
| REACT_APP_SHARETRIBE_SDK_BASE_URL | | `http://localhost:8088` | The base url to access the Marketplace API. |
|
||||
| REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY | | USD | The currency used in the Marketplace as ISO 4217 currency code. For example: USD, EUR, CAD, AUD, etc. |
|
||||
| REACT_APP_CANONICAL_ROOT_URL | | `http://localhost:3000` | Canonical root url of the marketplace is running. Needed for social media sharing and SEO optimization. |
|
||||
| NODE_ENV | | ? | Node env. Use 'dev' for development and 'production' for production. |
|
||||
| REACT_APP_ENV | | production | TODO Didn't understand NODE_ENV vs this? |
|
||||
| REACT_APP_SHARETRIBE_USING_SSL | | false | Redirect HTTP to HTTPS. |
|
||||
| SERVER_SHARETRIBE_TRUST_PROXY | | false | Set when running the app behind a reverse proxy. |
|
||||
| REACT_APP_PUBLIC_SENTRY_DSN | | - | See: [Error logging with Sentry](./sentry.md) |
|
||||
| SERVER_SENTRY_DSN | | - | See: [Error logging with Sentry](./sentry.md) |
|
||||
| REACT_APP_CSP | | - | See: [Content Security Policy (CSP)](./content-security-policy.md) |
|
||||
| BASIC_AUTH_USERNAME | | - | Set to enable HTTP Basic Auth |
|
||||
| BASIC_AUTH_PASSWORD | | - | Set to enable HTTP Basic Auth |
|
||||
| REACT_APP_GOOGLE_ANALYTICS_ID | | - | See: [Google Analytics](./analytics.md) |
|
||||
| Variable | Must be set? | Default | Description |
|
||||
| ----------------------------------------- | ------------ | --------------------- | ----------------------------------------------------------------------------------------------------------------- |
|
||||
| REACT_APP_GOOGLE_MAPS_API_KEY | X | - | See: [Google Maps API key](./google-maps.md) |
|
||||
| REACT_APP_SHARETRIBE_SDK_CLIENT_ID | X | - | Client ID (API key). You will get this from the Sharetribe team. |
|
||||
| REACT_APP_STRIPE_PUBLISHABLE_KEY | X | - | Stripe publishable API key for generating tokens with Stripe API. Use test key (prefix pk*test*) for development. |
|
||||
| REACT_APP_SHARETRIBE_SDK_BASE_URL | | http://localhost:8088 | The base url to access the Sharetribe Flex Marketplace API. |
|
||||
| REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY | | USD | The currency used in the Marketplace as ISO 4217 currency code. For example: USD, EUR, CAD, AUD, etc. |
|
||||
| REACT_APP_CANONICAL_ROOT_URL | | http://localhost:3000 | Canonical root url of the marketplace. Needed for social media sharing and SEO optimization. |
|
||||
| NODE_ENV | | ? | Node env. Use 'development' for development and 'production' for production. |
|
||||
| PORT | | 4000 | Port for server to accept connections. |
|
||||
| REACT_APP_ENV | | production | Env for client side. Use the same value as with NODE_ENV. |
|
||||
| REACT_APP_SHARETRIBE_USING_SSL | | false | Redirect HTTP to HTTPS? |
|
||||
| SERVER_SHARETRIBE_TRUST_PROXY | | false | Set when running the app behind a reverse proxy, e.g. in Heroku. |
|
||||
| REACT_APP_PUBLIC_SENTRY_DSN | | - | See: [Error logging with Sentry](./sentry.md) |
|
||||
| SERVER_SENTRY_DSN | | - | See: [Error logging with Sentry](./sentry.md) |
|
||||
| REACT_APP_CSP | | - | See: [Content Security Policy (CSP)](./content-security-policy.md) |
|
||||
| BASIC_AUTH_USERNAME | | - | Set to enable HTTP Basic Auth |
|
||||
| BASIC_AUTH_PASSWORD | | - | Set to enable HTTP Basic Auth |
|
||||
| REACT_APP_GOOGLE_ANALYTICS_ID | | - | See: [Google Analytics](./analytics.md) |
|
||||
|
||||
## Defining the env variables
|
||||
|
||||
When the Starter App is started locally with `yarn run dev` you can set environment variables by
|
||||
using the file .env.development.local. However, the server process doesn't currently pick up values
|
||||
from this file. In production it is recommended to set the environment variables on OS level.
|
||||
When the Starter App is started locally with `yarn run dev` or `yarn run dev-server`, you can set
|
||||
environment variables by using the file .env file. The repository contains a template file
|
||||
.env-template. Just copy that as .env and edit as necessary.
|
||||
|
||||
In production, it's recommended that you set the configuration via env variables and do not deploy
|
||||
an .env file. The client application will only be packaged with env variables that start with
|
||||
REACT_APP. This way server secrets don't end up in client bundles.
|
||||
|
|
|
|||
|
|
@ -20,8 +20,7 @@ section of the Places library documentation to enable using the Google Places AP
|
|||
## Setup the application to use the API key
|
||||
|
||||
The application uses the `REACT_APP_GOOGLE_MAPS_API_KEY` environment variable for the key value. For
|
||||
local development, you can add the variable in the Gitignored `.env.development.local` file in the
|
||||
project root:
|
||||
local development, you can add the variable in the Gitignored `.env` file in the project root:
|
||||
|
||||
```
|
||||
REACT_APP_GOOGLE_MAPS_API_KEY=my-key-here
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@
|
|||
"test-ci": "sharetribe-scripts test --env=jsdom --runInBand",
|
||||
"eject": "sharetribe-scripts eject",
|
||||
"start": "node server/index.js",
|
||||
"dev-server": "export REACT_APP_ENV=development REACT_APP_CANONICAL_ROOT_URL=http://localhost:4000&&yarn run build&&nodemon --watch server server/index.js",
|
||||
"dev-server": "export NODE_ENV=development REACT_APP_CANONICAL_ROOT_URL=http://localhost:4000&&yarn run build&&nodemon --watch server server/index.js",
|
||||
"heroku-prebuild": "./heroku-copy-ssh-key-from-env.sh",
|
||||
"heroku-postbuild": "yarn run build",
|
||||
"audit": "nsp check --preprocessor yarn"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
const helmet = require('helmet');
|
||||
const { config } = require('./importer');
|
||||
|
||||
const dev = process.env.REACT_APP_ENV === 'development';
|
||||
const googleAnalyticsEnabled = !!process.env.REACT_APP_GOOGLE_ANALYTICS_ID;
|
||||
|
|
@ -21,7 +20,7 @@ module.exports = (reportUri, enforceSsl, reportOnly) => {
|
|||
const self = "'self'";
|
||||
const inline = "'unsafe-inline'";
|
||||
const data = 'data:';
|
||||
const sharetribeApi = config.sdk.baseUrl;
|
||||
const sharetribeApi = process.env.REACT_APP_SHARETRIBE_SDK_BASE_URL;
|
||||
const sharetribeAssets = 'https://assets-sharetribecom.sharetribe.com/';
|
||||
const imgix = '*.imgix.net/';
|
||||
const loremPixel = 'https://lorempixel.com/';
|
||||
|
|
|
|||
41
server/env.js
Normal file
41
server/env.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
Implements .env file loading that mimicks the way create-react-app
|
||||
does it. We want this to get consistent configuration handling
|
||||
between client and node server.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
const NODE_ENV = process.env.NODE_ENV;
|
||||
|
||||
if (!NODE_ENV) {
|
||||
throw new Error('The NODE_ENV environment variable is required but was not specified.');
|
||||
}
|
||||
|
||||
// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
|
||||
var dotenvFiles = [
|
||||
`.env.${NODE_ENV}.local`,
|
||||
`.env.${NODE_ENV}`,
|
||||
// Don't include `.env.local` for `test` environment
|
||||
// since normally you expect tests to produce the same
|
||||
// results for everyone
|
||||
NODE_ENV !== 'test' && `env.local`,
|
||||
'.env',
|
||||
].filter(Boolean);
|
||||
|
||||
const configureEnv = () => {
|
||||
// Load environment variables from .env* files. Suppress warnings using silent
|
||||
// if this file is missing. dotenv will never modify any environment variables
|
||||
// that have already been set.
|
||||
// https://github.com/motdotla/dotenv
|
||||
dotenvFiles.forEach(dotenvFile => {
|
||||
if (fs.existsSync(dotenvFile)) {
|
||||
console.log('Loading env from file:' + dotenvFile);
|
||||
require('dotenv').config({ path: dotenvFile });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
configureEnv: configureEnv,
|
||||
};
|
||||
|
|
@ -17,5 +17,4 @@ module.exports = {
|
|||
matchPathname: mainJs.matchPathname,
|
||||
configureStore: mainJs.configureStore,
|
||||
routeConfiguration: mainJs.routeConfiguration,
|
||||
config: mainJs.config,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@
|
|||
// This enables nice stacktraces from the minified production bundle
|
||||
require('source-map-support').install();
|
||||
|
||||
// Configure process.env with .env.* files
|
||||
require('./env').configureEnv();
|
||||
|
||||
const express = require('express');
|
||||
const helmet = require('helmet');
|
||||
const compression = require('compression');
|
||||
|
|
@ -35,12 +38,11 @@ const { sitemapStructure } = require('./sitemap');
|
|||
const csp = require('./csp');
|
||||
|
||||
const buildPath = path.resolve(__dirname, '..', 'build');
|
||||
const env = process.env.REACT_APP_ENV || 'production';
|
||||
const env = process.env.REACT_APP_ENV;
|
||||
const dev = process.env.REACT_APP_ENV === 'development';
|
||||
const PORT = process.env.PORT || 4000;
|
||||
const CLIENT_ID =
|
||||
process.env.REACT_APP_SHARETRIBE_SDK_CLIENT_ID || '08ec69f6-d37e-414d-83eb-324e94afddf0';
|
||||
const BASE_URL = process.env.REACT_APP_SHARETRIBE_SDK_BASE_URL || 'http://localhost:8088';
|
||||
const PORT = process.env.PORT;
|
||||
const CLIENT_ID = process.env.REACT_APP_SHARETRIBE_SDK_CLIENT_ID;
|
||||
const BASE_URL = process.env.REACT_APP_SHARETRIBE_SDK_BASE_URL;
|
||||
const USING_SSL = process.env.REACT_APP_SHARETRIBE_USING_SSL === 'true';
|
||||
const TRUST_PROXY = process.env.SERVER_SHARETRIBE_TRUST_PROXY || null;
|
||||
const CSP = process.env.REACT_APP_CSP;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
const path = require('path');
|
||||
const moment = require('moment');
|
||||
const { config } = require('./importer');
|
||||
|
||||
const buildPath = path.resolve(__dirname, '..', 'build');
|
||||
const PORT = process.env.PORT || 4000;
|
||||
const PORT = process.env.PORT;
|
||||
const USING_SSL = process.env.REACT_APP_SHARETRIBE_USING_SSL === 'true';
|
||||
|
||||
/**
|
||||
|
|
@ -44,17 +43,17 @@ const port = rootURL => {
|
|||
};
|
||||
|
||||
/**
|
||||
* Return a structure for sitemap.xml and robots.txt to be
|
||||
* used by the express-sitemap library. Uses the canonical
|
||||
* URL value from config for domain and port information.
|
||||
* Return a structure for sitemap.xml and robots.txt to be used by the
|
||||
* express-sitemap library. Uses the canonical URL value from env
|
||||
* config for domain and port information.
|
||||
*/
|
||||
exports.sitemapStructure = () => {
|
||||
const now = moment().format('YYYY-MM-DD');
|
||||
|
||||
return {
|
||||
url: domain(config.canonicalRootURL),
|
||||
url: domain(process.env.REACT_APP_CANONICAL_ROOT_URL),
|
||||
http: USING_SSL ? 'https' : 'http',
|
||||
port: port(config.canonicalRootURL),
|
||||
port: port(process.env.REACT_APP_CANONICAL_ROOT_URL),
|
||||
sitemap: path.join(buildPath, 'static', 'sitemap.xml'),
|
||||
robots: path.join(buildPath, 'robots.txt'),
|
||||
sitemapSubmission: '/static/sitemap.xml',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import * as custom from './marketplace-custom-config.js';
|
||||
|
||||
const env = process.env.REACT_APP_ENV || 'production';
|
||||
const env = process.env.REACT_APP_ENV;
|
||||
const dev = process.env.REACT_APP_ENV === 'development';
|
||||
|
||||
// If you want to change the language, remember to also change the
|
||||
|
|
@ -33,9 +33,9 @@ const bookingUnitType = 'line-item/night';
|
|||
// react-scripts) require using the REACT_APP_ prefix to avoid
|
||||
// exposing server secrets to the client side.
|
||||
const sdkClientId = process.env.REACT_APP_SHARETRIBE_SDK_CLIENT_ID;
|
||||
const sdkBaseUrl = process.env.REACT_APP_SHARETRIBE_SDK_BASE_URL || 'http://localhost:8088';
|
||||
const sdkBaseUrl = process.env.REACT_APP_SHARETRIBE_SDK_BASE_URL;
|
||||
|
||||
const currency = process.env.REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY || 'USD';
|
||||
const currency = process.env.REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY;
|
||||
|
||||
// Sentry DSN (Data Source Name), a client key for authenticating calls to Sentry
|
||||
const sentryDsn = process.env.REACT_APP_PUBLIC_SENTRY_DSN;
|
||||
|
|
@ -219,7 +219,7 @@ const postalCode = '00100';
|
|||
const streetAddress = 'Bulevardi 14';
|
||||
|
||||
// Canonical root url is needed in social media sharing and SEO optimization purposes.
|
||||
const canonicalRootURL = process.env.REACT_APP_CANONICAL_ROOT_URL || 'http://localhost:3000';
|
||||
const canonicalRootURL = process.env.REACT_APP_CANONICAL_ROOT_URL;
|
||||
|
||||
// Site title is needed in meta tags (bots and social media sharing reads those)
|
||||
const siteTitle = 'Saunatime';
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue