Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading of port number for Nest.js application from JSON module

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.

like image 202
Klímačka Avatar asked Jun 30 '18 15:06

Klímačka


2 Answers

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.

like image 66
Vladyslav Moisieienkov Avatar answered Oct 08 '22 14:10

Vladyslav Moisieienkov


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!

like image 7
Alex Avatar answered Oct 08 '22 13:10

Alex