How to use express.js as proxy in angularjs-seed app - angularjs

angularjs newbie alert!!!
I need to a proxy to avoid CORS & i'm looking to implement express-proxy. I found this solution but I'm not sure where to put the code. I need the information in the context of a typical angular-seed app. Please help. Thank you!
ex: Where do I put in the code & how do I start the proxy server
var express = require('express'),
httpProxy = require('http-proxy'),
app = express();
var proxy = new httpProxy.RoutingProxy();
function apiProxy(host, port) {
return function(req, res, next) {
if(req.url.match(new RegExp('^\/api\/'))) {
proxy.proxyRequest(req, res, {host: host, port: port});
} else {
next();
}
}
}
app.configure(function() {
app.use(express.static(process.cwd() + "/generated"));
app.use(apiProxy('localhost', 3000));
app.use(express.bodyParser());
app.use(express.errorHandler());
});
module.exports = app;

I'm not sure what your exact setup is, but if you follow the templating from a scaffolding solution like yo, this code would go in the root directory under a file called, let's say, server.js. To start the server, to to the directory in the command line and type node server.js (or you can use gruntas a task runner if it is installed with your project). Lastly, just open your browswer to localhost:3000 and you should be all good to go.

Related

live reload when running express with CRA

I have my create react app setup similar to this setup. https://www.newline.co/fullstack-react/articles/using-create-react-app-with-a-server/
All is working great so far.
when I'm running on localhost:3000 i'm seeing hot reloading as CRA dev server is taking care of that for me.
Now when I run my app using my express server localhost:8081 i'm loading my html file and assets from CRA build folder which obviously means I'm only going to get the built files.
What i'd like to do is when running in port localhost:8081 I can get a reload of development changed files and not just the static build files.
The reason for this is let's say I'm using an authentication setup where I need to check if user is logged in before I allow the * route to proceed otherwise redirect to another route in express. I want to be able to check for this when working in development.
If I run the dev server localhost:3000 then I no longer get the route change loading my html files from express. Only the api call would work from express.
Here is my setup in express:
const express = require("express");
const path = require("path");
const PORT = process.env.PORT || "8081";
const app = express();
const indexPath = path.join(__dirname, "../build/index.html");
app.use(express.static(path.resolve(__dirname, "../build"), { index: false }));
app.get("/test", (req, res) => {
res.json({ message: "welcome to backend" });
});
app.get("*", (req, res) => {
console.log("sending index.html");
res.sendFile(indexPath);
});
app.listen(PORT, () => console.log(`listing on port ${PORT}`));
This express route will only work when using in localhost:8081 which is getting the build files.
app.get("*", (req, res) => {
console.log("sending index.html");
res.sendFile(indexPath);
});
But this never runs when working in dev server localhost:3000 so I can not do any authentication on this route when working in development mode. This would mean to test this I would have to keep rebuilding the build folder which is crazy.
I'm running my client in one terminal and my server in another. I also restarted both multiple times. The proxy as I said works in my package file for the /test route when called using fetch .
This a similar unanswered question I found:
create-react-app + nodejs (express) server

Can't understand client side routing

So I was looking into the p2p.chat.I modified it a bit to have a better room encoding technique and noise suppression based on RNN noise.
I ran the npm run bundle cmd to generate the production build and tried hosting using the express server. But I was not able to emulate the client-side routing as seen on the webpack dev output. It doesn't use react-router.
I have no idea how to host this web-app.
p2p.chat
okay got it fixed after replacing the contents of jam.js to this
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, '')));
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, '', 'index.html'));
});
app.listen(9000);
I removed the directory reference in it

Simple password-protection for React app on Heroku

