I have an AngularJS application that talks to a NodeJS backend. I have recently just hard-coded in the API address in my front-end as there has only been one environment (i.e. my development environment has been the same as my production environment).
However, as the project has expanded, I now have three environments: development, staging and production.
My development and staging environments talk to the same API (let's say dev.fooapi.com), but my production environment should be talking to a different API (let's say prod.fooapi.com).
My question is: what are some 'elegant' (I put this in quotes because who is to say what is elegant and what isn't) ways of achieving this in my application? I currently have a string placeholder in my source files that looks like 'API_PLACEHOLDER' and a Grunt task that performs a string replace anywhere in my codebase where it matches that string. Obviously this isn't ideal because the files where these placeholders are substituted are source controlled, and I don't really want to do a string replace and then accidentally commit some code that has hard coded developer API addresses because that will break in production.
Extra information: I do make use of Grunt in my application, I deploy to Windows (can't be changed, unfortunately), I use Git for source control and I do builds/deployment using Bamboo.
More than happy to answer any other questions about my issue.
Note: I need to substitute config values not only for my front end but also the back end (i.e. when I start my node server I want the port that it starts on to be configurable.
Thanks!
I'm using gulp-ng-config which allows dynamically generated angular constants to be added to my application based off the node environment variable.
In the docs from link above is an example of supply a different api url to front end app, I'm sure there is a grunt version, in fact grunt-ng-config looks like the equivalent. The values config option takes a function where you can return something based on the node environment variable
Related
So, I guess the language doesn't really matter but the thing is, I have a file called database.js in a folder. Its code must be different depending on whether I am programming in my local environment, or if the code has to be alocated the server (heroku in my case).
For the local environment, I have a postgresql database, which is different from the one I have as an addon in the heroku server. That's why the code is different. The connection to the database is the 'problem'.
What I do now to solve this, is comment out the code for server, test locally, and when I have something usable, I comment out the code for local, comment in the code for server, and deploy in the server.
Here's the code
https://github.com/MauroOyhanart/ControlDeGastosIngresos/blob/main/util/database.js
What solutions can I find? I'm pretty flexible. I'm really new to web programming and I'm looking for tools.
You're probably going to want to use some sort of configuration / environment variables. All if not most hosting services should offer a solution, but since you mentioned Heroku I know they support config variables. A bunch of information about them in different languages and how to add them to Heroku can be found here.
Just a quick summary; in NodeJS you are going to want to use process.env to access environment variables. For example (using fictional functions because that isn't the important part here):
db.connect(process.env.DB_HOST, process.env.DB_PORT);
db.login(process.env.DB_USERNAME, process.env.DB_PASSWORD);
Again look at the link above for the actual useful bit with Heroku. This should do the trick for you.
Sorry if you think this has been asked before but there doesn't seem like a good solution anywhere.
I have a build pipeline that packages up my react app into a single artifact.
The release pipeline pushes that artifact to different Azure storage accounts for each environment (Dev, UAT, Live).
Surely there is a way to use DevOps variables to configure variables in my package per environment.
Other solutions:
One build per environment - I don't want to do this because I would need to create a branch for each environment, a pipeline for each, the env configs for each, and a release pipeline for each. This means a change to 1 environment takes 3 times as long. Also, the time to build these environments trebles.
Using a JSON file and swapping this out on deployment. - This didn't work because webpack imported the JSON file into the build so whilst I transformed the config.json files. It was too late. This seems similar to using env.development and env.live and would mean 3 builds
Pull environment out of the request URL and call an endpoint - seems like my only option but definitely has flaws.
This isn't an issue in .NET (or Java I believe, .NET is my background) and was solved years ago with web.config and appSettings.
Please let me know if you have solved this and how?
Thanks for your help
Runtime Environment Variables in React for UAT and Live for a single build devops
We could use the task Replace Tokens to use DevOps variables to configure variables in the package per environment:
The format of variable in .json file is #{TestVar}#.
And define the key's values on the Variables based on the stages:
Hope this helps.
I have a Create React App Project that will be pointed to two different domains: .com and .co.uk.
I want do some localisation eg if .co.uk currency will be set as punds, email address will go to uk mailboxes etc.
What is the best way to do this? I thought window.location.href value passed by wrapping my routes in the context in App.js but having some issues with use effect and not sure if this is the most efficient approach.
The best way would be to use environment variables - this also allows for easy debugging for either version. This will require you to build the project twice for every website update - one version for .co.uk and the other for .com.
Setting an environment variable can be done through the .env file (depending on if you want it to be local you can use .env.local, if you want it to be only on production you can use .env.production and if you want to keep your production values local you can use .env.production.local) or via prepending the environment value before build, like so REACT_APP_COUNTRY=uk yarn build.
For the variables to be accessible in your application you will have to make sure they start with REACT_APP_. You can access them in your project with process.env.REACT_APP_COUNTRY (you do not need to import/install any libraries).
If you have a CI/CD set up this will be easier - you just need to create two separate pipelines to deploy a version with REACT_APP_COUNTRY=uk to the .co.uk site and a version with REACT_APP_COUNTRY=us to the .com site.
I've slightly "abused" the front-end "version" concept in App Engine (java), to implement modules before they were introduced. I have a configuration consisting of: module1-dot-myapp.appspot.com, module2-dot-myapp.appspot.com, module3-dot-myapp.appspot.com, etc., based on the version concept (more commonly used with numbers: 1-dot-myapp, etc.).
Specifically, the code in all versions is identical, but each is practically used for different purposes. This separation allows different clients to use different api versions, separate deployment schedule, staging versions, logs separation, etc.
My question is, under theses conditions, what is the best way to convert my application to "real" modules? such that "module1" is an actual module (still mapped to the same url - module1-dot-appspot.com)?
Note: my answer comes from a somehow similar exercise but in the python GAE runtime, there is likely aditional Java-specific stuff to look at as well.
First things to look at (possible show stoppers) are the app-level configs - those will need to be merged in from your different old app versions (if they exist) and will be shared by all your modules (or directed to the default module only), so they might not work as before, best to revisit the latest documentation on these configs:
dispatch file
queue
cron
DB indexes
Note: in multi-module python apps these configs might not be updated automatically at app upload, each of them may need to be uploaded explicitly, using the respective app configuration utility options.
The separate deployment schedule is almost free (each module can be deployed independently). But there may be some impact due to the app-level configs (multiple CLI invocations instead of a single one, for example)
The logs separation comes for free.
The staging story might need to be revisited, depending on what exactly you mean by that.
Other than that - you'd bring the different old versions of your app in separate module sub-directories in your new app. Check if your version control system supports this easier. The old app config file(s) would need to be "translated" into the respective module's config file(s) and some of the info would go into the new app's top dir config file.
The module URL routing should allow transparent URL mapping, but note that the URLs will actually be <module>-dot-<appname>.appspot.com and the only way to get exactly the same URLs would be to delete all older app versions before deploying the new one (due to conflicting URLs: <module>-dot-<appname> vs <appversion>-dot-<appname>, not sure if you'll get the old or the new code serving or if it's even possible to deploy the new code without error). You could use a new appname at first, just to get all ducks lined up before the switchover (possibly a new staging story you might consider going forward).
You might find helpful complementing URL routing with a dispatch file if you didn't have one before.
Finally, if you have identical files shared across modules you may consider a single per-app copy of the file, symlinked into the respective modules, if that's easier or makes sense from your source code management prospective.
I have an Angular application that will have multiple installations (for different customers) and I'd like to use system environment variables to hold things like the URL for the back end service.
I've read lots of questions on here that talk about using config files to hold those settings, but it's not feasible for me to add files to the source code each time a customer wants to install the application.
I know I can bring an environment variable into Grunt (for development purposes) and Express using e.g. process.env.URL, but how do I get that variable into Angular itself?