In my Nest.js based application, I'm trying to use one configuration file to define all configuration for an application.
The configuration.json file looks like this:
{
"environment": "development",
"backendPort": 8080,
"appRootPath": ".",
...more configuration...
}
And in my Nest.js application's main.ts is:
import { NestFactory } from "@nestjs/core";
import configuration from "../configuration.json";
import { AppModule } from "./app.module";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(configuration.backendPort);
}
bootstrap();
I have enabled TypeScript's resolveJsonModule feature as mentioned in TypeScript 2.9 Release notes and VS code successfully recognized the import and provides IntelliSense and type checking.
But when I try to start the app via
ts-node -r tsconfig-paths/register src/main.ts
I get an error:
(node:5236) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'backendPort' of undefined
at d:\CodeDev\NestCMS\backend\src\main.ts:10:36
at Generator.next (<anonymous>)
at fulfilled (d:\CodeDev\NestCMS\backend\src\main.ts:4:58)
at <anonymous>
at process._tickDomainCallback (internal/process/next_tick.js:228:7)
at Function.Module.runMain (module.js:695:11)
at Object.<anonymous> (d:\CodeDev\NestCMS\backend\node_modules\ts-node\src\_bin.ts:177:12)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
(node:5236) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:5236) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Is there a way to define application port in an elegant way like I tried?
I don't want the port number to be hard-coded in the main.ts file. I want it to be configurable by some option to allow me to deploy the same application build to different environments where the only thing differing will be the configuration.json.
Yes. Use this - https://docs.nestjs.com/techniques/configuration part of NestJS docs to create ConfigService. You can replace dotenv with json if you want. Then:
import {NestFactory} from '@nestjs/core';
import {ConfigService} from 'src/config/config.service';
import {AppModule} from './app.module';
let bootstrap = async () => {
const app = await NestFactory.create(AppModule);
const configService: ConfigService = app.get(ConfigService);
await app.listen(configService.getPort);
};
bootstrap();
Now you can inject ConfigService in most part of your code + whle loading you can validate it using Joi. Hope this helps.
Workaround in 2021:
main.ts, NestJS v8.0.4
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ConfigService } from '@nestjs/config';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const configService: ConfigService = app.get<ConfigService>(ConfigService);
const port = configService.get('APP_PORT');
await app.listen(port);
}
bootstrap();
Profit!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With