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!
Related
I received this message when i deploy to heroku:
remote: =====! create-react-app-buildpack has reached end-of-life 🌅
remote: This build may succeed, but the buildpack is no longer maintained.
remote: On the Heroku-22 stack and beyond, this may fail to build at all.
remote:
remote: Please consider migrating to https://nextjs.org or https://remix.run to develop React apps which are deployable using Heroku's Node.js buildpack https://github.com/heroku/heroku-buildpack-nodejs, or you may develop your own create-react-app deployment with Node.js and Nginx buildpacks.
I'm using this buildpack:
https://github.com/mars/create-react-app-buildpack
But heroku will no longer support it. I don't know how to migrate my reactapp to nextjs or remix, anyone know an alternative buildpack that supports the newer version of heroku?
Old Answer
The buildpack you're using is deprecated and doesn't work on Heroku-22. The simple solution, which is what I've done, is to postpone upgrading the Heroku stack until a new buildpack for Create-React-App is released. Heroku-18 is deprecated though, so you should upgrade to Heroku-20.
heroku stack:set heroku-20
Updated answer (as of 2023-01-05)
If you have a static website without environment variables, you can use an express server to run the static pre-build assets. Instructions based on this Medium article.
Remove the current buildpack from Heroku via the settings tab of your app in Heroku.
Install express with npm install express (or yarn add express)
Create a file scripts/heroku-start.js with the following content:
const express = require('express');
const path = require('path');
const app = express();
const port = process.env.PORT || 3000;
app.use(express.json());
// Your static pre-build assets folder
app.use(express.static(path.join(__dirname, '..', 'build')));
// Root Redirects to the pre-build assets
app.get('/', function(req,res){
res.sendFile(path.join(__dirname, '..', 'build'));
});
// Any Page Redirects to the pre-build assets folder index.html that // will load the react app
app.get('*', function(req,res){
res.sendFile(path.join(__dirname, '..', 'build/index.html'));
});
app.listen(port, ()=>{
console.log("Server is running on port: ", port)
})
Create a file Procfile with the following content:
web: node scripts/heroku-start.js
Set Heroku stack to Heroku-22 and deploy.
I seem to have found a easy work around that is currently working on my site.
I was getting the same error:
remote: =====> Detected Framework: Static HTML
remote: Stack heroku-22 is not supported!
remote: ! Push rejected, failed to compile React.js (create-react-app) multi app.
Although i already had the same page running on Heroku with different text/images (which is somehow running my react page without any buildpack currently).
To fix the issue this is what i tried and it allowed me to git push my app.
When you are pushing your react app from npm make sure to remove the react buildpack from the Heroku settings page for that app, repush via NPM and it should load without any issues and your app is now uploaded to Heroku. Now if you go and reapply your buildpack (https://buildpack-registry.s3.amazonaws.com/buildpacks/mars/create-react-app.tgz) and refresh your page it should be working fine.
FYI the new buildpack by the same commiter is now update and working..
https://github.com/heroku/heroku-buildpack-nodejs - Please review and plug this into the heroku :0
thank you internet NERDS - Love you all
Zero
I couldn't solve a certain Heroku issue (image storage/retrieval) so I'm trying my hand at Namecheap.
I purchased a domain and web host server from Namecheap, so I can deploy my completed MERN stack app I made for a client.
App file structure:
AppName
|
--client <<~~create-react-app
|
--middleware
|
--models
|
--node_modules
|
--routes
|
--uploads
|
--.env
|
--.gitignore
|
--package-lock.json
|
--package.json
|
--README.md
|
--server.js
Set my domain's Nameserver to Namecheap Web hosting DNS (namecheap guide instructions)
Ran npm run build in /client (did not do serve -s build though) to generate /client/build
server.js
// For Deployment
if(process.env.NODE_ENV === 'production') {
app.use(express.static(path.join(__dirname, 'client', 'build')));
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'client', 'build', 'index.html'));
});
};
Connected my git repo to the domain via Git Version Control cPanel option
Uploaded all my app files to cPanel File Manager (done automatically by Git Version Control)
Used cPanel's Setup NodeJS App feature
Setting up the NodeJS App requires a number of form fields:
NodeJS version: 12.19.1 <<~~slightly higher than mine, their support team advised me to do that
Application mode: Production
Application root: repositories/AppName <<~~path from the cPanel File Manager
Application URL: my-domain.com
Application Startup File: repositories/ChrisPortfolio/client/build/index.html <<~~this has been a guessing game, more notes below
As for Application Startup File, I tried server.js and experimented with a few things here.
Everything I tried led to, visiting the app in the browser and hitting a "Not Found" page.
With repositories/ChrisPortfolio/client/build/index.html however, the app says "It works!" and displays the Node version I selected, but.. it doesn't show the actual app.
There is an option to run npm install from inside the cPanel NodeJS dashboard, and I made sure to do that.
I think perhaps I need to have it run npm install inside the /client directory as well, but the dashboard does not let you choose from where you wish to run the command.
Anyways, this is where I'm at. Hopefully this is familiar to someone.
Solved deployment by:
cPanel's Git Version Control option to clone my repo, creating /home/username/repositories/appname directory in my File Manager
After running npm run build in my /client, directly uploading the contents of /build to /home/username/public_html (it needs index.html at the root of this folder)
cPanel's Setup NodeJS App feature, referencing the directory mentioned above as Application Root, and server.js as Application Startup File
App is now deployed.
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
I'm trying to set up a Node.js project that uses Express to provide a few backend APIs and serve a SPA built with Vue.js.
When I use the Vue cli to initialize a project, I get e.g. src/main.ts main file and commands npm run serve to run a dev server and watch for changes and npm run build to build a production release.
When I use the Express application generator to create a project, I get ./app.js main file and npm start to start the server and watch for changes.
How can I combine these into a single project, both served by the same Express server? Preferably so that a single command would watch + update changes to both server and client? I want to use Vue single file components and TypeScript, which (probably?) require a build step.
(I don't need dynamic server-side rendering of Vue templates, just the static SPA app provided. I prefer TypeScript, but JavaScript answers are fine as well.)
These will be different for your dev and prod environments...
For development look into concurrently - it basically allows you to create a single script in your package.json to start both the client and server concurrently and will watch for changes etc...
For production, you would need something like this in your app.js:
if (process.env.NODE_ENV === 'production') {
app.use(express.static('client/build'));
const path = require('path');
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
});
}
(The code above assumes that your directory structure has a client folder with a build folder after having run npm run build I'm more familiar with React than Vue... but the logic should be the same...)
I’m trying to deploy a very basic angular app to elastic beanstalk. The project was created using the angular cli. I have not made any changes to the files in this project.
Here are the steps I took to deploy the app
Executed ’ng build’ inside the root folder of my project
Moved the #angular/cli dependency from devDependencies to dependencies in package.json
Zipped the contents of the dist folder along with package.json
Deployed zip folder to AWS EB configured with the node.js platform, node version 8.11.3, the same as my local environment.
I always end up with a ‘npm install failed’ error when I check eb-activity.log.
Am I missing something trivial here? Would really appreciate any help with deploying angular apps to EB.
While this does not specifically answer your question, I don't think Elastic Beanstalk is the right tool for the job. I strongly suggest hosting on a Static Website on S3, and if you want https and a custom domain name, put a CloudFront distribution in front of it.
Create an S3 bucket, e.g. www.mydomainname.com
Enable Static Website Hosting
Set the Bucket Policy to public read
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "PublicReadForGetBucketObjects",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::www.mydomainname.com/*"
}
]
}
Build the angular app locally, into a dist folder.
Push the files to the website using the aws-cli
aws s3 sync dist s3://www.mydomainname.com/
This solution will cost pennies, much lower than an Elastic Beanstalk solution (EC2, EBS, ELBs). Elastic Beanstalk is great for Monolithic apps, but their existence is numbered, and the wrong paradigm when you are talking SPA, IMO.
I know I'm pushing my luck now, but I would also strongly recommend using the Serverless Framework to build and deploy NodeJS API endpoints for your Angular App to interact with.
Follow the steps:
-- Angular app
Create your Angular App
Build your Angular App using ng build --prod command
This will create a dist folder like 'dist/app-folder' with HTML, js, and CSS
The angular app you just built won’t work as a static website, it has to run on top of a Node.js server
-- Node.js App
Created a new folder and create a Node.js project by running: npm init and follow the instructions
Name entry point: (index.js) js to 'server.js'
Install Express and Path using npm install express path --save command
Create a file named 'server.js' into the project folder
Now check the package.json file for a configuration named “main” the value should be 'server.js'
Copy the Angular dist folder to Node.js app folder
Open 'server.js' file paste below code
var path = require('path');
const port = process.env.PORT ||3000;
const app = express();
//Set the base path to the angular-test dist folder
app.use(express.static(path.join(__dirname, 'dist/yourappfolder')));
//Any routes will be redirected to the angular app
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'dist/yourappfolder/index.html'));
});
//Starting server on port 8081
app.listen(port, () => {
console.log('Server started!');
console.log(port);
});
Run Node.js project locally using 'node server.js' command
The app should work on localhost:3000 port
Take the dist folder, the server.js file, and the package.json file (of the server project) and compress them as a zip. DO NOT include the “node_modules” folder.
Upload the zip to your AWS Elastic Beanstalk environment
Browse your site
Hope this is useful!
Got the deployment issue resolved! I used express to create a server and serve my angular app. I needed to add server.js to my dist/ folder. My server.js file looked like so
const express = require('express');
const http = require('http');
const app = express();
const port = process.env.PORT || 3001;
app.use(express.static(__dirname));
const server = http.createServer(app);
server.listen(port, ()=> console.log("Running..."));