My react app is running on http://localhost:3000 and I wanted to setup the env variable for the different environment development, production, staging and local.
my react app url for different environment are(I am mocking my urls)
local = http://localhost:3000
development = http://react.developmet.com
production = http://react.production.com
stage = http://react.stage.com
looking for a solution how i can setup the env var for different environment.
Adding my approach to the same thing just wanted to know is this approach is good or not.
and how I can achieve same for staging environment
I have created an environment.js file.
let BASE_URL = http://localhost:3000
//check for environment
if (process.env.REACT_APP_ENV = "development") {
BASE_URL = "http://react.developmet.com"
}
if (process.env.REACT_APP_ENV = "production") {
BASE_URL = "http://react.production.com"
}
export {BASE_URL}
and also updated my run scripts
"scripts": {
"dev":"REACT_APP_ENV=development npm start",
"prod":"REACT_APP_ENV=productionnpm start",
"build:dev":"REACT_APP_ENV=development npm run-script build",
"build:prod":"REACT_APP_ENV=production npm run-script build",
}
You can use env-cmd to manage your build for multiple env files:
Installation:
yarn add env-cmd -D
Create env files
Create a folder envs at root project level
Create .env files (as many as you need)
e.g. envs/.env.dev, envs/.env.prod, envs/.env.staging etc
A Sample .env (e.g. envs/.env.prod) file
REACT_APP_API_HOST=http://my-prod-api.example.com
REACT_APP_ANY_OTHER_VAR=some_value
Configure scripts in package.json file:
"scripts": {
"start": "react-scripts start",
"eject": "react-scripts eject",
"dev": "env-cmd -f envs/.env.dev react-scripts build",
"prod": "env-cmd -f envs/.env.prod react-scripts build",
"staging": "env-cmd -f envs/.env.staging react-scripts build",
},
Make the build:
$ yarn dev // to make build for dev env
$ yarn prod // to make build for prod env
$ yarn staging // to make build for staging env
PS: You can use npm commands as well. I used yarn only for example purpose.
Related
I’ve deployed a Nextjs app using docker to AWS infrastructure. The index page (/) loads fine, however, the content of index is loaded for every other route including the api routes as well as the js and css resources.
I’ve attempted running the app with just next start as well as building a standalone version and running node server.js. Both ways result in the same thing.
Dockefile looks like this
FROM node
ARG VERSION
ENV VERSION=${VERSION}
ARG COMMIT_REF
ENV COMMIT_REF=${COMMIT_REF}
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED 1
WORKDIR /usr/src/app
RUN apt-get update
RUN apt-get upgrade -y
RUN rm -rf /var/cache/apt/lists
COPY src ./src
COPY node_modules ./node_modules
COPY package.json ./
COPY next.config.js ./
COPY next-env.d.ts ./
COPY babel.config.js ./
COPY tsconfig.eslint.json ./
COPY tsconfig.json ./
COPY types.d.ts ./
COPY public ./public
RUN npx next build
ADD ./docker/start.sh /start.sh
RUN chmod +x /*.sh
ENTRYPOINT ["/start.sh"]
Has anyone seen this behaviour before?
Not sure if this helps but,
we have a web app in react and we did have this problem also.
The problem you are facing probably isn’t in your Dockerfile but in your build/config file.
We've fixed the issue by adding GENERATE_SOURCEMAP=false to the build tag script in package.json eg.
"scripts": {
"start": "react-scripts start",
"build": "GENERATE_SOURCEMAP=false react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
And then we ran a npm run build command.
Hope this helps!
I am building an ReactJs application that has many profiles.
The application will run in a development environment, qa environment and a production environment.
Given this, I would like to set on the host machine some environment variables and be able to get this on the .env file.
My need is to do something like:
.env file
REACT_APP_BASE_SERVICEX_URL=${ENV_ON_HOST_BASE_SERVICEX_URL}
REACT_APP_BASE_SERVICEY_URL=${ENV_ON_HOST_BASE_SERVICEY_URL}
Is this possible?
PS: The application will be running in Kubernetes.
1- Install env-cmd package from npm
2- Make a file called .env.envName in your project root, sush as .env.staging, .env.production, ... to differentiate between variables in each environment.
3- Inside the env file add your variables in key/value representation with prefix of REACT_APP
4- Inside your package.json. change the scripts builds.
"scripts": {
"start": "env-cmd -f .env.staging react-scripts start",
"build:staging": "env-cmd -f .env.staging react-scripts build",
"build:production": "env-cmd -f .env.production react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
5- -f flag is for custom env file paths as the default is in the project root otherwise you should specify the actual path
"start": "env-cmd -f ../../.env.staging react-scripts start",
Are you just asking how to handle environment variables?
You can put any variables that you need in the .env, .env.local, .env.development or .env.production file and then copy them over to the .env file when deploying.
It is custom to fully capitalize variables within the .env file. To use them within the code you place process.env prior to it.
In .env file :
DB_URL = http://fwohfjiowjfwefjpw
In react :
const DBURL = process.env.DB_URL
.env file
REACT_APP_BASE_SERVICEX_URL=HOST_BASE_SERVICEX_URL
And where you want to use the env variable, use this in the following way -
const URL = process.env.REACT_APP_BASE_SERVICEX_URL
I have created a react project using create-react-app. Now I need to update the webpack config, but I don't find the file anywhere.
Do I need to create this file myself or what is the process?
I am new to react and not really sure how to proceed from here.
No need to run npm run eject
Step 1
npm install react-app-rewired --save-dev
Step 2
Add config-overrides.js to the project root directory.(NOT ./src)
// config-overrides.js
module.exports = function override(config, env) {
// New config, e.g. config.plugins.push...
return config
}
Step 3
'Flip' the existing calls to react-scripts in npm scripts for start, build and test
/* package.json */
"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}
Step 4
Restart your app. Done
Option 1 - Eject your CRA
If you've just created your app using CRA, and haven't made big changes to it, you could use npm run eject - more about it here
Keep in mind that there is no going back (except by commits, of course) after doing this. This will basically provide you with webpack file and other files which are currently 'hidden' in CRA
Some critiques and second thoughts about this method here
Option 2 - React App Rewired
This might be the right choice for you. This allows you to extend your current webpack without ejecting, or messing up / making too many changes at your project as npm run eject will. Take a look at the package here
A great tutorial by Egghead.io using react-app-rewired here
I solved this problem by running a script between yarn install and yarn build. After yarn install the webpack.config.json file is generated, then immediately run a script on Node that modifies it, and then run the build.
My code:
custom.webpack.config.js
const fs = require('fs')
// WebPack.config File
const fileConfig = 'node_modules/react-scripts/config/webpack.config.js'
new Promise((resolve) => {
fs.readFile(fileConfig, 'utf8', function (err, data) {
if (err) {
return console.log(err)
}
resolve(data)
})
}).then((file) => {
let CodeAsString = "Code as String to save"
let regexCode = /YourCodeRegex}/g
let result = file.replace(regexCode, CodeAsString)
fs.writeFile(fileConfig, result, function (err) {
if (err) return console.log(err)
console.log('The webpack.config file was modifed!')
})
})
So, now do you need to edit the package.json to include this code in the process:
"scripts": {
"prestart": "node custom.webpack.config.js",
"prebuild": "node custom.webpack.config.js",
"start": "react-scripts start",
"build": "react-scripts build"
}
Done! :)
https://www.npmjs.com/package/react-app-rewired
Complete answer is :
How to rewire your create-react-app project
Create your app using create-react-app and then rewire it.
Install react-app-rewired
For create-react-app 2.x with Webpack 4:
npm install react-app-rewired --save-dev
For create-react-app 1.x or react-scripts-ts with Webpack 3:
npm install react-app-rewired#1.6.2 --save-dev
Create a config-overrides.js file in the root directory
/* config-overrides.js */
module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}
like this:
+-- your-project
| +-- config-overrides.js
| +-- node_modules
| +-- package.json
| +-- public
| +-- README.md
| +-- src
for example :
module.exports = function override(config, env) {
// New config, e.g. config.plugins.push...
config.module.rules = [...config.module.rules,
{
test: /\.m?js/,
resolve: {
fullySpecified: false
}
}
]
return config
}
'Flip' the existing calls to react-scripts in npm scripts for start, build and test
from:
/* package.json */
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
}
To:
/* package.json */
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
}
Note: Do NOT flip the call for the eject script. That gets run only once for a project, after which you are given full control over the webpack configuration making react-app-rewired no longer required. There are no configuration options to rewire for the eject script.
Start the Dev Server
npm start
Build your app
npm run build
Webpack configuration is being handled by react-scripts. I assume that you don't want to eject and just want to look at the config, you will find them in /node_modules/react-scripts/config
webpack.config.dev.js. //used by `npm start`
webpack.config.prod.js //used by `npm run build`
You can modify your webpack config or any other node_module using patch-package https://www.npmjs.com/package/patch-package
Install the version of react-scripts you want with npm i react-scripts#5.0.0
Then go into node_modules/react-scripts/webpack/webpack.config.js. Make the changes you need and then npx patch-package react-scripts
patch-package will generate a file in your project root like patches/react-scripts+5.0.0.patch
Add post-install script to package.json with
"scripts": {
"postinstall": "patch-package",
...
}
Now whenever you run npm i you will automatically get this patch included with the installed library.
The best way is:
Install react-app-rewired and customize-cra
Create a config-overrides.js file in your root folder. Here is an example Webpack override file gist: https://gist.github.com/Nagibaba/209c1bddcc39ff0686a820806cfa8ee3
Also, consider that you need to change react-scripts inside your package.json to react-app-rewired like:
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
You are ready to go
I am working on a react application created by create-react-app. I have two environments on AWS Elastic BeanStalk, staging and production. I am deploying my application through Docker. I am using CircleCI for automated deployments.
My problem is I want to change the endpoint url while building the react application.
I am using cross-env for setting a variable REACT_APP_API_HOST but i have to run a command build:staging for building it.
I am not sure how to do it with this docker.
Docker file
FROM node:12
WORKDIR /app
COPY . /app
RUN npm install
RUN npm run build
RUN npm install -g serve
EXPOSE 3000
ENTRYPOINT ["serve", "-l", "3000", "-s", "build", "-d"]
And the scripts part of package.json file
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"build:staging": "cross-env REACT_APP_API_HOST=staging react-scripts build",
"build:prod": "cross-env REACT_APP_API_HOST=production react-scripts build"
},
So after a long R&D, the answer I find with my friend is do run a intermediate script before deploying it to Elastic Beanstalk.
buildDocker.sh
#!/bin/bash
branch_name=$(git symbolic-ref --short -q HEAD)
if [ "$branch_name" == "develop" ]; then
result_sed=$(sed 's/RUN npm run build/RUN npm run build:staging/g' Dockerfile)
echo "$result_sed" > Dockerfile
elif [ "$branch_name" == "master" ]; then
result_sed=$(sed 's/RUN npm run build/RUN npm run build:prod/g' Dockerfile)
echo "$result_sed" > Dockerfile
fi
I am trying to target multiple environments from local while executing React app.
1. Development
2. Staging
3. Production
I am also trying to test for offline mode in any of the environments. So, the scripts what I have configured is as follows:
"staging-server": "nodemon server.js --environment=staging",
"staging": "concurrently -k \"npm:staging-server\" \"NODE_ENV='staging' PORT=3003 react-scripts start\"",
"prod": "npm run build && forever server.js --environment=production"
I am able to fetch environment arg using args inside my Express, but my local ui app is still showing development only when I console for process.env.NODE_ENV. I am also trying to set NODE_ENV with same line for staging, but still no luck. PORT setting is working but, the app is running in 3000 and 3003 both ports.
How to get rid of this? I would like to understand the staging configuration as well.
As per the docs, we cannot override NODE_ENV, but there is a room to create our own custom variables starting with REACT_APP_. So i configured to look as below:
Reference: https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables
"staging": "concurrently -k \"npm:staging-server\" \"cross-env REACT_APP_ENVIRONMENT='staging' PORT=3003 react-scripts start\"",
And inside my UI application, I can fetch its value by consoling it like this:
console.log('REACT_APP_ENVIRONMENT => ', process.env.REACT_APP_ENVIRONMENT);
I build the build with REACT_APP_STAGE and use it in my application as process.env.REACT_APP_STAGE.
"scripts": {
"analyze": "source-map-explorer 'build/static/js/*.js'",
"build-css": "node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/",
"watch-css": "npm run build-css && node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/ --watch --recursive",
"start-js": "react-scripts start",
"start": "REACT_APP_STAGE=local npm-run-all -p watch-css start-js",
"build": "npm run build-css && react-scripts build",
"build-dev": "REACT_APP_STAGE=dev react-scripts build",
"build-prod": "REACT_APP_STAGE=prod react-scripts build",
"build-qa": "REACT_APP_STAGE=qa react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
Use cross-env in front of NODE_ENV.
npm i -g cross-env
"staging": "concurrently -k \"npm:staging-server\" \"cross-env NODE_ENV='staging' PORT=3003 react-scripts start\"",
Easiest approach is to add it directly in your command:
"scripts": {
"start": "./node_modules/.bin/nodemon server.js",
"start:prod": "NODE_ENV=prod node server.js",
},