How to use variable substitution in Frontend js applications like backend applications?
Complex applications developed with react, vue, angular or other javascript based frameworks has the same problem or requirement as backend applications (java, nodejs, python, etc): How read configurations?
Here I will list some some approaches to work with configurations for javascritpt frameworks, from simple to manged solutions. Some of them are used for backend applications.
#1 Global variables
As we are talking about javascript frameworks, just create global var at the startup of your application and this will be available for all your scripts:
<html>
<header>
<meta charset="utf-8">
<title>This is title</title>
<script>
var myVar = "global value"; // Declare a global variable
</script>
<script>
console.log("from another script:"+myVar);
</script>
</header>
<body>
Hello world
</body>
</html>
Of course, a harcoded url in the source code is not an option but understand this is the entry point to the next approaches. Almost all of them are based on this approach or do something similar.
#2 Webpack
Webpack provide us with several mechanisms like DefinePlugin
new webpack.DefinePlugin({
API_BASE_URL: JSON.stringify(process.env.API_BASE_URL)
})
The DefinePlugin is a direct text replacement. Webpack will look for the identifier and replace it with the given string. The following example illustrates how that works.
You could use this variable as if it were a global variable :
$.ajax({
type: "GET",
url: API_BASE_URL+'/odds?date=2019-01-19',
dataType: 'json',
success: function (data) {
...
}
});
}
Here more webpack mechanisms : https://stackoverflow.com/a/40416826/3957754
Advantages:
- Simple way to set or define several variables and use them throughout the application.
- Using a C.I server like jenkins you could set all your configurations and build your artifact an then deploy it:
export API_BASE_URL=http://awesome.api.com
export ENDPOINT_DETAIL=/detail
export ENDPOINT_FAVOURITE=/favourite
export MODULES=user,guest,admin,configure
npm run build
Disadvantages
- Variables are injected at build stage. Changes in your configurations will require a new build and redeploy of your application.
#3 Properties from SCM, Database or File System
Check this answer:
- What is the best way to change application configurations in a CI environment
#4 Centralized and manageable configuration
The main idea is put all your configurations, settings or properties in one site and all your applications must retrieve this values in a secure way. Nowadays the most common technique to retrieve this configuration from final application is perform an http request to an api rest published by the platform.
This kind of platforms are the perfect partners for a microservice architecture. Also I was able to use it for microfrontends.
Here some platforms:
-
configurator
- This is a nodejs application that allows you to Centralize and Management configurations of all your applications.
-
zookeeper
- http://www.therore.net/java/2015/05/03/distributed-configuration-with-zookeeper-curator-and-spring-cloud-config.html
-
Spring Cloud
- https://www.baeldung.com/spring-cloud-configuration
- This is a java spring framework functionality in which you can create properties file with configurations and configure your applications to read them.
-
Consul
- Consul is a service mesh solution providing a full featured control plane with service discovery, configuration, and segmentation functionality.
- doozerd, etcd
You can use one of these platforms in conjunction with webpack approach. So instead to manually environment variables export you can consume the api rest at build stage in webpack or with your C.I server like jenkins.
Advantages
- Everything commented above.
Disadvantages
- Unique properties file or manual environment exports are easy and fast to configure versus doing it on another server different to the application.
#5 /settings in your web
Asumming that your web is served at http://myapp.com, you could publish another endpoint like http://myapp.com/settings. This endpoint will return all the settings required by your microfrontend or web application at CLIENT SIDE using AJAX.
In your javascript application, in the entry point (commonly App.js in react, vue, etc), I mean before render mechanisms, you can consume http://myapp.com/settings and expose as global vars to your application. You can also save it in one of the storages available like, localStorage, sessionStorage, etc
Advantages
- Changes in your configurations are ready to use without rebuild the application. Just perform a page refresh to execute again the entry point in your javascript.
- You can use the approach #3 in the backend controller of your /settings
Disadvantages
- Pre hardcoded variables are instantly loaded versus an ajax http request.