Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

express – config file gets called called before app or server files which returns env variable to be undefined

in my app the server.ts is the entrypoint which serves the app in port. all app.use is done in the app.ts file where the dotenv is called. As far as I know you are only supposed to call dotenv once and the entire app should have the variables. But for some reason the config file gets loaded first before the app or server files which is when the env variable process.env.WHITELIST_ORIGINS starts with undefined. I cannot understand the reason why this is happening. Is there any way to fix this without having to call dotenv again from the config file

server.ts

import http from 'http'
import { Socket } from 'socket.io'
import app from './app'
import { setIO } from './config'

const server = http.createServer(app)

const io = setIO(server)

io.on('connection', function (socket: Socket) {
  console.log('New client connected with id => ', socket.id)

  socket.on('disconnect', function (reason): void {
    console.log('A client disconnected with id => ', socket.id, ' reason => ', reason)
  })
})

const port = process.env.PORT || 8095

server.listen(port, () => {
  console.log(`App running`)

})

console.log('server call')

app.ts

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import compression from 'compression'
import cors from 'cors'
import dotenv from 'dotenv'
import express, { Application } from 'express'
import helmet from 'helmet'
import { errorHandler, verifyToken } from './middleware'
import router from './router'

dotenv.config()

const app: Application = express()

app.use(compression())
app.use(cors())
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(helmet())
app.use(verifyToken)
app.use('/', router)
app.use(errorHandler)

console.log('app call')

export default app

config/socket-config.ts

import { Server as HttpServer } from 'http'
import { Server } from 'socket.io'
// import dotenv from 'dotenv'
// dotenv.config() - If this is called here it works fine.

let _io: Server

const whitelistOrigins = process.env.WHITELIST_ORIGINS
console.log("whitelistOrigins", whitelistOrigins) // This logs undefined

console.log('whitelistOrigins', whitelistOrigins)

export const setIO = (server: HttpServer): Server => {
  _io = new Server(server, {
    cors: {
      origin: whitelistOrigins,
      methods: ['GET', 'POST'],
      credentials: true,
    },
    allowEIO3: true,
  })
  return _io
}

export const getIO = () => {
  return _io
}

console.log('socket call')

Here is the order of how console logs

whitelistOrigins undefined
socket call
app call
server call
App running

>Solution :

The issue is described in detail within the dotenv docs

When you run a module containing an import declaration, the modules it imports are loaded first, then each module body is executed in a depth-first traversal of the dependency graph, avoiding cycles by skipping anything already executed.

For this reason, dotenv provides a specific import that executes config() within its body.

import 'dotenv/config';

It’s best to add this as close to your app’s entry-point as possible. I would place this first in server.ts

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading