How to deploy React application to Heroku - node.js

I have built a single-page weather app with React and Node.js but can't seem to get it to deploy to Heroku. So far, I have:
Created a new app on Heroku called weather-app-react-node
Logged into Heroku on the CLI
Run the command 'heroku git:remote -a weather-app-react-node' in my terminal
Added a Procfile with 'web: npm start' in it
Ran 'git add .', 'git commit -m "Pushed to heroku"', 'git push heroku master'
My terminal tells me it is deployed and waiting but when I click on the link, I get this error message:
SecurityError: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.
I've tried to google it but can't seem to find anything relevant to my situation. Anyone know how to fix it?
heroku-site: https://weather-app-react-node.herokuapp.com/github: https://github.com/caseycling/weather-app

To deploy the React app to Heroku, I performed the following steps...
1. In your terminal, enter npm -v and node -v to get your npm and node version. In my case, my npm version is 6.14.1 & my node version is 12.13.0.
2. In package.json, add "main": "server.js", and "engines": { "npm": "6.14.1", "node": "12.13.0" }, under the "private" property. In your scripts property, add "heroku-postbuild": "npm install" and set "start" to "node server.js".
3. In the root directory, create a Procfile with one line of text: web: node server.js.
4. In the root directory, create the server.js file with the below code..
const express = require("express");
// eslint-disable-next-line no-unused-vars
// const bodyParser = require('body-parser');
const path = require("path");
const app = express();
const port = process.env.PORT || 8080;
app.use(express.static(path.join(__dirname, "build")));
// This route serves the React app
app.get('/', (req, res) => res.sendFile(path.resolve(__dirname, "build", "index.html")));
app.listen(port, () => console.log(`Server listening on port ${port}`));
5. Enter npm run build in the terminal to produce the build directory. Next, remove (or comment out) /build from .gitignore file (in root directory).
6. Test if server.js works by entering node server.js (or nodemon server.js) in the terminal. If it works, server.js should serve the React app.
7. Commit everything from step 1-6 to GitHub and Heroku repository. To commit to Heroku repository, in your terminal, enter heroku git:remote -a weather-app-react-node and afterward, enter git push heroku master.

You can try logging in to heroku directly and deploy your github repository's desired branch from there directly.

I used create-react-app-buildpack
npm install -g create-react-app
create-react-app my-app
cd my-app
git init
heroku create -b https://github.com/mars/create-react-app-buildpack.git
or
heroku create -b mars/create-react-app
git add .
git commit -m "I am the newborn app"
git push heroku master
heroku open
Note: In my case, buildpack config from CLI did not work, I still had nodejs-build pack, so I manually changed the build pack to mars/create-react-app in the Heroku project dashboard

The best practice to push React apps to Heroku with a node js backend is to use the Heroku Post Build Script, The post build will take care of all the work under the hood
Follow the steps below
Add This below snippet to your package.json under the scripts
scripts{
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix reactFolderName && npm run build --prefix reactFolderName"
}
And add this snippet to your index.js file
app = express()
app.use(express.static('reactFolderName/build'));
app.get('*', (req, res) => res.sendFile(path.resolve(__dirname, 'reactFolderName', 'build', 'index.html')));

After I set up the all the things above mentioned I'm facing this issue.
When I'm using the URL like http://localhost:8080/ & http://localhost:8080/button
Cannot GET /button
In Console
Failed to load resource: the server responded with a status
of 404 (Not Found)
DevTools failed to load source map: Could not load content
for chrome-
extension://gighmmpiobklfepjocnamgkkbiglidom/browser-
polyfill.js.map: System error: net::ERR_FILE_NOT_FOUND

Related

Final Deployment of React Project

