Fonto Why & How: Why is my configuration cyclic!?

Why is my configuration cyclic!?

In this weekly series, Martin describes a question that was raised by a Fonto developer, how it was resolved and why Fonto behaved like that in the first place. This week, a developer gets an error caused by a cyclic dependency in their configuration!

A developer just updated something in a random file, after which the editor refused to start. They saw this error:

Error: Configuration value "preferred-locales" was not set.
    at ConfigurationManager.get (configurationManager.ts:2039:10)
    at eval (localizationManager.ts:8:2)
    at Module platform-linked/fontoxml-localization/src/localizationManager.ts (main.js:13505:1)
    at __webpack_require__ (main.js:22911:42)
    at eval (operationsManager.ts:7:103)
    at Module /platform-linked/fontoxml-operations/src/operationsManager.ts (main.js:14165:1)
    at __webpack_require__ (main.js:22911:42)
    at eval (browserSelectionManager.ts:7:99)
    at Module platform-linked/fontoxml-browser-selection/src/api/browserSelectionManager.ts (main.js:2923:1)
    at __webpack_require__ (main.js:22911:42)

The last thing they did was adding a dependency from a modal to a new component that was offered by the platform. The configuration value preferred-locales was set in the config/configuration.ts file. This file was not recently changed.

Let’s take a look at the contents of the config/configuration.ts file. It looked something like this:

import configurationManager from 'fontoxml-configuration/src/configurationManager.js';
import MyConfigurableModal from 'configurable-modals/src/MyConfigurableModal';

configurationManager.set('my-modal', MyConfigurableModal);
...

It looks like they have a feature that requires a configurable modal. After asking how they used it, they explained the editor is used by multiple organizations. Some of these organizations have a requirement to replace a ‘normal’ modal with a totally new one. By making this modal configurable using the configurationManager they hoped to reuse code.

The reason why this error happens is that some platform code depends on configuration values being set. However, as those values are usually set in the application’s config/configuration.ts file, they can not be read before that file is evaluated. By importing the platform code inside of configuration.ts, we’ve created an impossible cycle where the platform code needs configuration.ts to run first, but configuration.ts needs the platform code to run first.

Because of this we consider it bad practice in general to set configuration values to values that are not strings, numbers, booleans or simple JavaScript objects. This is why all of our configuration options that refer to for example React components actually use a ComponentName that is registered through the UiManager. This prevents cyclic dependencies.

To solve their overridable modal use case, the developer could input strings into the configurationManager and choose the modal depending on the configured value where it is used. Those files are evaluated after all configuration values have been set, so it’s safe to import any API there:

// in code that uses the modal
import MyConfigurableModal from './src/MyConfigurableModal';
import MyConfigurableModal2 from './src/MyConfigurableModal2';

const MODAL_BY_NAME = {
  ‘my-modal’ : MyConfigurableModal
  ‘my-modal-2’ : MyConfigurableModal2
}

const ConfiguredModal = MODAL_BY_NAME[configurationManager.get('my-modal') ];
…
return <ConfiguredModal>...</ConfiguredModal>;

Another error message that is caused by a similar cycle looks like Error: Configuration value "fonto-debug-build" was not set. This is commonly caused by using XPath to build a configuration value.

These errors can also be caused by files that the config/configuration.ts file depends on. In general it is good practice to limit the dependencies in the config/configuration.ts file as much as possible.

I hope this explained how Fonto works and why it works like that. During the years we built quite the product, and we are aware some parts work in unexpected ways for those who have not been with it from the start. If you have any points of Fonto you would like some focus on, we are always ready and willing to share! Reach out on Twitter to Martin Middel or file a support issue!

Stay up-to-dateFonto Why & How posts direct in your inbox

Receive updates on new Fonto Why & How blog posts by email

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top