I just want to know the correct way to serve an angular universal app with an existing nodejs/express server that talks to a Mongodb database and serves data with an "/api/*" route for example.
So is it to have the universal app have its own node/express server as explained here https://angular.io/guide/universal and just merge that with the existing node/express server with route configuration as done here Serve angular universal app with NodeJS/ExpressJS back-end and allow both the custom node/express server and the universal apps express server have different ports (because i assume that is how they will be able to co-exist in production)
Or do we use the custom node/express server as the server for the universal app with proper configuration.
To serve angular app with node server first you need to build the app just run the below command
ng build
And then add two lines of code in your node server file as
app.use(express.static(__dirname + '/dist'))
app.use(function(req, res) {
res.sendFile(__dirname + '/dist/index.html')
})
And after that you can run node server and the default entry index html file will open when you hit the host.
Related
I manage to create Angular apps in general, but I do not understand how Angular and Node.js connect together.
Even on a local environment, you need to launch two things:
ng serve
node app.js
So how the two connect? Do you render the Angular app via Node.js? Do you render the app like this:
or like this:
But then there is the route problem, do you define routes via Node.js with app.get('/')
or via Angular with:
const routes: Routes = [
{ path: '', component: HomeComponent}
];
ng serve & node app.js will launch those two scripts at the same time.
Angular and NodeJS application connect over HTTP where NodeJS is the backend and the Angular is the frontend.
ng serve is the command to server Angular application on your local environment but when you'll deploy your Angular app in production, first you'll have to build the Angular app and serve the destination folder using Nginx or something else..
node app.js is the command you are using to launch your NodeJS server (in your case) which will start listen on some HTTP port (if you are using NodeJS Express correctly)
An example of connection between the two over HTTP is like this:
the Angular app issue an HTTP request to the NodeJS backend and the NodeJS server respond to that HTTP request to send data back to the Angular app.
regarding the routing, Angular is a Single Page Application (SPA) so it can handle it own routing requests as you showed and this is what you should use for your website (the frontend) most of the times. where the routes in your NodeJS application refer to your REST API routes, as in what functions your NodeJS server supports.
I think you should read on how to implement REST api in NodeJS and you'll find great detailed guides about it, and creating a single page application in Angular
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'm currently developing using ng serve, with proxy configuration, while the proxy points to another nodejs instance on the same machine.
This backend is a simple express server, like this (simplified):
var express = require('express');
var app = express();
var customers = require('./customers.controller.js');
app.get('/api/customers', customers.getAll)
var server = app.listen(8081)
The frontend (ng serve) runs on port 4200 and proxies /api to http://localhost:8081/api
As far as I can see, this is the recommended setup.
However, I would prefer to have the backend running directly inside of ng serve instance instead of the proxy.
And if possible, even take advantage of the automatic reload feature of ng so that I don't have to restart the server if I change something on the backend code.
As both are nodejs and ng seems to be configurable, I think this is possible, but I can't find a starting point for defining my own routes
Its possible to do this
you just need to put your angular into the backend by utilize the nodejs routing
basicly angular is a "static file" and the entry point is coming from the index.html
// Redirect all the other resquests
this.app.get('*', (req, res) => {
res.sendFile(path.resolve('dist/index.html'));
});
but remember you need to handle the routing for image, js, css and others also.
I have a Node/Express setup in dev that outputs data as JSON for consumption. In dev that endpoint is localhost:3000/data
I also have an Angular 8 app in the same node directory for the front end. In dev, I launch two separate Node command prompts... one to run node/express at port 3000 and another to run angular at port 4200.
The goal is to have the Angular app output the data the Node/Express backend is providing... in an Azure Web App.
I have read articles that state how to deploy Angular to a WebApp, but can I have both the Node/Express backend serving data and the Angular app running in a single Azure Web App... or do I need to create two separate apps and use a CORS listing for the frontend to speak to the backend Web App?
I am guessing that I will need to use Express to launch Angular then perform a build instead of Express and Angular running on separate ports?
You can use Angular and Express on the same directory, and a middleware on express, so when you do request, the middleware identify if it's a "/data" URL or a simple URL and send the index file that angular generate on dist folder.
Move app.js to your Angular app folder
Insert this code;
app.use(express.static(path.join(__dirname, '/dist/<your Angular App Name>')));
app.use('/data', <your route file>);
app.use(function(req, res) {
res.sendFile(path.join(__dirname, '/dist/<your Angular App Name>', 'index.html'));
With this, you Angular and Express runs on localhost:3000.
I have installed polymer-cli and setup an Express server. How can I run Polymer code with Express?
Routing with Polymer and Express - This link work for you to run Polymer code with Express and setup Express.
// Node.js notation for importing packages
var express = require('express');
// Spin up a server
var app = express();
// Serve static files from the main build directory
app.use(express.static(__dirname + '/build/bundled'));
// Render index.html on the main page, specify the root
app.get('/', function(req, res){
res.sendFile("index.html", {root: '.'});
});
// Tell the app to listen for requests on port 3000
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
The answer given by StackOverflowuser is correct. Just clarifying what I have found so that newbies can follow.
Polymer Cli is a stand alone tool: i.e you don't need anything else to run a polymer app. It has it own web server and listens on the port to serve request.
So when you execute
polymer serve --open
You are serving your polymer app on
http://127.0.0.1:8081/components/polymer-starter-kit/
Now that you have developed your app, its time to deploy this to a web server as polymer cli is not a web server.
This is the part that requires the deployment.
You now have to build this app to be deployable
We do polymer build. This prepares the app for deployment to a separate build folder under
build/
es5-bundled...
We now need to take this bundled files and deploy on web server. This is independent of Polymer Cli and you can choose which port etc to expose.
In this case, going by your definition you want to deploy on express which is a web server on top of node.js.
The code present on top explains the actual code you would use to deploy the polymer bundled app in express on top of node.js.
pm2 abstracts this and you can run it as a service with all the web server goodies. So we could now use pm2 to run the web server app than the default node.js.
Both styles of deployment are possible.
Have both web server hosting app and polymer app in the same solution.
Have different apps for web server hosting app and polymer app
When you have different apps, you have the added overhead of copying only the files under the build to the web server to be hosted but its cleaner and separates the source from the deployed similar to backed technologies were code is different from compiled libraries.