I have an application built using Express, Mongoose, React and Node. My application is hosted on a location which looks like the following: https://example.com/app_name which means that app_name is the base path for all of the static assets.
I'm using Webpack and setting publicPath to https://example.com/app_name. I can reach my static assets just fine, but when I attempt to do a call to my back-end, my requests are being routed to https://example.com/api/... instead of https://example.com/app_name/api/....
Is there a way to prefix my endpoint calls so that they use https://example.com/app_name/api/... instead of https://example.com/api/...through webpack or any other means?
Related
My Vue app is set up using Vue CLI (Webpack) and it's working as it should. My NodeJS/Express REST API is also working properly. However, to run them simultaneously I now start a local server for each of them -- each with its own port. I would like to have both of them communicate over one port.
Localhost:8080 should point to the home page of my Vue App and the API requests should follow localhost:8080/api/...
In my production environment I use one and the same port/URL by serving the Vue App as a set of static files ('dist' folder). In my development environment I don't know how to set this up, however.
I looked around for answers online, but feel lost among all the different terms I have come across (.env, crossenv, nginx, cors) and that I am running in circles.
What would be a good way of setting this up?
Thank you
Edit:
I ended up creating three modes to run my application:
Development
I use one script in a package.json to start the frontend and backend server on different ports, using pm2 to run the servers in the 'background' rather than blocking further commands in the terminal/cmd. I use configured a proxy inside my vue.config.js to redirect my API calls made in the frontend to the right base URL and used cors as middleware to allow requests to my API from other domains/ports.
Staging
I use one script in a package.json to build the Vue app into a folder ('dist' folder inside my backend folder) that is a collection of static files and start the backend server. My backend is set up to know when I want to go into staging mode and then serve the static files in the 'dist' folder.
Production
I use one script in a package.json to build the Vue app into a folder ('dist' folder inside my backend folder) that is a collection of static files and push my backend (incl. the built static files) to Heroku.
Well if you need to run both on the same port you could first build your app so that you receive a dist directory or whatever your output directory is named and set up an express server that serves that app and otherwise handles your api requests
const express = require("express");
const path = __dirname + '/app/views/';
const app = express();
app.use(express.static(path));
app.get('/', function (req,res) {
res.sendFile(path + "index.html");
});
app.get('/api', function (req,res) {
// your api handler
}
app.listen(8080)
Assuming that node and the 'app' will always run on the same server you can just use a template library like ejs.
You would then just bundle the app and api together, assuming that the front-end is tied to the backend, realistically you would not even need to hit the API as you could just return the records as part of the view, however if dynamic elements are needed you could still hit the API.
Now, with that said, if the API is something used by many applications then it would probably make sense to build that out as its own microservice, running on its own server and your frontend would be on its own. This way you have separation of concerns with the API and Vue app.
I have a react app and a node api, I'm planning to host the react app on netlify and I want my users to be able set custom domains, the route can have other routes too, for example example.com/route1/97/route2
You can use a routing library like React Router, and then to get Netlify to let you use it, define this in your _redirects file:
/* /index.html 200
I have a running ember.js frontend app. Also have a node.js backend app which can do basic CRUD operations from MongoDB. Using Postman I can see that my node.js app is returning JSON data properly.
I want my frontend to use the backend to do CRUD operations on MongoDB. I am new to ember.js so I want a guideline where I can understand to use the JSON data from the node.js app and use with ember.js frontend.
My ember.js app already is using a mock server. It has a "dist" folder inside.
My adapter/application.js file in ember.js frontend:
import DS from 'ember-data';
export default DS.RESTAdapter.extend({
namespace: 'api'
});
I want to use my localhost:3000 node server here. Do not know where to add it.
DS.RESTAdapter has a host property that allows you to configure the host used:
// app/adapters/application.js
import RESTAdapter from '#ember-data/adapter/rest';
export default RESTAdapter.extend({
host: 'https://api.example.com'
});
But I would not recommend to point that one to a local development server cause that reduces your flexibility. E.g. a team colleague of yours may want to start the local instance on another port. I would recommend to use the --proxy option of Ember CLI's serve command:
ember serve --proxy http://localhost:3000
This will proxy the requests to your local development server.
You may need to customize the adapter and serializer if your API isn't following the defaults of Ember Data's RESTAdapter and RESTSerializer. Please have a look in the guides for a quick introduction to do so.
The documentation says that you simply must update your app.yaml - like you would for any language within AppEngine. It also states later on that for local development, you probably want your server to respond to static requests as well. However, when I update my very simple app.yaml to be as such:
runtime: nodejs8
handlers:
- url: /apiEndPoint
script: auto
- url: /.*
static_dir: public
It seems all requests still end up coming in to my script - which will return a 404 in the prod instance, since those files won't be uploaded. I can force them to be uploaded, and then my nodejs server responds to the static requests - but I thought the idea of this app.yaml was to configure it so static files are served outside of my app logic?
So to be clear - you can host static files in production Nodejs Standard AppEngine without needing to use a JS server. However, for local development, you must find a way to serve those files locally when running on your machine. For this reason, you put the handler in Express, for static files, which should never be touched in production - since the app.yaml handler is the first-pass.
If you want to be positive Express.js is not serving up static files in production, you can do so by doing something like this:
// Production instances automatically have this environment variable.
const isLocal = (process.env.NODE_ENV !== "production");
if(isLocal) {
app.use(express.static('public'));
}
The static files are uploaded during deployment, but not in the same place as the app's code. They're uploaded in Google's infra dedicated for directly serving static content. This could be confirmed by increasing the log verbosity of the deployment command.
When a request URL matches one of the static handlers it should be directed to this dedicated infra, it shouldn't reach your app code. It should be relatively easy to confirm with an actual deployment.
As for the local development, I'm not exactly sure how the Node.Js server behaves (indeed, the docs appear to suggest Express may be needed to handle static files), but the Python one serves itself the static files based solely on the app.yaml static handler configs, without hitting any of the app code. Could be because of the still very new Node.JS standard environment support.
The static files that you want to serve need to be deployed along your application code with gcloud app deploy.
Your app.yaml file says:
Any request that matches /apiEndPoint will be routed to your Node.js app
Any other request URL will serve a static file from your public folder and not arrive to your application (once deployed).
For example: /index.html will serve public/index.html if this file has not been deployed, then it will return a 404 page.
I have a react + node + express + webpack client/server app.
I want to dynamically generate and serve the client front end to have dynamic meta-tags informed by the HTTP request URI.
Specifically:
How does one configure webpack to accept context variables directed by HTTP request URI, and dynamically render this content?
You can't really do that with Webpack alone. Webpack is a module bundler that runs during build time to compile your code into static bundles that are later consumed by your frontend app.
It's possible to generate html using webpack with html-webpack-plugin, but I wouldn't recommend this approach for your needs.
What you can do instead is to configure your express server to dynamically generate the html. There are multiple ways of doing this. One way would be to use a templating engine with your express server to dynamically generate the markup before sending the response.
see: https://expressjs.com/en/guide/using-template-engines.html