One of the most common misunderstandings with Vue.js deals with how to define endpoints for backend services that are not resolvable during build time. In this post I’m going to describe how to define dynamic configurations like backend endpoints so they can be determined at runtime.
Vue.js applications are typically designed to access backends through REST APIs whose endpoints are defined as environment variables in a project’s
.env file. What many people don’t realize is that when you run
npm run build to compile a Vue.js project, those environment variables get hardcoded into the production code output by a process called webpack. Unless you intend to rebuild the webpack bundles every time backend endpoints change then those endpoints should be dynamically loaded, instead.
Avoid this hardcode anti-pattern:
Lets say your Vue app accesses backend services from many different views and components. It makes sense to define backend endpoints as VUE_APP_ environment variables in
.env so that they could be globally accessed using the
process.env object. However, when you run
npm run build webpack compiles each of those references into the production ready code under
dist/. Now, your deployable package is effectively hardcoded to use the set of endpoints loaded from
.env during build time. If users want to deploy your code with bindings to their own set of backend endpoints then they have to search for “VUE_APP_” variables in the minified code under
dist/ and replace them with the values that point to their own backend services. Yuck!
You could automate this with things like AWS CloudFormation templates that completely automate production deployment but the routines for finding and replacing hardcoded backend configurations in production code would be kludgy and slow. More importantly, changing production code in this way is a security liability since it precludes you from adding Subresource Integrity (SRI) checks in webpack which allows browsers to verify that files they fetch are delivered without unexpected manipulation.
Define dynamic configurations under
A far better way to resolve configurations during runtime is to save them under your
public/ folder. Vue designates the
public folder as the place to put static assets that should be simply copied to
dist/ without going through webpack. This also allows you to access a runtime configuration file with an HTTP request just like you would access any other API.
For example, you could define backend endpoints in
public/runtimeConfig.json then load that file using a
src/main.js), like this:
Then you can distribute those runtime configurations globally across all your Vue components using Vue mixins, like this:
By resolving runtime configurations from the
public/ folder instead of
.env, your application will deploy faster and can benefit from the security features provided by webpack’s Subresource Integrity (SRI) checks.
For more information about how I applied this technique to one of my own projects, see https://github.com/awslabs/aws-media-insights-engine/pull/147.
Please provide your feedback to this article by adding a comment to https://github.com/iandow/iandow.github.io/issues/18.