I am new to NodeJS and come from Java world, but in last 3 month I have done quite good development.
I use ExpressJS and ReactJSin my first project, Now during development we use 2 http server 1 for ExpressJS back-end application and another for ReactJS front-end application.
Now is this the way we have to deploy on production or we can combine it as 1 application and deploy on 1 http server listening on port 80.
regards
Deploy a production React app to Heroku
1. Create a React App
npm create-react-app heroku-deploy-test
cd heroku-deploy-test
2. Create an Express JS server to serve your production build
//server.js
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(__dirname));
app.use(express.static(path.join(__dirname, 'build')));
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
const port = process.env.PORT || 8080;
app.listen(port);
In your package.json file, change the start script to the following: start:
"node server.js"
3. Deploy to Heroku
If you don’t already have a Heroku account, create one here: https://signup.heroku.com/
In your command line, run the following: heroku login
You will need to type in your heroku credentials to the terminal. Once you have successfully entered your heroku credentials, run the following in your terminal to create a new deployed app:
heroku create heroku-deploy-test
(Replace heroku-deploy-test with your own app name.)
Then push your app build to heroku with the following git in your terminal:
git init
git add .
git commit -m "initial commit"
heroku git:remote -a heroku-deploy-test
git push heroku master
These commands install your dependencies, initialize git, and connect your repo to the remote repository hosted by Heroku.
Note: if you already initialized your git before running heroku create [app-name], then you don’t need to run heroku git:remote -a [app-name].
run heroku open and your development app will open in your default browser. If you want a production build, I think you already know what to do. - > Create a production build of your React app. Create a proper .gitignore file so only the relevant files will be deployed.
IMPORTANT: If you already had a .gitignore file, make sure that this line isn't in it /build :)
May I also suggest reading this blog! Have a good one!

How to set up dev and API server from create-react-app?

I've started a new app with create-react-app, and ejected from that. I made a small express server as follows:
const express = require('express');
const app = express();
if(process.env.NODE_ENV === 'production') {
app.use(express.static('build'));
}
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Server started at: http://localhost:${port}/`);
});
In package.json I've added a line, "proxy": http://localhost:3000", as well as switching the commands:
"scripts": {
"run": "npm-run-all -p watch-css start-js",
"start": "node server.js",
},
run used to be start.
However now of course when I run npm start and go to localhost:3000, I get Cannot GET /. I need this server to receive and return local API calls I'll be making from my app, but I also want it to run a hot-reloading dev server just like the old npm start (now npm run) command did. How do I do this?
Some time ago I made a fork of the create-react-app repository adding webpack watch option because of this same reason. It might help you.
Just to add more info, I really invested time looking on how to get webpackdevserver to build the "bundle.js", and found that it is not possible because it loads the bundle into memory but doesn't persist it, so the file is never created. The only way available is the webpack watch option but, I don't understand why the create-react-app team can't add it to the repo, it's a really requested feature, and there are more forks than mine that solves this issue. So, you have three options:
Use the proxy server in package.json (if it works)
Make your own fork and add the watch option, or use an existing one
Don't use create-react-app

How can i deploy a Selenium NodeJS web app to Heroku?

