Different values configuration constants - angularjs

I have an AngularJS website in different environments (dev, prod). I also have some configuration constants that are different depending on the environment (i.e. to send requests to an API).
I have read many posts that solve this with Grunt by creating a dynamic file. Is there any other "more homemade" approach?
UPDATE
In the client side, Im runnĂ­ng my AngularJS client application in an Nginx web server.

You could make your Node.js server decide which configuration file to serve to your client.
var app = express();
app.set('env', process.argv[2] || 'development');
//...
app.get('/libs/config.js', function(req,res){
var env = app.get('env');
if(env === 'development') {
res.sendfile('config/dev-config.js');
} else if (env === 'production') {
res.sendfile('config/prod-config.js');
} else {
res.send(404);
}
});
And in you angular client you do:
<script src="libs/config.js"></script>
And your servers you run your node doing
node app.js development
node app.js production
Also, I think Express has direct support to configure your current environment using process.env.NODE_ENV, so most likely, all you have to do is to set the NODE_ENV=production environment variable in your production Node.js server and you won't need to pass the configuration from the command line directly.

This is a hack, but my home made approach is to override the address of my API using a static hosts entry.
/etc/hosts
192.168.1.100 api.mydomain.com
It is dirty but it works.

Related

How to self-host Gatsby v4 with Server Side Rendering (SSR) capabilities

I'm trying to set up a site to host static content, using GatsbyJS. Some of my pages use SSR. When I run it using gatsby serve from the project root, i'm able to view these pages. I'm not sure how I can deploy and host this application with SSR capabilities. according to this page, gatsby serve is to be used only to test the production build, which infers that there may be a different strategy to host actual production.
Our goal is to deploy to a virtual private server (vps) or Azure App Service, where we have more or less full control of our environment.
I was able to host the static site using this script on Azure App Service (win-node16):
const express = require('express');
const gatsbyExpress = require('gatsby-plugin-express');
const app = express();
const port = process.env.PORT || 8080;
const dev = process.env.NODE_ENV !== "production";
// serve static files before gatsby
Express app.use(express.static('public/'));
app.use(gatsbyExpress('config/gatsby-express.json',
{
publicDir: 'public/',
redirectSlashes: true,
}));
app.listen(port, function() {
console.log(`App started on port ${port}`);
});
this seems serve the static pages properly, but all pages with SSR returns 404. I surmise it may be due to the fact that those pages did not have html stubs generated. as I'm new to Express, i'm also not sure if this is the right approach
if anyone has advice on hosting that would be appreciated.
unfortunately this plugin gatsby-plugin-express is 2 or 3 years old and therefor doesn't support server-side rendering.
You can see this question How to properly run gatsby with SSR in a production environment for more options.
TL;DR: There is no option for self-hosting it unless you will write it yourself.

Different IP addresses in production and test environment how to handle it automaticaly

I have an app with django backend and react frontend. When testing and coding i run my django app on local server 127.0.0.1:8000 and connecting all my react requests to those endpoints. However in production my django app run on a different ip address and everytime i changed my code and push my reactjs app to production server i have to change all the endpoints ip's.
What is the best way to handle it? (as a source control i use git i do not know if it makes any differences)
I set the axios.defaults.baseURL depending on the window.location.origin. Here is my setting:
if (window.location.origin === "http://localhost:3000") {
axios.defaults.baseURL = "http://127.0.0.1:8000";
} else {
axios.defaults.baseURL = window.location.origin;
}
The above config is from my article Docker-Compose for Django and React with Nginx reverse-proxy and Let's Encrypt certificate. I'm serving React with nginx, and have reverse-proxy to Django (also in nginx), that's why for production setting I'm just using the same address. In the case of development, I have REST API at 127.0.0.1:8000.
I prefer this dynamic setting than settin env files because I don't need to set any environment variables.

How to parameterize variables in a React Webpack app for different environments?

I'm working on a React web app which was created by create-react-app and I am getting ready to deploy it.
The issue is, for development, the app uses the api instance running on my dev environment (localhost:{api-port}) but for the deployed app this should point to the server api instance (api.myapp.com).
Currently the host is just a variable in my networking component:
const hostname = 'localhost:9876'
I plan on using webpack to generate the static files which will be served by the production front-end, and I would like to continue developing using npm start as set up by create-react-app.
What would be the correct way to set up my project such that the host can be set automatically to the correct value based on whether I'm running the dev server or building for production?
A common solution is to check against process.env.NODE_ENV like this:
const hostname = process.env.NODE_ENV === "development" ? "localhost:9876" : "localhost:6789";
You may need to force the environment variable to be present in your Webpack configuration file using the DefinePlugin like this:
plugins: [
new webpack.DefinePlugin({
"process.env": {
NODE_ENV:JSON.stringify(process.env.NODE_ENV || "development")
}
})
]
An alternative solution might be to use the config package and provide your hostname string as a configuration parameter. config will inherit configurations from files based on the current NODE_ENV. It will start by using configuration from a default.json file, then override it with a development.json, or production.json, depending on your environment.
Note that you'll need for the config files to be copied to your output directory using CopyWebpackPlugin for it to work.
There are definitely many ways you could achieve that. One of those solutions would be to use webpacks's DefinePlugin. In your plugins section in webpack configuration you would add something like this:
new webpack.DefinePlugin({
API_HOST: process.env.NODE_ENV === 'production'
? JSON.stringify('localhost:8080')
: JSON.stringify('api.com')
}),
That creates a global variable API_HOST available everywhere in your codebase, which you can use. You can read more about the DefinePlugin here https://webpack.js.org/plugins/define-plugin/
you could use a relative path when you make any request to your api server instead of calling the full url for your app.
and for your development you could add a proxy property to your package.json file:
{
...
"proxy": {
"/api/*": {
"target" :"http://localhost:9876"
}
}
}
so whenever you make any request that prefixed with /api will be redirected to http://localhost:9876/api this is just in the development but in the production if you make a request prefixed with /api it won't be redirected it will be served normally because the proxy is just available in the dev server coming with create-react-app.

Setting environment for AngularJS development with existing OSGi/Rest serverices

How to setup the dev environment where the UI is to be re-done using AngularJS and typescript etc but we already have an existing set of services hosted in rest/osgi bundles.
All the development models with AngularJS and type script talks about node/npm etc but how do we hit existing services with that? do i need to enable cors etc for development?
how is UI development done in these kind of projects as i believe not all projects are done from the beginning and have liberty to use node at server.
Well, usually from an angular app you define some kind of angular service that talks to your api in a standard way.
It's true that most "Frontend" projects use a mocking server during development but it isn't hard to hard to use a real server for this, provided it's not you own production server, obviously.
About the cors issue, I use to let CORS fully open during development ,and have a minimally accesable configuration on production, depending on your project.
After some research we have finalized the DevEnv and it's working out very well.
used angular cli for development
used proxy server to make the calls made to 4200 port to redirect to express server running at port 3000
package.json:
"start": "ng serve --proxy-config proxy.conf.json",
finally wrote a small express server to login to existing server and then pipe all requests!
This was our code:
var app = express();
//enable cors
var cors = require('cors')
app.use(cors());
//relay all calls to osgi server!!
app.use('/a/b/c/rest', function (req, res) {
var apiServerHost = "https://" + HOST + ":" + PORT + "/a/b/c/rest";
try {
var url = apiServerHost + req.url;
req.pipe(request(
{
headers: headers,
url: url,
"rejectUnauthorized": false
})).pipe(res);
} catch (error)
{
console.log("Error " + error);
}
} // Added by review
No mock required

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.

Resources