load client-side environment variables at runtime

This commit is contained in:
Cassie Tarakajian 2018-08-24 17:41:23 -04:00
parent 4dc0ee1d25
commit 6705e4c3f8
17 changed files with 58 additions and 52 deletions

View file

@ -4,6 +4,8 @@ import { connect } from 'react-redux';
import DevTools from './components/DevTools'; import DevTools from './components/DevTools';
import { setPreviousPath } from '../IDE/actions/ide'; import { setPreviousPath } from '../IDE/actions/ide';
const __process = (typeof global !== 'undefined' ? global : window).process;
class App extends React.Component { class App extends React.Component {
constructor(props, context) { constructor(props, context) {
super(props, context); super(props, context);
@ -23,7 +25,7 @@ class App extends React.Component {
render() { render() {
return ( return (
<div className="app"> <div className="app">
{this.state.isMounted && !window.devToolsExtension && process.env.NODE_ENV === 'development' && <DevTools />} {this.state.isMounted && !window.devToolsExtension && __process.env.NODE_ENV === 'development' && <DevTools />}
{this.props.children} {this.props.children}
</div> </div>
); );

View file

@ -2,7 +2,8 @@ import axios from 'axios';
import * as ActionTypes from '../../../constants'; import * as ActionTypes from '../../../constants';
const ROOT_URL = process.env.API_URL; const __process = (typeof global !== 'undefined' ? global : window).process;
const ROOT_URL = __process.env.API_URL;
function setAssets(assets) { function setAssets(assets) {
return { return {

View file

@ -5,7 +5,8 @@ import { reset } from 'redux-form';
import * as ActionTypes from '../../../constants'; import * as ActionTypes from '../../../constants';
import { setUnsavedChanges } from './ide'; import { setUnsavedChanges } from './ide';
const ROOT_URL = process.env.API_URL; const __process = (typeof global !== 'undefined' ? global : window).process;
const ROOT_URL = __process.env.API_URL;
function appendToFilename(filename, string) { function appendToFilename(filename, string) {
const dotIndex = filename.lastIndexOf('.'); const dotIndex = filename.lastIndexOf('.');

View file

@ -1,7 +1,8 @@
import axios from 'axios'; import axios from 'axios';
import * as ActionTypes from '../../../constants'; import * as ActionTypes from '../../../constants';
const ROOT_URL = process.env.API_URL; const __process = (typeof global !== 'undefined' ? global : window).process;
const ROOT_URL = __process.env.API_URL;
function updatePreferences(formParams, dispatch) { function updatePreferences(formParams, dispatch) {
axios.put(`${ROOT_URL}/preferences`, formParams, { withCredentials: true }) axios.put(`${ROOT_URL}/preferences`, formParams, { withCredentials: true })

View file

@ -12,7 +12,8 @@ import { setUnsavedChanges,
import { clearState, saveState } from '../../../persistState'; import { clearState, saveState } from '../../../persistState';
import { redirectToProtocol, protocols } from '../../../components/forceProtocol'; import { redirectToProtocol, protocols } from '../../../components/forceProtocol';
const ROOT_URL = process.env.API_URL; const __process = (typeof global !== 'undefined' ? global : window).process;
const ROOT_URL = __process.env.API_URL;
export function setProject(project) { export function setProject(project) {
const targetProtocol = project.serveSecure === true ? const targetProtocol = project.serveSecure === true ?

View file

@ -3,7 +3,8 @@ import * as ActionTypes from '../../../constants';
import { showErrorModal, setPreviousPath } from './ide'; import { showErrorModal, setPreviousPath } from './ide';
import { resetProject } from './project'; import { resetProject } from './project';
const ROOT_URL = process.env.API_URL; const __process = (typeof global !== 'undefined' ? global : window).process;
const ROOT_URL = __process.env.API_URL;
export function getProjects(username) { export function getProjects(username) {
return (dispatch) => { return (dispatch) => {

View file

@ -2,9 +2,10 @@ import axios from 'axios';
import { createFile } from './files'; import { createFile } from './files';
import { TEXT_FILE_REGEX } from '../../../../server/utils/fileUtils'; import { TEXT_FILE_REGEX } from '../../../../server/utils/fileUtils';
const s3BucketHttps = process.env.S3_BUCKET_URL_BASE || const __process = (typeof global !== 'undefined' ? global : window).process;
`https://s3-${process.env.AWS_REGION}.amazonaws.com/${process.env.S3_BUCKET}/`; const s3BucketHttps = __process.env.S3_BUCKET_URL_BASE ||
const ROOT_URL = process.env.API_URL; `https://s3-${__process.env.AWS_REGION}.amazonaws.com/${__process.env.S3_BUCKET}/`;
const ROOT_URL = __process.env.API_URL;
const MAX_LOCAL_FILE_SIZE = 80000; // bytes, aka 80 KB const MAX_LOCAL_FILE_SIZE = 80000; // bytes, aka 80 KB
function localIntercept(file, options = {}) { function localIntercept(file, options = {}) {

View file

@ -6,8 +6,9 @@ import { connect } from 'react-redux';
import * as UploaderActions from '../actions/uploader'; import * as UploaderActions from '../actions/uploader';
import { fileExtensionsAndMimeTypes } from '../../../../server/utils/fileUtils'; import { fileExtensionsAndMimeTypes } from '../../../../server/utils/fileUtils';
const s3Bucket = process.env.S3_BUCKET_URL_BASE || const __process = (typeof global !== 'undefined' ? global : window).process;
`https://s3-${process.env.AWS_REGION}.amazonaws.com/${process.env.S3_BUCKET}/`; const s3Bucket = __process.env.S3_BUCKET_URL_BASE ||
`https://s3-${__process.env.AWS_REGION}.amazonaws.com/${__process.env.S3_BUCKET}/`;
class FileUploader extends React.Component { class FileUploader extends React.Component {
componentDidMount() { componentDidMount() {

View file

@ -3,8 +3,8 @@ import axios from 'axios';
import * as ActionTypes from '../../constants'; import * as ActionTypes from '../../constants';
import { showErrorModal, justOpenedProject } from '../IDE/actions/ide'; import { showErrorModal, justOpenedProject } from '../IDE/actions/ide';
const __process = (typeof global !== 'undefined' ? global : window).process;
const ROOT_URL = process.env.API_URL; const ROOT_URL = __process.env.API_URL;
export function authError(error) { export function authError(error) {
return { return {

View file

@ -14,6 +14,8 @@ import AccountView from './modules/User/pages/AccountView';
import { getUser } from './modules/User/actions'; import { getUser } from './modules/User/actions';
import { stopSketch } from './modules/IDE/actions/ide'; import { stopSketch } from './modules/IDE/actions/ide';
const __process = (typeof global !== 'undefined' ? global : window).process;
const checkAuth = (store) => { const checkAuth = (store) => {
store.dispatch(getUser()); store.dispatch(getUser());
}; };
@ -30,7 +32,7 @@ const routes = (store) => {
targetProtocol: protocols.https, targetProtocol: protocols.https,
sourceProtocol, sourceProtocol,
// prints debugging but does not reload page // prints debugging but does not reload page
disable: process.env.FORCE_TO_HTTPS === false, disable: __process.env.FORCE_TO_HTTPS === false,
}); });
return ( return (

View file

@ -4,12 +4,14 @@ import DevTools from './modules/App/components/DevTools';
import rootReducer from './reducers'; import rootReducer from './reducers';
import { clearState, loadState } from './persistState'; import { clearState, loadState } from './persistState';
const __process = (typeof global !== 'undefined' ? global : window).process;
export default function configureStore(initialState) { export default function configureStore(initialState) {
const enhancers = [ const enhancers = [
applyMiddleware(thunk), applyMiddleware(thunk),
]; ];
if (process.env.CLIENT && process.env.NODE_ENV === 'development') { if (__process.env.CLIENT && __process.env.NODE_ENV === 'development') {
// Enable DevTools only when rendering on client and during development. // Enable DevTools only when rendering on client and during development.
enhancers.push(window.devToolsExtension ? window.devToolsExtension() : DevTools.instrument()); enhancers.push(window.devToolsExtension ? window.devToolsExtension() : DevTools.instrument());
} }

View file

@ -33,13 +33,6 @@ services:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
target: production target: production
args:
- API_URL
- NODE_ENV
- S3_BUCKET
- AWS_REGION
- S3_BUCKET_URL_BASE
- FORCE_TO_HTTPS
# image: index.docker.io/catarak/p5.js-web-editor:latest # image: index.docker.io/catarak/p5.js-web-editor:latest
# env_file: # env_file:
# - "$PWD/.env" # - "$PWD/.env"

View file

@ -3,7 +3,7 @@ kind: Ingress
metadata: metadata:
name: editor-ingress name: editor-ingress
annotations: annotations:
kubernetes.io/ingress.global-static-ip-name: "test-web-editor" kubernetes.io/ingress.global-static-ip-name: "web-editor-ip"
spec: spec:
backend: backend:
serviceName: web-editor-node serviceName: web-editor-node

View file

@ -59,7 +59,7 @@ if (process.env.NODE_ENV === 'development') {
} }
let mongoConnectionString; let mongoConnectionString;
if (process.env.NODE_ENV === 'production') { if (process.env.NODE_ENV === 'production' && process.env.MONGO_RW_USERNAME && process.env.MONGO_RW_PASSWORD) {
const { const {
MONGO_RW_USERNAME, MONGO_RW_USERNAME,
MONGO_RW_PASSWORD, MONGO_RW_PASSWORD,

View file

@ -15,6 +15,21 @@ export function renderIndex() {
<link href='https://fonts.googleapis.com/css?family=Inconsolata' rel='stylesheet' type='text/css'> <link href='https://fonts.googleapis.com/css?family=Inconsolata' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'> <link href='https://fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>
<link rel='shortcut icon' href='https://raw.githubusercontent.com/processing/p5.js-website-OLD/master/favicon.ico' type='image/x-icon'/ > <link rel='shortcut icon' href='https://raw.githubusercontent.com/processing/p5.js-website-OLD/master/favicon.ico' type='image/x-icon'/ >
<script>
if (!window.process) {
window.process = {};
}
if (!window.process.env) {
window.process.env = {};
}
window.process.env.API_URL = '${process.env.API_URL}';
window.process.env.NODE_ENV = '${process.env.NODE_ENV}';
window.process.env.S3_BUCKET = '${process.env.S3_BUCKET}';
window.process.env.S3_BUCKET_URL_BASE = '${process.env.S3_BUCKET_URL_BASE}';
window.process.env.AWS_REGION = '${process.env.AWS_REGION}';
window.process.env.FORCE_TO_HTTPS = ${process.env.FORCE_TO_HTTPS === 'false' ? false : undefined};
window.process.env.CLIENT = true;
</script>
</head> </head>
<body> <body>
<div id="root" class="root-app"> <div id="root" class="root-app">
@ -24,19 +39,19 @@ export function renderIndex() {
`//<![CDATA[ `//<![CDATA[
window.webpackManifest = ${JSON.stringify(chunkManifest)}; window.webpackManifest = ${JSON.stringify(chunkManifest)};
//]]>` : ''} //]]>` : ''}
</script> </script>
<script src='${process.env.NODE_ENV === 'production' ? `${assetsManifest['/vendor.js']}` : '/vendor.js'}'></script> <script src='${process.env.NODE_ENV === 'production' ? `${assetsManifest['/vendor.js']}` : '/vendor.js'}'></script>
<script src='${process.env.NODE_ENV === 'production' ? `${assetsManifest['/app.js']}` : '/app.js'}'></script> <script src='${process.env.NODE_ENV === 'production' ? `${assetsManifest['/app.js']}` : '/app.js'}'></script>
<script> <script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-53383000-1', 'auto'); ga('create', 'UA-53383000-1', 'auto');
ga('send', 'pageview'); ga('send', 'pageview');
</script> </script>
</body> </body>
</html> </html>
`; `;

View file

@ -39,15 +39,7 @@ module.exports = [{
}), }),
new webpack.DefinePlugin({ new webpack.DefinePlugin({
'process.env': { 'process.env': {
API_URL: process.env.API_URL ? `"${process.env.API_URL}"` : undefined, NODE_ENV: JSON.stringify('development')
CLIENT: JSON.stringify(true),
FORCE_TO_HTTPS: process.env.FORCE_TO_HTTPS === 'true' ?
JSON.stringify(true) :
JSON.stringify(false),
NODE_ENV: JSON.stringify('development'),
S3_BUCKET: process.env.S3_BUCKET ? `"${process.env.S3_BUCKET}"` : undefined,
S3_BUCKET_URL_BASE: process.env.S3_BUCKET_URL_BASE ? `"${process.env.S3_BUCKET_URL_BASE}"` : undefined,
AWS_REGION: process.env.AWS_REGION ? `"${process.env.AWS_REGION}"` : undefined
} }
}) })
], ],

View file

@ -88,14 +88,7 @@ module.exports = [{
plugins: [ plugins: [
new webpack.DefinePlugin({ new webpack.DefinePlugin({
'process.env': { 'process.env': {
API_URL: process.env.API_URL ? `"${process.env.API_URL}"` : undefined, NODE_ENV: JSON.stringify('production')
NODE_ENV: JSON.stringify('production'),
S3_BUCKET: process.env.S3_BUCKET ? `"${process.env.S3_BUCKET}"` : undefined,
S3_BUCKET_URL_BASE: process.env.S3_BUCKET_URL_BASE ? `"${process.env.S3_BUCKET_URL_BASE}"` : undefined,
AWS_REGION: process.env.AWS_REGION ? `"${process.env.AWS_REGION}"` : undefined,
FORCE_TO_HTTPS: process.env.FORCE_TO_HTTPS === 'false' ?
JSON.stringify(false) :
undefined
} }
}), }),
new webpack.optimize.CommonsChunkPlugin({ new webpack.optimize.CommonsChunkPlugin({