Environment variable with dotenv and TypeScript

Viewed 100851

I create this .env file:

TYPE=xxx
HOST=xxx,
PORT=xxx,
USERNAME=xxx,
PASSWORD=xxx,
DATABASE=xxx,

in my file I use in this way:

import * as dotenv from "dotenv";

dotenv.config();

export const typeOrmConfig: TypeOrmModuleOptions = {
    port: process.env.PORT
}

but i can use only my port variable from .env file and i cannot use rest of the variables, can someone tell me why i can't use rest of my vars?

9 Answers

Actually you have define the path of the .env file

Try like this

import * as dotenv from "dotenv";
dotenv.config({ path: __dirname+'/.env' });

Try this also

require('dotenv').config({ path: __dirname+'/.env' });

Change the path of .env file as required

reference : https://www.npmjs.com/package/dotenv

If you get undefined value and if you use ES6, you need to import it as follows (.env file must be in project root directory) :

How do I use dotenv with import?

  1. Preload dotenv: node --require dotenv/config index.js (Note: you do not need to import dotenv with this approach)
  2. Import dotenv/config instead of dotenv (Note: you do not need to call dotenv.config() and must pass options via the command line or environment variables with this approach)
  3. Create a separate file that will execute config first as outlined in this comment on #133

You have to import in your project's app.ts file (first) Example with express:

app.ts

//here
import 'dotenv/config'

import express from 'express'
import { userRouter } from './routes/user'

const app = express()

app.use(`/users`, userRouter)
app.listen(process.env.PORT, () => {
    console.log(`running`)
})

Now use it anywhere in your project

It is always good to read the documentation

My project has eslint setup, so I have to disable the import/first rule

/* eslint-disable import/first */
require('dotenv').config();

import Koa from 'koa';

import { Logger } from './utils/loggers';
import { app } from './app';

const LOGGER = Logger();
const port = parseInt(process.env.PORT as string, 10) || 8081;

const server = (server: Koa) => {
  server.listen(port, () => {
    LOGGER.info(`> Ready on http://localhost:${port}`);
  });
};

server(app());

We can also use:

import 'dotenv/config'

but

require('dotenv').config({path:path_to_dotenv});

is more flexiable.

You could use built-in NestJs way to handle this (ConfigModule).

Configuration | NestJs

// main.ts

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { InventoriesModule } from './inventories/inventories.module';
import typeORMConfig from './config/database.config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { PrismaModule } from './prisma/prisma.module';

@Module({
  imports: [
    ConfigModule.forRoot(), // load .env file
    TypeOrmModule.forRoot(typeORMConfig()),
    InventoriesModule,
    PrismaModule
  ],
})
export class AppModule { }


// ./config/database.config

import { TypeOrmModuleOptions } from '@nestjs/typeorm';

export default function (): TypeOrmModuleOptions {
    return {
        'type': 'mysql',
        'host': process.env.DB_HOST,
        'port': 3306,
        'username': process.env.DB_USERNAME,
        'password': process.env.DB_PASSWORD,
        'database': process.env.DB_DATABASE,
        'entities': ['dist/**/*.entity{.ts,.js}'],
        'synchronize': false
    }
};

This is Nestjs way how to set environment variables:

 npm install @nestjs/config

That packages internally uses dotenv package which puts together all environment variables in your machine.

app.module.ts

// configModule chooses the .env file, configservice extract the settings
import { ConfigModule, ConfigService } from '@nestjs/config';


@Module({
  imports: [
    // list your project's modules
    ConfigModule.forRoot({
      // this is set so we do not have to reimport the ConfigModule all over the place into other modules
      isGlobal: true,
      envFilePath: `.env.${process.env.NODE_ENV}`,
    }),
    // Notice we are not using TypeOrmModule.forRoot({})
    // we set this to get access to ConfigService through dependency injection system
    TypeOrmModule.forRootAsync({
      // this tell DI system, find the configService which has all of the config info
      inject: [ConfigService],
      useFactory: (config: ConfigService) => {
        return {
          type: 'sqlite',
          database: config.get<string>('DATABASE'),
          synchronize: true,
          entities: [User, Report],
        };
      },
    }),

I had this issue too, it was driving me nuts until I realized I copied pasted environment values from a YAML file which does not have the same format than the .env file.

One uses :, the other uses =.

If it helps another developer soul :-)

You must import the dotenv and execute dotenv.config() at the top most of root file.

As early as possible in your application, require and configure dotenv. Ref:dotenv-npm

Related