How can I access environment variables in Vue, that are passed to the container at runtime and not during the build?
Stack is as follows:
There are suggested solutions on stackoverflow and elsewhere to use .env file to pass variables (and using mode) but that's at build-time and gets baked into the docker image.
I would like to pass the variable into Vue at run-time as follows:
I've tried the following in helloworld.vue:
<template> <div>{{displayURL}} <p>Hello World</p> </div> </template> <script> export default { data() { return { displayURL: "" } }, mounted() { console.log("check 1") this.displayURL=process.env.VUE_APP_ENV_MyURL console.log(process.env.VUE_APP_ENV_MyURL) console.log("check 3") } } </script>
I get back "undefined" in the console log and nothing showing on the helloworld page.
I've also tried passing the value into a vue.config file and reading it from there. Same "undefined" result in console.log
<template> <div>{{displayURL}} <p>Hello World</p> </div> </template> <script> const vueconfig = require('../../vue.config'); export default { data() { return { displayURL: "" } }, mounted() { console.log("check 1") this.displayURL=vueconfig.VUE_APP_MyURL console.log(vueconfig.VUE_APP_MyURL) console.log("check 3") } } </script>
With vue.config looking like this:
module.exports = { VUE_APP_MyURL: process.env.VUE_APP_ENV_MyURL }
If I hardcode a value into VUE_APP_MyURL in the vue.config file it shows successfully on the helloworld page.
VUE_APP_ENV_MyURL is successfully populated with the correct value when I interrogate it: kubectl describe pod
process.env.VUE_APP_MyURL doesn't seem to successfully retrieve the value.
For what it is worth... I am able to use process.env.VUE_APP_3rdURL successfully to pass values into a Node.js app at runtime.
If we are using the full build i.e including Vue directly using the script tag without using a build tool, we should make sure we use the minified version (vue. min. js) for production. We can run the bundling command with the actual NODE_ENV environment variable set to "production".
Running the app locallyThe Vue CLI comes with a built-in development server. This allows you to run your app locally so you can test it easily without needing to configure a server yourself.
Create a file config.js
with your desired configuration. We will use that later to create a config map that we deploy to Kubernetes. Put it into your your Vue.js project where your other JavaScript files are. Although we will exclude it later from minification, it is useful to have it there so that IDE tooling works with it.
const config = (() => { return { "VUE_APP_ENV_MyURL": "...", }; })();
Now make sure that your script is excluded from minification. To do that, create a file vue.config.js with the following content that preserves our config file.
const path = require("path"); module.exports = { publicPath: '/', configureWebpack: { module: { rules: [ { test: /config.*config\.js$/, use: [ { loader: 'file-loader', options: { name: 'config.js' }, } ] } ] } } }
In your index.html, add a script block to load the config file manually. Note that the config file won't be there as we just excluded it. Later, we will mount it from a ConfigMap
into our container. In this example, we assume that we will mount it into the same directory as our HTML document.
<script src="<%= BASE_URL %>config.js"></script>
Change your code to use our runtime config:
this.displayURL = config.VUE_APP_ENV_MyURL || process.env.VUE_APP_ENV_MyURL
In Kubernetes, create a config map that uses the content your config file. Of course, you wanna read the content from your config file.
apiVersion: v1 kind: ConfigMap metadata: ... data: config.js: | var config = (() => { return { "VUE_APP_ENV_MyURL": "...", }; })();
Reference the config map in your deployment. This mounts the config map as a file into your container. The mountPath
Already contains our minified index.html. We mount the config file that we referenced before.
apiVersion: apps/v1 kind: Deployment metadata: ... spec: ... template: ... spec: volumes: - name: config-volume configMap: name: ... containers: - ... volumeMounts: - name: config-volume mountPath: /usr/share/nginx/html/config.js subPath: config.js
Now you can access the config file at <Base URL>/config.js
and you should see the exact content that you put into the ConfigMap entry. Your HTML document loads that config map as it loads the rest of your minified Vue.js code. Voila!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With