fudo
fudo

Reputation: 2880

Use env variable in VueJS SPA components at runtime?

I'm building a simple SPA with VueJs and Webpack, and would like to use/access env variables from my VueJS components.
I know I will not be able to change those variables "on the fly" but instead I need to recompile-rebuild-redeploy the entire application to see the changes, but for now it's ok since the actual need is to show different info and/or sections base on the deploy environment (local, staging, production).

To be more specific, for now I'm trying to get the env var COMMIT_HASH just to display it as some applications already do just for development info.
This variable would primarily used by the pipeline for the staging deployment, as in local development would be not that useful and probably not used at all for production deployment.

The problem is that I cannot figure out how to access env variables values from my VueJS components scripts sections at runtime, as process.env is a Node method accessible only during webpack compilation and not at runtime.

I thought about using string replacement and found this question, but then I would need to update Webpack script for any new env variable I need to use, so it looks quite inelegant to me.

I also tought of loading all the env variables in a js object and somehow pass it down to the files being compiled by Webpack, but this also looks inelegant/inefficient to me.

So now I'm stuck as can't figure out how to access env vars from my VueJS components at runtime.

Upvotes: 1

Views: 481

Answers (1)

fudo
fudo

Reputation: 2880

I ended up using string-replace-loader with regex matching and a callback for dynamic replacement.

Basically I'll use env.SOME_VARIABLE in my code and search/replace it with the variable value. For some reason I couldn't make the regex work with the \w to match for word characters and used [a-zA-Z_] instead.

{
    test: /resources.*\.js$/,
    loader: 'string-replace-loader',
    options: {
        search: 'env\.([a-zA-Z_]+)',
        replace(match, p1, offset, string) {
            return process.env[p1];
        },
        flags: 'g'
    }
}

Notes

Since it is text replacement I cannot simply assign env variable values to vue component data properties as it would be interpreted as a variable:

// E.g. given env `COMMIT_HASH=some_hash`

data() {
    return {
        /**
         * WRONG:
         * this would be parsed as
         *     hash: some_hash
         * leading to an
         *     Uncaught ReferenceError: some_hash is not defined
         */
        hash: env.COMMIT_HASH,

        /**
         * RIGHT:
         * wrap string to be replaced in single/double quotes so after
         * replacement it became a string literal assignment.
         *     hash: "some_hash"
         */
        hash: "env.COMMIT_HASH",
    };
},

Upvotes: 1

Related Questions