I am working on my first NestJS application, which was working fine with hardcoded database connecting string in app.module.ts
.
But then as per our requirements, I had to pick the database config values from environment files. For that, I followed the configuration documentation on the nestjs documentation website - https://docs.nestjs.com/techniques/configuration
But the issue is that I need to use the .env variables inside the same file for database connection, which is failing.
Here is my original code that was working fine:
@Module({
imports: [
MongooseModule.forRoot(`mongodb+srv://myusername:mypassword@myhost.net?retryWrites=true&w=majority&db=dbname`, { useNewUrlParser: true, dbName: 'dbname' }),
ProductModule,
CategoryModule,
],
controllers: [
AppController,
HealthCheckController,
],
providers: [AppService, CustomLogger],
})
Now, I wanted to pick those DB values from .env files which are like local.env
, dev.env
etc. depending on the environment. Now, my this code is not working:
@Module({
imports: [
ConfigModule.forRoot({ envFilePath: `${process.env.NODE_ENV}.env` }),
MongooseModule.forRoot(`mongodb+srv://${ConfigModule.get('DB_USER')}:${ConfigModule.get('DB_PASS')}@myhost.net?retryWrites=true&w=majority&db=dbname`, { useNewUrlParser: true, dbName: 'dbname' }),
ProductModule,
CategoryModule,
],
controllers: [
AppController,
HealthCheckController,
],
providers: [AppService, CustomLogger],
})
1. Keeping using ConfigModule
You need to set NODE_ENV
in npm scripts so that it can be used to load an env file based on the env.
"scripts": {
"start:local": "NODE_ENV=local npm run start"
"start:dev": "NODE_ENV=dev npm run start"
}
Now you can just use the ConfigModule
:
@Module({
imports: [
ConfigModule.forRoot({ envFilePath: `${process.env.NODE_ENV}.env` }),
MongooseModule.forRoot(`mongodb+srv://${process.env.DB_USER}:${process.env.DB_PASS}@myhost.net?retryWrites=true&w=majority&db=dbname`, { useNewUrlParser: true, dbName: 'dbname' })
...
})
2. Using dotenv
npm install dotenv
Add some scripts to your package.json
to set what env you are in.
"scripts": {
...
"start:local": "NODE_ENV=local npm run start"
"start:dev": "NODE_ENV=dev npm run start"
}
Import dotenv
in main.ts
file. Make sure you do it at the top of the file.
require('dotenv').config({ path: `../${process.env.NODE_ENV}.env` });
3. Using env-cmd
You can use env-cmd
npm package.
npm install env-cmd
And add some commands for different envs in package.json
, for example:
"scripts": {
...
"start:local": "env-cmd -f local.env npm run start"
"start:dev": "env-cmd -f dev.env npm run start"
}
...
Now you can use the env variables, for example:
MongooseModule.forRoot(`mongodb+srv://${process.env.DB_USER}:${process.env.DB_PASS}@myhost.net?retryWrites=true&w=majority&db=dbname`, { useNewUrlParser: true, dbName: 'dbname' })
process.env.MONGO_CONNECTION_STRING
Update:
To overcome the env set command problem in different platforms, you can install cross-env
package.
npm install -D cross-env
And update the scripts:
"scripts": {
"start:local": "cross-env NODE_ENV=local npm run start"
"start:dev": "cross-env NODE_ENV=dev npm run start"
}