Appearance
<div style="display: none;" hidden="true" aria-hidden="true">Are you an LLM? You can read better optimized documentation at /guides/vue/plugins/config.md for this page in Markdown format</div>
Overview
Config plugin's main goal is to enhance and improve upon ecommercen's frontend code modularity by introducing configuration files. In this doc, we'll glance over its features, abilities and take a deep dive into its inner workings, giving a thorough documentation of its functionality.
Check feature/vue-langs-and-configs in adveshop4 repository.
The architecture
The core plugin consists of two webpack modules. TheconfigPlugin.js and configService.js. In``configService.jsyou'll find all the functions necessary for config's ability to work. Essentially, all plugin's logic is contained withinconfigService.js. The configPlugin.js is a shell, or a wrapper if you like, ofconfigService.jsin order to register the config plugin as an actualVue` plugin.
We intentionally split up the code in plugin & service, to make the plugin usable, even outside Vue instance. Yes you heard it right! You can actually use the config plugin anywhere in js as long as you import the configService.js![^1]
Along with configPlugin.js and configService.js we also provided a loader (index.js in assets/vue/config ) that will load any files matching the pattern *.conf.json automatically within the assets/vue/config directory. That said, because of the size of the code base, and the multiple Vue instances involved, we felt it was appropriate to provide a way for different instances to override the default assets/vue/config (of which from now on, we'll refer to as common) contents. To achieve this, we've distributed a config/ directory along with index.js for each instance (client) and registered it in each instance's vueapp.js as a clientBundle.
The config plugin is designed in a way to support multiple configurations through bundles, A bundle is essentially a group of configurations that's usually loaded using the index.js loader. By default, there are two bundles. the common bundle which contains all configurations from assets/vue/config and the client bundle which contains all configurations from the active vueapp.js (which by default, it's assets/main/vue/v2/config).
Here's a hierarchical directory tree structure to help visualize config's architecture
[assets]
|-------[vue]
| |-------[config]
| |---configPlugin.js
| |---configService.js
| |---index.js
|-------[front]
| |-------[config]
| |---index.js
|-------[design]
| |-------[config]
| |---index.js
|-------[main]
|-------[config]
| |---index.js
|-------[v2]
|-------[config]
|---index.js "Why the index.js? Can't it just be a single config.json instead?" The concept behind index.js loader is to enable a way of grouping configurations of similar purpose together. We call those namespaces. Each *.conf.json file is its own namespace. You can have as many namespaces as you like as long as they sit directly next to index.js. Simply create a new <namespace>.conf.json file, and it'll be automatically loaded thanks to index.js. From then on, you can refer to that namespace by supplying ConfigService.get's namespace parameter with your <namespace>.[^2]
The Search Flow
In this section, we'll provide some insight of how the plugin searches the config entries given a specified key.
From the The Architecture paragraph, we explained what bundles and namespaces are. Essentially bundles are groupings of different configuration instances which enable client specific overrides, and namespaces are groupings of similar purpose configuration items. To analyze in depth how config searches in bundles and namespaces we need to take a look at ConfigService.get
The ConfigService.get method
Parameters:
key(Which key should the config look for)namespace(optional) (in Which namespace should the config look for)
If no namespace is provided, the config will try to fetch the requested config item by searching under all available namespaces within a bundle. Although this can be considered a "feature", we highly discourage the use of ConfigService.get without supplying the namespace, as it can lead to strange results when multiple identical config keys are found within different namespaces.
Upon calling ConfigService.get the plugin will first attempt to look under client bundle. If the key requested is nowhere defined under client bundle, the plugin redoes the search under common bundle.
if the plugin fails to find any result, it'll return null. Alternatively, (if it finds a valid entry) it will attempt return the result after parsing[^3] it.
Features
We added some features for config that we believe will improve its usability.
Feature: window variable references
There's a way to reference window variables as long as those are called before the ConfigService.get call. Instead of supplying the config entry with a hardcore value, insert an object of this format:
json
"myConfigKey": {
"config.type": "references.variable.window",
"config.value": "myWindowVariable"
}Where myConfigKey is your config key, and config.value the value you want to reference. For example, say you want to create a currentLang config item, and want to reference window.advAppData.languageAbbr as the value. In this case the you'll normally input the key as you'd do but instead of hard coding a value, you'd supply it with a config instruction object like this:
json
"currentLang": {
"config.type": "references.variable.window",
"config.value": "advAppData.languageAbbr"
} This can be very useful when you want to make pointers to variables supplied from php and set them up as config items.
Feature: config item references
Additionally, we also added the ability to reference a different config item. Here is the full format of ``config instruction object` for config item references:
json
"myConfigKey": {
"config.type": "references.setting.config",
"config.value": {
"config.key": "myConfigKeyPointer",
"config.namespace": "myConfigNamespacePointer"
}
} Alternatively, (and although not recommended) if you want to only reference the key you can set config.namespace to false or simplify specify the key of the config directly in config.value like so:
json
"myConfigKey": {
"config.type": "references.setting.config",
"config.value": "justMyConfigKeyPointerThatIShouldAvoidDoing"
} You might want to use this in cases where you want to provide extra modularity by splitting your code config values into multiple config keys but also want to give a default value/behavior for all those new config keys.[^4]
Service methods
Here's a full list of all methods config plugin provides. Params with * are required.
| Method | Params | Description |
|---|---|---|
ConfigService.replaceLoadedBundle | Replaces currently loaded bundle data with new ones | |
ConfigService.getLoadedBundles | bundleName*, payload* | Gets the currently loaded bundles and their data, where the bundleName param is the name of the bundle that its data will be replaced and payload param the new bundle data |
ConfigService.get | key*, namespace | See The Search Flow paragraph |
Footnotes
[^1]: When using the config plugin as a webpack module, it will only have access to assets/vue/config (common) bundle, However, you can setup your own bundle for your own grouped modules by creating your own config/ bundle and setting it as a client bundle path with ConfigService.replaceBundlePath. [^2]: When supplying the namespace param, the config will only look under that namespace you've supplied, and it'll do that search both for common and client bundles. See The Search Flow paragraph for more info. [^3]: See Features paragraph for why there's a need to parse the result and uses that provides. [^4]: All search flow rules from The Search Flow apply.