Creating a config in NestJS using a barrel file
I've been on the search for the perfect way to create a config for our NestJS applications. In my opinion, Angular has done a great job here where your build environment selects which environment.ts
file to use. What's really great about this is that it allows our IDEs to pick up the environment model and tell us what keys exist.
In this article, I'm going to run through a few points:
- What the current method looks like
- Why I'm not a fan of the current method
- An alternative way that works incredibly well
The current method
If you look at the techniques in the NestJS documentation you'll see that you import the ConfigModule
and inject the ConfigService
to access the config variables.
One of the problems I have here is that you have to type the config and remember to change your config structure. You'll see that the standard way to create the config is as follows:
But if you ever change the database
key in this then you'll need to remember to change the DatabaseConfig
as well.
Why I don't like it
The example above describes why I'm not a fan of this structure. The problem is that you have to modify the model and the types separately.
I'd prefer a way where you create a config and the type is automatically determined. What's great about this is that the IDE would autocomplete the structure of the config when we import it.
An alternative method
The alternative method uses a barrel file to create the config. Check this article to see what a barrel file does. I usually create a folder called config
in my src
directory and then my index.ts
file looks as follows:
And one of these "feature" config files would look as follows:
I like to add the paths to the tsconfig.json
file to make imports easier,
Here you can see that you enter the path to your config folder and you can then use @config
to import the config. So in code you have a few options:
A downside to this approach
As in most cases, there are some downsides to using this approach. The main problem is when you set the tsconfig.json
path so that you can use @config
instead of the path to the config folder (eg. import { Config } from '../../../../config';
).
If you build the Nest application and try to run the built .js
project, it'll give you an error that the @config
module is not found. The best way to resolve this is to create a tsconfig bootstrap file. This issue on Github describes the solution best.
Final thoughts
There are many ways to get a config up and running in a Nest application. I like the barrel file because the typing is set up automatically when you create the objects and values in the config. By using the barrel file I know that dotenv
runs before the objects are created so the process.env
object is populated with the values from dotenv
.
The ConfigModule
has been been changing over the last few years in the Nest documentation. I have no doubt that this method will become deprecated at a stage so keep an eye out in the docs for new changes.
Until then, I hope this helps!