12

I am trying to access some environment variables using process.env that were loaded by dotenv.

My folder structure :

.env
src
-- - server.js

My server.js configuration :

(...)
import auth from './middleware/auth'
import dotenv from 'dotenv'
dotenv.load({
    path: '../',
    silent: process.env.NODE_ENV === 'production'
})
auth()
// Instantiate app
const app = express();

The file where I try to access process.env variable :

(...)
module.exports = function() {
        console.log("env", process.env.MONGODB_URI)
        var options = {};
        options.jwtFromRequest = ExtractJwt.fromAuthHeader()
        options.secretOrKey = process.env.JWT_SECRET

Which logs env, undefined, and then crashes with

TypeError: JwtStrategy requires a secret or key

Even if I move .env into src (same directory as server) and remove path in config, it fails.

softcode
  • 4,358
  • 12
  • 41
  • 68

6 Answers6

8

It appears that when you specify the path, you need to make it full:

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

.env being your file

yBrodsky
  • 4,981
  • 3
  • 20
  • 31
  • update your question and show us your folder structure, where you have the .env file and where are you trying to call it. – yBrodsky Feb 16 '17 at 20:36
  • 1
    folder structure is the first code sample, and I'm trying to call it in `server.js` as in the 2nd code sample – softcode Feb 16 '17 at 20:37
  • If server.js is inside a subfolder my code should work. What's the output of __dirname? – yBrodsky Feb 16 '17 at 20:40
  • `console.log(__dirname)` doesn't output anything because nothing runs in `server.js` – softcode Feb 16 '17 at 20:42
  • What do you mean? put it somewhere, if that file is being included it should output. – yBrodsky Feb 16 '17 at 20:45
  • If I log it in `auth.js`, it outputs the right directory. If it's in `server.js`, nothing gets outputted because the app crashes before it reaches the statement – softcode Feb 16 '17 at 20:49
  • then you need to fix the error that's causing the crash first. Check the JWTStrategy and provide the needed secret. – yBrodsky Feb 16 '17 at 20:53
  • yes that's what I'm trying to use `process.env` for, is to get that secret – softcode Feb 16 '17 at 20:55
  • Does middleware run before `server.js`? I put a log at the top of `server.js` and it gets printed after the log in `auth.js` – softcode Feb 16 '17 at 21:10
  • I don't know how's your setup. Comment out the JWT thing until you can have the env working. Debug __dirname and see what it outputs. – yBrodsky Feb 17 '17 at 12:28
  • @iamwhitebox what exactly? The path needs to be full. Either using `__dirname` or `process.cwd()` – yBrodsky Jun 17 '20 at 12:10
  • ```var path = require('path')``` and ```const env_path = path.join(__dirname, 'path/to/.env')``` please, don't just use string concatenation – William Le Nov 18 '22 at 14:00
5

Try this; this should work.

import {} from 'dotenv/config'
import somethingElse from 'somethingElse'
...
[the rest of your code]

This works because of how ES6 modules imports modules.

If you want to dig into more. Please refer this. https://hacks.mozilla.org/2015/08/es6-in-depth-modules/

As a summary :

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.

Hope this will help someone.

Chamika
  • 51
  • 1
  • 1
1

I'm using require('dotenv').config() on my main nodejs .js entry file and it works just fine.

From the docs:

Path

Default: .env

You can specify a custom path if your file containing environment variables is named or located differently.

require('dotenv').config({path: '/custom/path/to/your/env/vars'})

Omri Luzon
  • 3,975
  • 6
  • 20
  • 29
  • I know that your problem is probably not related to the dotenv module, but I still gave a good answer. Your app probably crashes because something else. – Omri Luzon Feb 16 '17 at 21:40
  • 1
    Your answer is a link to docs. That was the first thing I read. It's not a good answer sry – softcode Feb 16 '17 at 21:51
  • My answer **includes** a link to the documentation, this is how answers should be in stackoverflow. If your problem was an error thrown because of something else, you should at least mention it, and not just open a new question. – Omri Luzon Feb 16 '17 at 22:55
  • 1
    Your answer literally paraphrases docs. The only non-doc sentences are the ones introducing the docs. Furthermore the next question I asked has nothing to do with this one. Look at the comments to this question to understand the difference before flagging as duplicate. – softcode Feb 16 '17 at 22:57
  • I'm not allowed to ask you questions in my answer. That's what was possible to answer to you with the minimal information you presented. Not going to make this any longer. – Omri Luzon Feb 16 '17 at 23:05
0

use may use:

require('dotenv').config({ path: require('find-config')('.env') })

This will recurse parent directories until it finds a .env file to use.

You can also alternatively use this module called ckey inspired from one-liner above.

.env file from main directory.

# dotenv sample content
USER=sample@gmail.com
PASSWORD=iampassword123
API_KEY=1234567890

some js file from sub-directory

const ck = require('ckey');

const userName = ck.USER;     // sample@gmail.com
const password = ck.PASSWORD; // iampassword123
const apiKey   = ck.API_KEY;  // 1234567890
Sachi
  • 1,286
  • 1
  • 10
  • 17
0

If you're using a mono-repo which uses a single .env file across multiple packages/work-spaces you can use the following to find the root .env file.

Install the find-up package from npm: https://www.npmjs.com/package/find-up

import find from 'find-up';

export const findEnv = () => find.sync(process.env.ENV_FILE || '.env');
Josh Dando
  • 1,647
  • 14
  • 9
0

you have to set the dotenv configs at the very top level of your app:

import dotenv from 'dotenv'
dotenv.load({
    path: '../',
    silent: process.env.NODE_ENV === 'production'
})
(...)
import auth from './middleware/auth'

auth()
// Instantiate app
const app = express();

The order of imports in this case matters since you are loading the environment variables.

Amirsalar
  • 648
  • 9
  • 18