I have created a Selenium NodeJS web app in Local. It uses chromedriver and my driver must use some chrome extensions. Everything is ok in local.
I want to use it in Heroku but I could not do it. I tried it with build packs but but I could not do it again.
How can i deploy it to Heroku ?
package.json (dependencies):
..
"dependencies": {
"body-parser": "*",
"express": "*",
"firebase": "^4.1.5",
"firebase-admin": "^4.2.1",
"selenium-webdriver": "*",
"chromedriver":"*",
"telebot":"*"
},
..
Note: I am using React, Express, and Selenium with chrome
Step 1: Create a new Heroku app.
Step 2: From your terminal, login to heroku using heroku login
step 3: Once you're logged in, cd to your project directory and set it's remote to your heroku app. heroku git:remote -a YOUR-HEROKU-APP-NAME
step 4: Run all the following commands in your terminal
heroku buildpacks:add https://github.com/heroku/heroku-buildpack-chromedriver
heroku buildpacks:add https://github.com/heroku/heroku-buildpack-google-chrome
heroku config:set CHROME_DRIVER_PATH=/app/.chromedriver/bin/chromedriver
heroku config:set CHROME_BINARY_PATH=/app/.apt/opt/google/chrome/chrome
step 5: Login to heroku from your browser and navigate to your app. Go to settings and under buildpacks, add heroku/nodejs
step 6: This is how my index.js looks like. Note: my express entry point is inside root-dir/server/index.js and my react files are inside root-dir/client/
const express = require('express');
const app = express();
const path = require('path');
// Serve static files from the React app.
app.use(express.static(path.join(__dirname, '..', 'client/build')));
app.get('/api', async (req, res) => {
const webdriver = require('selenium-webdriver');
require('chromedriver');
const chrome = require('selenium-webdriver/chrome');
let options = new chrome.Options();
options.setChromeBinaryPath(process.env.CHROME_BINARY_PATH);
let serviceBuilder = new chrome.ServiceBuilder(process.env.CHROME_DRIVER_PATH);
//Don't forget to add these for heroku
options.addArguments("--headless");
options.addArguments("--disable-gpu");
options.addArguments("--no-sandbox");
let driver = new webdriver.Builder()
.forBrowser('chrome')
.setChromeOptions(options)
.setChromeService(serviceBuilder)
.build();
await driver.get('http://www.google.com');
res.send(await driver.getTitle());
});
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, '..', 'client/build/index.html'));
});
const port = process.env.PORT || 5000;
app.listen(port, () => {
console.log(`listening to port ${port} now...`);
});
step 7 (if you are using React): Now inside your package.json in root-dir/, add this
"scripts": {
...
"heroku-postbuild": "cd client && npm install && npm run build"
}
step 8 (if you are using react): inside your package.json in root-dir/client/ (i.e: package.json for react app), add the following line:
"proxy": "http://localhost:5000/",
step 8: (if you're using react): inside root-dir/client/src/, create a new file called setupProxy.js and paste the following code:
const proxy = require("http-proxy-middleware");
module.exports = function(app) {
app.use(proxy('/api', { target: `http://localhost:${process.env.PORT || 5000}/`}));
};
step 9: Now, you are ready for deployment. Make sure you have the following packages installed: express, selenium-webdriver, and chromedriver
step 10: now push it to heroku
git add .
git commit -m "my app"
git push heroku master
you can do the following steps to deploy your application on heroku
1)make an new repository on git
create an account on github and create an new repository
then on command line check the status of your project file using
git status
if they are red mark then add all the file using
git add .
then commit
git commit -m "first commit"
2)push all the data on that repository
git remote add origin https://github.com/git_account/repository_name.git
git push -u origin master
3) then push from git to heroku
git push heroku

Deploy the backend and frontend on the same Heroku app/dyno

At the root of my project, I have a frontend and backend folder. Both folders contain a package.json that list their dependencies. How do I tell Heroku to run npm install on both folders when deploying the application? It seems like Heroku expects to have a single package.json file by default. Do I have to do something with a Procfile? The Heroku documentation doesn't seem to tell much about my specific question.
Thanks for the help!
I just successfully completed this goal using static files created during a heroku postbuild step, as described in this blogpost. I have a React frontend (could be anything though) and Express API backend. Each process has its own port in dev, but deploying on Heroku uses just one total.
Put the working frontend in a subdirectory of root (such as /frontend).
Put the working backend in a subdirectory of root (such as /api -- the blogpost assumes the backend remains in the root directory -- either way is fine).
Proxy API requests from the frontend to the backend by adding this line to /frontend/package.json (replacing 5000 with your backend port):
"proxy": "http://localhost:5000",
Add the following to api/app.js (or api/index.js) in the backend (be sure the last part is AFTER you define the appropriate backend [or api] paths):
const path = require('path')
// Serve static files from the React frontend app
app.use(express.static(path.join(__dirname, '../frontend/build')))
// AFTER defining routes: Anything that doesn't match what's above, send back index.html; (the beginning slash ('/') in the string is important!)
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname + '/../frontend/build/index.html'))
})
Edit the root directory's /package.json file with something like the following (note that using the concurrently package allows an easy way to run the whole app locally with npm run dev, but only heroku-postbuild is required here):
"scripts": {
"frontend": "cd frontend && npm start",
"api": "cd api && nodemon app.js",
"dev": "concurrently --kill-others-on-fail \"npm run api\" \"npm run frontend\"",
"heroku-postbuild": "cd frontend && npm install && npm run build"
},
Make sure you install all backend package dependencies in the root directory, or you will get errors.
Make sure your /Procfile has something like web: node api/app.js
Seems that you can put a package.json file on the root of the project and use scripts to invoke npm i in both folder.
https://devcenter.heroku.com/articles/nodejs-support#customizing-the-build-process
Something like cd front && npm i && cd ../back && npm i
But i should say that if they are running on different ports, it may not work as it seems that only one web process per procfile is available.
this last point is to confirm.
You can define several entry points for your project in the Procfile :
web: cd front && npm i && npm start
server: cd backend && npm i && npm start
However, you have to upgrade to Hobby at least. It's 7$/dyno/month.

