Heroku doesnt serve bundled React JS application in Spring Boot - reactjs

I have the following gradle build configuration
node {
version = '10.14.2'
npmVersion = '6.5.0'
download = true
workDir = file("${project.buildDir}/node")
nodeModulesDir = file("${project.projectDir}/src/main/webapp/chronos-ui")
}
bootJar {
baseName = 'chronos'
version = '0.1.0'
from("${project.projectDir}/src/main/webapp/chronos-ui/build") {
into "${project.projectDir}/src/main/resources/static"
}
}
task installFeDependencie(type: NpmTask) {
args = ['install']
}
task buildFe(type: NpmTask) {
args = ['run-script', 'build']
}
buildFe.dependsOn(installFeDependencie)
build.dependsOn(buildFe)
Basically it does the following:
Builds ReactJS application
Copies the build ReactJS application into jar file
When I locally executegradlew build and then java -jar jar_name.jar
I am able to see the built React JS application at the localhost:8080
However, when I deploy my app to the heroku, the access to the root URI provides me 404 error.
What is the problem and how can I fix it?

Related

Deploy ASP.NET core 7 Web API with React front end

I wrote an ASP.NET Core 7 web API backend and standalone Javascript React front end. I can deploy the backend to IIS successfully and it works fine through postman. However when I try to deploy the react front end using the method described in this tutorial https://learn.microsoft.com/en-us/visualstudio/javascript/tutorial-asp-net-core-with-react?view=vs-2022
my visual studio just freaks out and crashes. I am trying to figure out how to deploy the front end manually without using the visual studio publish feature.
This is my project setup:
[1]: https://i.stack.imgur.com/cApdk.png
And this is the IIS side where the WEB API backend is currently published:
[2]: https://i.stack.imgur.com/GtJ9O.png
Do I need to create a separate site for the frontend or can I deploy it to the same site as the backend? How can I build the frontend and manually deploy to the IIS?
For the site to work properly, you should build the frontend part in production mode, i.e. use the command npm run build instead of npm run start.
And then move the resulting files to the wwwroot folder inside your NET7 project.
Additionally, you should add static files using the AddStaticFiles method.
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-7.0
Also remember to set the ports correctly, because you can have different ones in the development and production environment, you will do it in launchsetting.json
You just need to change your Program.cs file like below, the you could publish webapi project directly. Every step mentioned in the official document must be completed, and finally add the following code.
namespace WebApplication1
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
else
{
app.UseDefaultFiles();
//app.UseStaticFiles();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
//app.MapControllers();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
// Add this line
endpoints.MapFallbackToFile("/index.html");
});
app.Run();
}
}
}
Test Result

Trouble getting production build React application to make requests to Flask back-end

I have developed a React (front-end) and a Flask (back-end) application.
I have been using the command "npm start" to start the development version of the front-end. This is working fine. The front-end has no trouble sending "fetch" commands to the Flask back-end.
I need to get a production build of the React application running. The React application and the Flask server both need to be deployed locally on the same Linux box (I cannot use "Heroku", etc).
I have created a development build of the react application using the command "npm run build". After the build folder is created successfully, I can run the development build using the command "serve -s build"
The problem occurs when the production build React application attempts to communicate with the currently running back-end server using the fetch command.
The back-end server is set up to run on host = "localhost", port = 3001. The front-end is running on host = "localhost", port = 3000. For development purposes I installed "http-proxy-middleware" and then I created the file "src/setupProxy.js" with the following content:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(createProxyMiddleware("/api_tpwa" , { target : "http://127.0.0.1:3001/"})); }
After doing a bit of research online I came to the conclusion that the current proxy can be used for development, but not in a production build
Here is an example of some test react code (that calls "fetch") that works in the react development application but fails in the production build (proxy is still being used in production build)):
fetch(`/api_tpwa/test`).then(response => {
console.log(response);
return response.json();
})
.then((data) =>
{
console.log(data);
})
.catch(error => {
console.log(error);
})
When I run this using the production build I get the following information printed for the "response" variable in the console:
Response { type: "basic", url: "http://localhost:3000/api_tpwa/test", redirected: false, status: 200, ok: true, statusText: "OK", headers: Headers, body: ReadableStream, bodyUsed: false }
I get the following information for the caught error in the console:
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
I compared the value for "response" for the development build (started with npm start) vs the production build and the values were identical. So, I'm not sure why there would be a json syntax error in one case and not in the other.
I suspect the problem is related to the use of the proxy within the production build but I'm not sure.
Here is the back-end route test function:
#app.route("/api_tpwa/test")
def routeTest():
print("executing api test()")
returnResult = {'result': 1}
return json.dumps(returnResult)
This back-end function never gets executed for the production build. the text "executing api test()" is not printed to the console.
What changes would I need to make to either the front-end or back-end to get a production build react app that can successfully communicate with the Flask back-end?
Any help would be greatly appreciated.

React app + heroku server not working on production, but working fine in dev

