DEV Community

Cover image for Oh boy, this is exciting!
José Pablo Ramírez Vargas
José Pablo Ramírez Vargas

Posted on

Oh boy, this is exciting!

So last Saturday and Sunday I took the time to finally complete the set of features I wanted to deliver in v2.0.0 of wj-config.

So I did that on Saturday and started re-working the React v18.2.0 example I have in the repository to make sure all was working as expected. While doing this and updating the project's README, I realized of a few things that led me to work on higher API to help comply with DRY. This took the Sunday evening.

Quick Screenshot of the React Sample

Image description


Anyway, the end result is quite interesting. Let me put it like this: Have you ever had the need to have configuration values vary depending on things like the browser the user is using? (Honest question, I am no backend developer). Well, now you'll be able to!

One new feature, conditional inclusion of data sources allows you to run abritrary checks, including things like checking for browser capabilities. I'll give you a preview of the example code I wrote for the README:

import wjConfig, { Environment } from "wj-config";
import mainConfig from './config.json';

// Chromium-based browsers.
var isChromium = !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime);

export default await wjConfig()
    .addObject(mainConfig)
    .name('Main')
    .addFetchedConfig('/config.chromium.json')
    .when(e => isChromium, 'Chromium')
    .build();
Enter fullscreen mode Exit fullscreen mode

Per-Region Or Per-Tenant Configuration

This was the original feature I wanted to complete before releasing v2.0.0 as a production package.

Have you ever had this need to have different production configuration files per region or per tenant, and maybe even for pre-production environments too? Have you done this combination of files yourself, producing stuff like config.prod.tenantA.json, config.prod.tenantB.json, config.pre-prod.tenantA.json and config.prod.tenantB.json? And so on for other environments?

Well, with Per-Trait Configuration this multiple configuration file creation will no longer be needed. Here's an example preview taken from the upcomming README. It basically computes the combination you need on the spot:

import wjConfig, { Environment, EnvironmentDefinition } from "wj-config";
import myTraits from './myTraits.js';

// Easiest to show with NodeJS as we already have an environment object with all variables ready.
// The ENV_TRAITS environment variable would contain the desired trait value assigned when deploying.
const currentEnvDef = new EnvironmentDefinition(process.env.NODE_ENV, process.env.ENV_TRAITS);
const env = new Environment(currentEnvDef, ['MyList', 'OfPossible', 'Environments']);
// Main configuration file.  Boolean argument defines if the file must exist.
const mainConfig = loadJsonFile('./config.json', true);
// Classic per-environment configuration.
const perEnvConfig = loadJsonFile(`config.${env.current.name}.json`, false);
export default await wjConfig()
    .addObject(mainConfig)
    .name('Main')
    .addObject(perEnvConfig)
    .name(env.current.name)
    .addComputed(() => loadJsonFile('config.amr.json', false))
    // The second parameter is just the data source name.
    .whenAllTraits(myTraits.Americas, 'Americas') // <-- It conditions the recently added data source.
    .addComputed(() => loadJsonFile('config.eur.json', false))
    .whenAllTraits(myTraits.Europe, 'Europe')
    .addComputed(() => loadJsonFile('config.asa.json', false))
    .whenAllTraits(myTraits.Asia, 'Asia')
    .includeEnvironment(env)
    .build();
Enter fullscreen mode Exit fullscreen mode

Oh, if you don't know, wj-config works for React and NodeJS the same way. The only differences you see is things like fetching config files in React, but loading files in NodeJS.

Still working on the final details of the documentation and making sure the TypeScript types are all updated and reflecting the new API properly. Maybe by next weekend we'll have a commit and a new NPM package upload. Fingers crossed!

Top comments (0)