Application environment variables undefined when application is served by Amplify - vue.js

I have a Vue.js app hosted by AWS Amplify.
In Vue, env vars can be set application-wide by using .env. files.
I currently use such files for development and for production modes, containing different values.
When locally building and serving my application the above works as expected. However, once Amplify deploys my app (in my case I use Amplify's CD feature), these variables are not defined.
I know I can define the same env vars in Amplify, but that would mean I need to manage these values in two places since won't be redeploying while developing. so this seems to be prone to errors (I will need to remember to update the vars on both the application end and amplify console whenever I need to make a change for example).
I wonder if this behavior is expected or is there something I am missing in my setup.
Thanks!

I was also facing the same issue in my React app.
The thing is, you need to have a .env file in your app with all the environment variables.
Why? — The reason behind that is, it generates static HTML, CSS and JS files. Those files can't access process during the runtime.
After adding all the environment variables in Amplify, you have to add one more command in your build stage in App build specification.
You can refer to this official documentation on how to implement this.
If you don't care much about your environment variables, you can use this hack: printenv. This will store all the environment variables of your OS and your application in the .env file.
My config looks something like this:
build:
commands:
- 'printenv >> .env'
- 'npm run build'

Related

Getting environment variables at runtime in a compiled VueJS app

I'm working on a VueJS app that uses env vars in multiple places. It runs on GCloud with nginx serving the files compiled with vue-cli-service build.
When developing everything works well with the env vars set in .env.development and .env.development.local files and used in JS with process.env.VUE_APP_FOO. I'm not using .env.production as some of these env vars shouldn't be committed to our repository.
For the staging and prod environment of all of our projects, we use GCloud's config maps which let us provide env vars to the pods. The issue in this project is that vue-cli-service build requires the env vars to be available at build time, which is not the case in our setup. Config maps are only available in the pods that run the images.
Out of curiosity, I checked the compiled code and all uses of process.env are quite simply replaced by an object with all vue env vars (basic ones + VUE_APP_* ones). So for example,
console.log(process.env.VUE_APP_FOO);
is compiled to
console.log(Object({NODE_ENV: "production", BASE_URL: "/", VUE_APP_FOO: "bar"}).VUE_APP_FOO);
Except that in our case, VUE_APP_FOO is missing from the object as it's not available in the environment when building the app.
So as is, it doesn't seem possible to provide env vars when the server is started or the JS file is served. Is there a way to tell vue-cli-service to not compile the env that way? Or any other alternative?
The only one I found so far is to replace the uses of env vars with their actual value directly in the compiled JS file when the pod starts using sed, but that's pretty ugly and could break easily.
One approach you can follow is to provide the production values when building locally. Another approach is to setup a continuous integration workflow that fetches your environment variables from wherever it is stored, builds the apps and pushes to production servers. I personally work with approach 2.
It is relatively easy to setup a github workflow that runs whenever your code is pushed to a particlar branch

Is there is any way to get the appcenter config from env file in React Native

One of my android application is developed using React-Native and I have plans to distribute this using app-center as this app is for Internal users. In App-Center I have different projects (created new app) for the different environments - one for dev, one for uat and one for production.
My issue here is whenever I create build package (apk file) to deploy to App Center project, I need to manually change the app-center config. I have used .env config file to get config for different environment. But I can't use this to set app-center config. Can anyone guide me how I can automate this process by either configuring the app-center in .env file or somewhere in code?
If you want to use a specific configuration for each build with the same code, you should use the appcenter's environment variable.
Just add an "app_secret" environment variable, and use a pre build script to create a appcenter-config.json file containing the app_secret

Run Netlify variable api key on build, hiding key from the github repo

I'm using DOTENV module, I want to hide my api key on my github repo, however Netlify needs this to build the api call. I want to create a variable that runs on build in Netlify, yet still works in my development version.
In my code I use this:
let unsplashApiKey = process.env.REACT_APP_UNSPLASH;
Which links to an .env in the root, this works in my dev localhost, I can ignore this with gitignore, but then Netlify needs this .env to run its build, because it builds directly from the repo.
I've seen in DEPLOY SETTINGS in Netlify this option: "Environment Variables", it lets me place name and key, seems to be what I need. How then do I make this varible work for my api inside my code?
all I had to do was call the environmental variable this: REACT_APP_UNSPLASH Due to my code being like this:
let unsplashApiKey = process.env.REACT_APP_UNSPLASH;
I was using the unsplashApiKey in the Netlify variable, which was not working. Now I have been able to hide the .env file in my repo, yet have it in my local, therefore hiding the api key from posible nasty people. Happy days!

How to use deploy specific .env in Vuejs

I have several environments that I build my Vuejs application to. Each of those environments has a different API that I'd like to call.
My ideal scenario is that I have an .env file in the root of each of the servers I deploy to, so that when I deploy my build, the Vue app looks at the .env that is in it's environment specific location and pulls the relevant API path variables from inside of it.
This way, I can build the app once, and have it deployed on multiple servers and I don't need to make a specific build for each server.
I've tried using dotenv-webpack but it seems that the .env that's included in the build is just from whatever the value is when I create the build, and not fetched from any .env on the individual servers.
I've found that I can use axios to GET a js file from /static but this doesn't really seem like the cleanest approach.

How to set an api path during the build process of a vue application based on environment variable?

I am wondering if there is a way to change a 'root path' for my site's api which is a string value of a variable at build time in a vue application. I would like the value of my api path to be read in during the build process and set. This functionality exists in angular, and I am wondering if it exists in vue. I have checked the docs and do not see anything similar. This blog describes the functionality that I am after in angular. If there is nothing similar how does one change the root path of an api from for example 'localhost:8080' to 'example.mysite.com' at build time so that the right path is set when building/deploying to production and not needed to be changed manually? Thanks for any help!
You could set it in an environment variable during the build and access it via process.env.MY_VARIABLE.
During development you would use a package like https://www.npmjs.com/package/dotenv and have a .env file with your environment variables but in production you would set it in your CI or build script.
Bare in mind if this is browser based then you will need to replace
process.env references with the explicit values which you can do with most bundlers.