I have a simple React app, created with create-react-app, that I'd like to deploy to Heroku (or somewhere easy) and password-protect. The protection can be really simple—just a single password is fine.
I started looking into HTTP basic auth but didn't find an easy answer. The closest I found was in this post, but (a) I don't love the idea of having to eject my app, and (b) I couldn't get it working. I was hoping I could find a Heroku plugin, but no luck there either.
It wouldn't be too hard to write a component that wraps my app and requests a password before showing it. The problem is that it executes client-side. I want to store the correct password server-side (or a hash thereof), and have the app send password attempts up to the server.
Since create-react-app operates on top of Node, I'm hoping there's an easy way to tell it to execute and store certain things on the server, but maybe I'm wrong. Any suggestions?
This create-react-app buildpack seems to support http basic auth:
https://github.com/substantial/create-react-app-buildpack
https://elements.heroku.com/buildpacks/substantial/heroku-buildpack-static
I am assuming your intentions are wanting to protect the config vars in heroku so other people cannot access you database with your credentials.
The way I password protected my deployment to heroku, is to make a keys_prod.js file containing the Heroku config vars of my mLab database in my backend using express and mongoDB:
keys_prod.js file:
module.exports = {
mongoURI: process.env.MONGO_URI,
secretOrKey: process.env.SECRET_OR_KEY
};
keys.js file:
if (process.env.NODE_ENV === 'production') {
module.exports = require('./keys_prod');
} else {
module.exports = require('./keys_dev');
}
in my server.js file I added:
// DB Config
const db = require('./config/keys').mongoURI;
// Server static assets if in production
if (process.env.NODE_ENV === 'production') {
// Set static folder
app.use(express.static('client/build'));
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
});
}
This allows you to request the config vars you filled in heroku without including it in your repo.
If you use Node in backend you can use Passport Basic Auth
app.get('*', passport.authenticate('basic', { session: false }), (req, res) => {
res.sendFile(path.join(`${__dirname}/../build/index.html`))
})
Every time you access the page in browser, a popup will appear, asking you username and password.

A second node server (or port) won't start in production (Elastic Beanstalk)

I have a Node/Angular app I'm trying to deploy. It uses two node servers: One to essentially serve the app; another to get data from an API, when a specific port is requested by the app, and store that data locally.
I've got it working perfectly on my own local machine. However, when I deploy to production environments -- either Heroku or AWS Elastic Beanstalk -- I find that the second script either won't run or won't start properly. The end result is, it doesn't get the data I need.
Here are the two scripts; they're both set to run in package.json under "start": "node main.js & node node-server.js"
main.js (again, this one seems to be serving the app just fine):
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/app'));
app.listen(process.env.PORT || 3000);
node-server.js (the one that doesn't seem to work; no data is gathered or populated in the app):
var http = require('http');
var port2 = 1234
var fs = require('fs');
//We need a function which handles requests and send response
function handleRequest(req, res) {
request.get({
url: 'http://sample-url.json',
qs: {
url: 'http://sampletool/pb/newsletter/?content=true'
}
}, function (err, result) {
res.end(result.body);
fs.writeFile('app/data.json', result.body, function (err) {
if (err) return console.log(err);
console.log('API data > data.json');
});
});
}
//Create a server
var server = http.createServer(handleRequest);
//Lets start our server
server.listen(port2, function () {
//Callback triggered when server is successfully listening. Hurray!
console.log("Server listening on: http://0.0.0.0:%d", port2);
});
Then, the main Angular app calls this port (http://0.0.0.0:1234) when the page is loaded, to request new data.
Elastic Beanstalk is using nginx, something I'm not super familiar with and that I don't have running on my local.
Is there something big I'm missing in configuring multiple node.js servers to be running on different ports in a production environment? Thanks in advance for any help.
For security reasons, cloud service providers typically allow the usage of only one port (which is dynamically and randomly assigned to the PORT environment variable) for an application to use from a node server. Read this section from Heroku documentation to understand more about this.
This is why the main app (main.js) that uses process.env.PORT is working and the other app (node-server.js) that uses hard-coded 1234 is not.
This question has some pointers about the feasibility of multiple ports on Heroku (though, there is no good news there, I am afraid).
As how to go about fixing this, one thing that could be tried is to split this into two separate apps that are deployed separately with separate package.json etc.

Configuring Yeoman for building non-root projects

I might be missing something obvious, but i really can't figure it out by going over the docs and issues on GitHub -
I'm developing an AngularJS project that will be deployed on a specific sub-directory on the server (i.e not the root).
I'm using Yeoman.io, and trying to configure it so the app is self-contained and doesn't rely on absolute paths like '/images' and so on.
Every attempt to mess around with the Grunt file or Compass config ends up with a broken build. Paths of images and sprites are wrong - sometimes it's a wrong directory and sometimes wrong filename (no revision prefixes).
Anyone had good experience with that?
So if I understand you correctly, you want to serve your angular project on a specific path on system.
In grunt.js, I've registered a server task which starts my (local) server:
grunt.registerTask('server', 'Start server', function() {
var done = this.async();
var app = require('./app.js');
var http = require('http');
// Start server
http.createServer(app).listen(app.get('port'), function () {
console.log("Express server listening on port " + app.get('port'));
}).on('close', done);
});
app.js contains the server config:
var express = require('express'),
path = require('path');
var app = module.exports = express();
// Configuration
app.configure(function () {
app.set('port', process.env.PORT || 4000);
app.use(express['static'](path.join(__dirname, 'dist')));
});
In my example I serve the project on directory dist, but this can be anything.

Resources