Reputation: 3332
I am trying to deploy my MEAN app. Before doing that on heroku or some other place, I am testing the production mode. Everything works in "development mode" when I launch Node and Angular separately on two different ports. In production mode i cannot reach the backend API.
Using environment variables (see below) I have Node.js/Express server the Angular compiled code in /dist. These are some relevant excerpts from the Node.js code:
const express = require("express");
const path = require('path')
const cors = require('cors');
const mongoose = require('mongoose');
const app = express();
... //some non-relevant stuff eg passport, body-parser ...
//Load configurations
const config = require('./config/config.js');
// Load routes
const storeroutes = require('./routes/stores.routes.js');
//Use mongoose to connect to the stores DB in mongoDB
mongoose.connect(config.mongoDB, { useNewUrlParser: true });
mongoose.connection.once('open', () => {
console.log('Connection to the MongoDB database established successfully!');
});
// CORS Middleware
app.use(cors());
...
// Static Folders (used by Node)
app.use(express.static(path.join(__dirname, 'views')));
app.use(express.static(path.join(__dirname, 'public')));
// Serve Angular
if (process.env.NODE_ENV == 'production') {
app.use(express.static("../dist/"));
app.use((req, res) => {
res.sendFile(path.join(__dirname, '../dist/index.html'));
});
}
// Use routes
app.use('/', storeroutes)
app.listen(config.port);
The config/config.js just exports the environment variables.. so trust me that NODE_ENV='production', config.port=4000, and others that I don't show.
The routes in stores.routes.js is basically an express router and, as I said, everything works in development mode. For example, in development mode the API at http://localhost:4000/stores
shows on the mongoDB database
When I launch NODE_ENV=production node server.js
the front-end page shows correctly, but under the hood the calls to the server API fail, see the screenshots. In fact I cannot navigate to the API link above.
In my Angular service I call the API as follows:
export class StoreService {
uri:string = environment.node_url; //this is 'http://localhost:4000'
// Fetches all documents.
getAllStores() {
return this.http.get(`${this.uri}/stores`);
}
...
}
I suspect the problem is in the Node/Express code app.use((req, res) => { res.sendFile(..
, but maybe if it is a problem in the url to the API that I use in Angular (should I try using baseUrl
somehow?).
Upvotes: 0
Views: 275
Reputation: 3332
The code below forces all routing to the front-end's index.html:
app.use((req, res) => {
res.sendFile(path.join(__dirname, '../dist/index.html'));
});
I first made it work by removing those lines. However, a better solution was to place the backend API above as follows:
// Use routes for backend API
app.use('/', storeroutes)
// Serve Angular
if (process.env.NODE_ENV == 'production') {
app.use(express.static("../dist/"));
// Any request that is not the storeroutes above goes to Angular client
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, '../dist','index.html'));
});
}
Upvotes: 1