Environment sharing across libraries with Angular Injection tokens.

Loïc Combis
ShopStyle Engineering
6 min readFeb 13, 2021

Hi there! Let’s look at how you — as we do at ShopStyle — can use Angular injection tokens to share your application-specific environment with Nx libraries and build complex, sophisticated apps that scale like a charm👌.

Angular developer with red hoody.

As your app grows, you will face a dilemma on how to manage your increasing amount of features. 🤯 A solution would be to properly segment your angular modules within the app. But what if for example, you want to create another application? The chances are high that at least some of the features/behaviors are similar between the apps. It doesn’t matter if it’s only the design or entire modules. Would you copy/paste the code, reimplement everything? 😖💩 Of course not!

Remember, a good engineer is a lazy one.

Instead, you will create beautiful and reusable libraries!! 🎉 But as you already know, with great power comes great responsibility. Your libraries MUST stay isolated. Meaning you cannot import anything from the actual app into the library. This is a one-way street.

But then… How do I use my application-specific configuration without compromising library isolation? Well, let’s see a quick and efficient way to deal with environment variables with Angular Injection Tokens.

Although Angular supports libraries out of the box (see the documentation), it is less convenient when it comes to sharing features across multiple apps. For this tutorial, we’ll be using Nx.

What is Nx?

Nx extensive dev tools logo

Nx is a suite of powerful, extensible dev tools to help you architect, test, and build at any scale — integrating seamlessly with modern technologies and libraries while providing a robust CLI, caching, dependency management, and more.It has first-class support for many frontend and backend technologies, so its documentation comes in multiple flavours.

This is how Nx describes itself on its website. It is basically a set of tools allowing you to manage several applications and their dependencies in one single codebase called “Monorepo”.

Let’s get started

Setup

$ node --versionv10.11.0$ npm --version6.14.7$ npx --version 6.14.7$ nx --version11.2.12

🚨 Note: You can easily install npx & nxusing npm install -g npx nx.

Create an Nx Workspace

$ npm install -g create-nx-workspace$ npx create-nx-workspace@latest
create-nx-workspace command flow
$ cd environment-token/

You can run nx list in your repo to check the list of plugins installed in the workspace. As we created an empty project, we should only have base plugins installed:

Nx workspace installed plugins

Add Angular schematics and create an application.

$ npm install --save @nrwl/angular

Let’s run nx list again:

Nx workspace installed plugins after adding angular

🚨 Note: In addition to Angular, Nx also installed Cypress which is an End to End testing framework. We use it at ShopStyle and it’s actually very powerful as it allows you to test complete user stories. 💯 👍

Create the applications and libraries

Let’s first generate two applications that will share common libraries.

$ nx g @nrwl/angular:application first-app$ nx g @nrwl/angular:application second-app

The actual setup for each project doesn’t really matter for this tutorial. But here is what configuration I used.

Angular app initial configuration

Now let’s create two shared libraries. The first one will be called “home” and will contain a shared home.component. The second will be the called “environment” and will hold the Injection Token and the environment interface definition.

// Create the "home" library
$ nx g @nrwl/angular:lib home
// Add the "home" component to the "home" library and export it.
$ nx g @nrwl/angular:component home --export --project home
// Create the environment library.
$ nx g @nrwl/angular:lib environment

We’re all set!! 😍 Your project structure should look like the following at this point (2 applications + e2e apps, 2 libraries with a home component).

Monorepo structure

Create the injection token

Under ./libs/environment/src/lib/ create the two following files:

environment.interface.ts

Here we’re defining the contract that the token value must respect (so we don’t get surprises when using the token).

environment.token.ts

🚨 Note: Think of the token as a wildcard. The token holds a value that we don’t know yet but will be provided at runtime.

Let’s export those two files. Under ./libs/environment/src/index.ts paste the following.

We just created the Injection Token. 🎉 Awesome!! Hold on tight, just a few more steps to complete!

Provide the token

We need to let Angular know about this token so we can use it in components. Under both ./apps/first-app/src/app/app.module.ts and ./apps/second-app/src/app/app.module.ts provide the injection token as follows:

Angular now knows what value use when the token is injected into a component/service. We can add custom properties to the value to match the environment.interface .

→ Replace the content of./apps/first-app/environments/environment.ts with the following:

→ Replace the content of./apps/second-app/environments/environment.ts with the following:

And boom!! That’s how you provide an injection token to an angular app.

Use the token in a library

Our environment token is now ready to be used. So let’s use it in our home.component! 😃

To inject it into the component, replace the content of ./libs/home/src/lib/home/home.component.ts with:

Add a little bit of HTML to display the values. In home.component.html (of the same folder), add :

And a little bit of style of course (in home.component.scss):

Finally, let’s use our home component in the applications.

In both ./apps/first-app/src/app/app.component.html & ./apps/second-app/src/app/app.component.html replace the content with:

<environment-token-home></environment-token-home>

🚨 Note: This assumes you already imported the home.module in both app.module.ts when providing the environment token.

Let’s see the results:

$ npm start first-app
$ npm start second-app

And voila!! 😉

I hope you liked this tutorial! Feel free to fork the repo and play with it. If you did please clap 😊👏! Otherwise, any constructive comment will be welcomed!

You can check out my other stories on medium (more to come soon). I’ll also try to post every new story to my Twitter account.

Sources

Github repo: https://github.com/loic-combis/environment-token

Nx website: https://nx.dev/

Angular Libraries: https://angular.io/guide/creating-libraries

Angular Injection Tokens: https://angular.io/api/core/InjectionToken

Monorepos: https://www.atlassian.com/git/tutorials/monorepos

More Links

Personal website: https://loic-combis.github.io/

Twitter: https://twitter.com/CombisLoic

Medium: https://loic-combis.medium.com/

Github: https://github.com/loic-combis

ShopStyle main website: https://www.shopstyle.com/

More about what we do at ShopStyle: https://about.shopstyle.com/

Pixabay header image: https://pixabay.com/photos/red-matrix-matrix-matrix-code-5031496/

--

--