I am working on React application which is querying from a server. I have deployed the server on heroku. When I am testing in dev, the application is behaving as expected. But when I am using it on vercel deployment, it is failing as heroku server is not responding properly.
Following is the server code of the query:
app.get(`/allPlans`, async (req, res) => {
console.log("allPlans() query");
ret = await Plans.find({});
f = [];
for (i = 0; i < ret.length; i++) {
f.push(ret[i].name);
}
console.log(f);
return res.status(200).send(f);
});
Folowing is the code I am using to query from the client using axios:
const endPoint = "/allPlans";
let ret = await axios.get(endPoint);
console.log(ret.data);
In the dev environment, when I am deploying the application on localhost:3000, this is returning me a nice array.
["test","myPlan190","myPlan987"]
But in the actual production on vercel it is returning the following object(You can check this message in the console by going on the vercel deployment):
All suggestions are welcome.
Github repo
Vercel deployment
Server status
Heroku server query which is failing from axios, but working elsewise
Well, I checked you repository and also checked the XHR requests on your Vercel deployment and as far as I can see it making only one, which is:
Request URL: https://planner-pcrsehfg3-akcgjc007.vercel.app/allPlans
It is not making an actual call to the server. I see that in Dashboard.js you are requiring axios from the package. I did not find any created instance of axios. So essentualy there is nothing to append in front of "/allPlans". Either create an axios instance with the right url "https://cryptic-bayou-91116.herokuapp.com" of just test it by putting the whole url "https://cryptic-bayou-91116.herokuapp.com/allPlans" inside the axios call in Dashboard.js.
Following is the updated code for an axios query:
const baseURL = "https://cryptic-bayou-91116.herokuapp.com"
...
const endPoint = baseURL + "/allPlans";
let ret = await axios.get(endPoint);
console.log(ret.data);
fHeroku randomly changed application binding port.
You may set port by:
const port = process.env.PORT || 3000
for this use in you app dotenv
Or edit file .env on heroku. Install Heroku CLI:
heroku login
heroku run bash -a app_name
touch .env
echo "PORT=3000" >> .env
check variable by
cat .env

Trying to serve CRA build folder statically in asp.net core 2

I created a basic web api, and added a react frontend using create-react-app. When in production I want to serve the build folder which gets created by running npm run build from create-react-app statically. Based on what I found on the docs here, I tried the following, but to no avail. I get a 404, and nothing on screen.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsProduction())
{
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "client/build")),
RequestPath = "/static"
});
}
app.UseMvc();
}
Not sure where I am going wrong.

App engine SDK not accessible in Gradle app engine project

My build.gradle:
buildscript { // Configuration for building
repositories {
jcenter() // Bintray's repository - a fast Maven Central mirror & more
mavenCentral()
}
dependencies {
classpath 'com.google.cloud.tools:appengine-gradle-plugin:+' // latest App Engine Gradle tasks
}
}
repositories { // repositories for Jar's you access in your code
maven {
url 'https://maven-central.storage.googleapis.com' // Google's mirror of Maven Central
// url 'https://oss.sonatype.org/content/repositories/snapshots' // SNAPSHOT Repository (if needed)
}
jcenter()
mavenCentral()
maven {
url "s3://my.private.repo.com/maven/releases"
credentials(AwsCredentials) {
accessKey AWS_ACCESS_KEY
secretKey AWS_SECRET_KEY
}
}
}
apply plugin: 'java' // standard Java tasks
apply plugin: 'war' // standard Web Archive plugin
apply plugin: 'com.google.cloud.tools.appengine' // App Engine tasks
dependencies {
providedCompile group: 'javax.servlet', name: 'servlet-api', version:'2.5'
compile 'com.google.appengine:appengine:+'
compile 'com.stripe:stripe-java:3.6.0'
compile 'javax.mail:mailapi:1.4.3'
}
appengine { // App Engine tasks configuration
run { // local (dev_appserver) configuration (standard environments only)
port = 8080 // default
}
deploy { // deploy configuration
stopPreviousVersion = true // default - stop the current version
promote = true // default - & make this the current version
}
}
group = 'com.example.appengine' // Generated output GroupId
version = '1.0-SNAPSHOT' // Version in generated output
sourceCompatibility = 1.7 // App Engine Standard uses Java 7
targetCompatibility = 1.7 // App Engine Standard uses Java 7
The Stripe and JavaMail JARs appear to be downloaded just fine. But when I run compileJava I get other errors:
/path/to/eclipse-workspaces/google-eclipse-projects/myproject/src/main/java/com/package/ChargeStripeServlet.java:3: error: package com.google.appengine.api.taskqueue.TaskOptions does not exist
import static com.google.appengine.api.taskqueue.TaskOptions.Builder.withUrl;
...
It appears that the App Engine SDK is not being downloaded, but I don't see any error message. I have installed the SDK locally, if that helps (although I suspect the JARS will just be downloaded anyway).
What you need to do is to add the following dependency:
compile 'com.google.appengine:appengine-api-1.0-sdk:+'
As you can see here 'com.google.appengine:appengine:+' is of type POM, hence does not carry any java classes, it's only a parent.

Resources