I have dotenv configurated at the beginning of my entry file. I also have a bit after an import that import the book.route.js file.
import express from 'express';
import dotenv from 'dotenv';
import morgan from 'morgan';
// Load environment variables
console.log('dotenv');
dotenv.config({ path: './config/config.env' });
const app = express();
const PORT = process.env.PORT;
const ENV = process.env.NODE_ENV;
if (ENV === 'dev') {
app.use(morgan('dev'));
}
const apiPrefix = '/v1';
// Route files
import bookRoute from './routes/book.route.js';
// Mount routers
app.use(`${apiPrefix}/book`, bookRoute);
app.listen(PORT, () => {
console.log(`Server is running in ${ENV} mode on port ${PORT}`);
});
The content of book.route.js is :
import express from 'express';
import { getAllBooks } from '../controllers/book.controller.js';
const router = express.Router();
router.get('/all', getAllBooks);
export default router;
In this file I notably import getAllBooks
from book.controller.js
that have this content:
import httpStatus from 'http-status-codes';
import dbUtil from '../utils/db.util.js';
const getAllBooks = async (req, res) => {
const result = await dbUtil.query('SELECT * FROM book');
res.status(httpStatus.OK).json(result.rows);
};
export { getAllBooks };
Finally, in book.controller.js
I import db.util.js that have the following content:
import pg from 'pg';
console.log('db.util');
const pool = new pg.Pool({
user: process.env.DB_USER,
host: process.env.DB_HOST,
database: process.env.DB_DATABASE,
password: process.env.DB_PASSWORD,
port: process.env.DB_PORT
});
export default pool;
Now my issue is that the file db.util.js
is read before the dotenv
configuration even if the import is later in the code. I have put a console log in the entry file and in the db.util.js
file and I get the following output:
db.util
dotenv
Because of that I cannot use environment variables in db.util.js
because this file is read before the dotenv
configuration.
Does someone had an issue like this before?
In ES modules, the import statements are always executed first, regardless of where they are placed in the script. This means that your db.util.js
will be evaluated first before your entry file is executed.
If you still want to access the same environment variables instantiated in your entry file, you can make your pool lazy (wrapping your pool in a nullary function),
// db.util.js
import pg from 'pg';
console.log('db.util');
const getPool = () => new pg.Pool({
user: process.env.DB_USER,
host: process.env.DB_HOST,
database: process.env.DB_DATABASE,
password: process.env.DB_PASSWORD,
port: process.env.DB_PORT
});
export default getPool;
And whenever you need the pool, for e.g. in book.controller.js
:
const result = await dbUtil().query('SELECT * FROM book');