When building large scale applications that deploy to a variety of environments with different audiences, we often need the ability to show/hide certain features in the UI. The Angular CLI provides us an
environment.ts file that can help us quite a bit with this but limited to static values. What if we want to change these at dynamically at build time, lets say we have Chef building our app to a variety of different environments and it needs to flip some things on and off in its config. Dealing with a static environment typescript file is gonna be kind a pain. There is a very popular node package called config (original right?) that lets us do some really tricky stuff like config inheritance, supports a variety of different formats and allows us to set variables at runtime. This article could just focus on that topic alone but I wanted to get a bit more specific with it in terms of feature toggling. So how would we do this?
Setting up config
First lets install config from npm like:
npm i config --D
We are only using this at build time, so make sure to install as a dev dependency. Next, we need to setup some basic config files, so create a folder called
config in the root of your project and lets add a few config files:
This is a bit verbose and in dev, we typically want everything, lets simplify this to something like this:
in this example we use a wildcard to indicate that all features are on.
Next lets say we don’t want to show zoo in production, lets make another config file for production and set that to false.
Integrating the config
We’ve got these awesome config files but how do we actually get these inside the app so that we can read them out at runtime? Lets create a simple script that will read out the config and write a config file to our environments folder for us:
I put files that are custom scripts in a folder called
~/tools/build . If you don’t follow this structure, you will need to update your paths in the script. Now lets wire this script up to run before
build steps in our npm scripts:
"build": "npm run build:config && ng build",
"build:config": "node tools/build/config.js"
Now anytime our build runs, we will create this file. When you setup your CI, to swap out the config files you just need to pass a different a different node environment variable. Read more about this and how to set runtime properties on the config package docs.
Now, we have a file in our
environment/config.ts folder that has a map of all our custom config options. Make sure to ignore this file from git!
Toggling the UI
Now that we have this config in our code, we can read it out with a directive and choose to render or not different components. A simple directive to do that looks something like this:
then in our UI, we just hook it up like:
Pretty cool? In the application I built, I had a header that would read out the router links and show them in a nav list. I hooked up my features to reflect the route paths so I could automatically bind the feature toggle to them like this:
Angular CLI gives us great options for basic config, but we can take it to a whole other level using packages like config. We can automate steps in our build to read out those configs and write files and then have directives read out those objects really easily for a nice feature toggling feature!