How do I make Openshift to use Express 4, instead of its installed Express 3?

I developed my Nodejs Express app locally using Express 4 and it works as expected on my computer. I then git the whole app up to Openshift. When I try to run it Openshift returns"503 Service Unavailable". If I ssh into my base Node cartridge and do "express -V" it returns version 3.2.5. I get the same version 3.2.5 if I go into my app folder at app-root/repo and run "express -V".
So clearly my Express 4 which was included in the git upload in my app's node_modules is not being used. What is the solution to use Express 4 as required by my app?
Ideas are- remove Openshift's version of Express 3, force Openshift to use my Express 4 in my app area, upgrade Openshift's Express 3 to Express 4. I cannot figure out how to do any of those and I have researched this.
Here's how to troubleshoot:
ssh into your cartridge
cd into the app-root/repo directory
run grep version ./node_modules/express/package.json
you should see a version based on your package.json dependency
verify your package.json has a scripts section containing a start command that just runs your app with something like node ./server.js (server.js being whatever file you coded your main app start script in). You don't need the express command line program to launch an express server. It's for setting up new project boilerplate and other ancillary tasks.
To see the version of express running within your app, you can add this code to your server.js (or equivalent) file: console.log(require("express/package").version);
Look at this project to know how to integrate openshift with express4
Its a simple example .
https://github.com/master-atul/openshift-express4
try this
rhc ssh
cd app-root/repo
npm start
also edit the ./bin/www
var port = normalizePort(process.env.OPENSHIFT_NODEJS_PORT || '8080');
var ip = process.env.OPENSHIFT_NODEJS_IP;
if (typeof ip === "undefined") {
// Log errors on OpenShift but continue w/ 127.0.0.1 - this
// allows us to run/test the app locally.
console.warn('No OPENSHIFT_NODEJS_IP var, using 127.0.0.1');
ip = "127.0.0.1";
};
//app.set('ip', port);
app.set('port', port);
var server = http.createServer(app);
server.listen(port, ip);
server.on('error', onError);
server.on('listening', onListening);
you can follow step:
copy all content bin/www and replace all content in file server.js:
Change some content at server.js:
from
`var port = normalizePort(process.env.PORT || '3000');`
to
var port = normalizePort(process.env.OPENSHIFT_NODEJS_PORT || '3000');
Add line:
var ip = process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1';
from
server.listen(port);
to
server.listen(port, ip);
Add more to package.json
from
"scripts": {
"start": "node bin/www"
},
to
"scripts": {
"start": "node server.js"
},
Add line:
"main": "server.js",
Use npm install --save module-name for npm install
create file .gitignore with content:
node_modules
on local run node server.js to start server with address localhost:3000
upload to openshift:
git add .
git commit -m "First update new server version"
git push
Browser: domain-appname.rhcloud.com

Resources