Reputation: 1543
I am trying to use the dotenv
NPM package and it is not working for me. I have a file config/config.js
with the following content:
'use strict';
var dotenv = require('dotenv');
dotenv.load();
console.log('config');
I have another file .env
at the root of my application folder. I also have an environment variable TWILIO_ACCOUNT_SID
.
This is the process I go through while trying to use the environment variables in a certain function:
$ node
> require('./config/config.js');
config
{}
> process.env.TWILIO_ACCOUNT_SID
undefined
I defined the TWILIO_ACCOUNT_SID
in my .env file but as soon as I try to output the value in my console, I get an error stating that the variable is undefined.
I will be very grateful for any support in troubleshooting this issue.
Upvotes: 106
Views: 180931
Reputation: 1
If you want to use.env file in your node js project. Hear all stapes.
1 Stape: install dotenv package:
npm install dotenv.
2 Stape: creates .env file in the root directory. 3 Stape: import dotenv in the main file at the top of the line.
import dotenv from "dotenv"
4 Stape: after importing all package config the dotenv like that :
dotenv.config({path: './env'});
It's the path of the env file path: './env'
5 Stape: Added dotenv as an experimental in package.json in the script.
"scripts": {"dev": "nodemon -r dotenv/config --experimental-json-modules src/index.js"}
if come to any error replace this line "dev": "nodemon -r dotenv/config --experimental-json-modules src/index.js" with this "dev": "nodemon -r dotenv/config src/index.js"
My index.js file:
import dotenv from "dotenv";
import express from "express";
const app = express();
dotenv.config({
path: "./.env",
});
in the script dev line src/index.js this is the path of your index.js file.
NOW YOU CAN ABLE USE YOU .env FILE GLOBAL. THANKS;
Upvotes: -1
Reputation: 688
In my case also, every time I tried to get a key from the .env file using process.env.DB_HOST, it returned undefined.
So, My problem was I am using 2 different environment for local and for prod like .env.local and .env.prod and in my package.json file i defined
"start": "set NODE_ENV=prod && node index.js",
"start:dev": "set NODE_ENV=dev && nodemon index.js"
so here the trick was when i am accessing NODE_ENV variable like
require('dotenv').config({path: __dirname + `/.env.${process.env.NODE_ENV}`})
my address is becoming 'MY_FILE_PATH.env.dev '
Its hard to see the space after .env.dev. So whenever you are using 2 diff env make sure to remove spaces in pacakge.json like this:
"start": "set NODE_ENV=prod&&node index.js",
"start:dev": "set NODE_ENV=dev&&nodemon index.js"
I hope it will help.
Upvotes: -1
Reputation: 1
I faced the same problem when I moved my server code to a nested folder since dotenv is looking in the root directory by default. On top of that, I was using ES6 module imports so I had to do the following:
import dotenv from "dotenv";
dotenv.config({ path: "/path/to/envfile/.env" });
It did the trick in my case.
As an extra tip, in case you want to use __dirname
to get the path, if you had set
type: "module"
in your package.json file like I did, you won't be able to use __dirname. What I did, was to go to the directory where .env file was and create a new file named envpath.cjs (pay attention to .cjs):
// envpath.cjs
// a file to return the path as a string
const envpath = __dirname;
module.exports = envpath;
Then in my working module I had:
import dotenv from "dotenv";
import envpath from "../envpath.cjs";
dotenv.config({path: envpath + "/.env"});
Upvotes: 0
Reputation: 1
var dotenv = require('dotenv').config({path: 'D:\\site-checker\\.env'});
console.log(dotenv);
result---
{
parsed: {
PORT: '5000',
HOST: 'http://localhost',
DATABASENAME: 'test_sitechecker',
NODE_ENV: 'test'
}
}
Here what I struggled with is my path was wrong, it should with two backslashes and should point exactly where your .env
file is.
Upvotes: 0
Reputation: 887
If this is a react native project using dotenv, the .env file might not change because it's being cached in an IOS build. In XCode, do a Product > Clean Build Folder every time you update the .env
Upvotes: 0
Reputation: 563
In my case, the same codebase that reads my .env file on my MacBook Pro didn't read the .env file on my staging server ubuntu 18.04, so i tried @user3006381 advice and i noticed the code is trying to look for .env file in my user directory "/home/myusername/.env" and not in "/home/myusername/project/.env", if you have any idea why that is happening please add a comment.
Upvotes: 1
Reputation: 192
i had similar problem. i solved it by trim. Please check, path.resolve may add additional space to end of path.
var path = require('path');
const envPath = path.resolve(process.cwd()+'/config','.env.'+process.env.NODE_ENV).trim()
require('dotenv').config({ path: envPath })
my package script is like this to use multiple .env:
"scripts": {
"start": "set NODE_ENV=development && nodemon ./bin/www",
"prod": "set NODE_ENV=production && node ./bin/www"
},
Upvotes: 0
Reputation: 609
In my case, I was creating a vscode extension in which
__dirname
was referring to something like d:\extension\my_extension\out
.
the root folder was my_extension
, but __dirname
was pointing to my_extension\out
so I fixed it by writing
require('dotenv').config({path: __dirname.slice(0,-3)+'/.env'});
Upvotes: 0
Reputation: 10590
There's a lot of confusion about this topic and in these answers. I'm not surprised, that no single answer was accepted. Hopefully yet.
The answer by Basheer indeed solves most of the problems. However, there are few things you still need to know. Especially, if you're coming, like me, from frontend background and wants to add secrets to your frontend. Possibly, related to the introduction of some Server-Side Rendering (SSR) logic in the app.
Most probably you've seen this code in your webpack
settings in a frontend app to solve the issue, as a frontend developer.
/* Custom webpack properties. */
const dotenv = require('dotenv-webpack');
module.exports = {
plugins: [
new dotenv(), // Handle environemntal variables on localhost, but on the Server-Side Rendering (SSR). There's no access to "process.env" on the browser.
],
};
Now, it'll work out fine, if you render on the server (SSR) across your app if the .env
file is in the root of your project. However, it might not work if you have some custom server-related settings. An example of such situation is Angular Universal
, Nuxt.js
handles this much easier in which require('dotenv').config()
in your next.config.js
and makes you good to go. That's due to difference in philosophies between how Angular
and Vue.js
are handling SSR. To get Angular Universal
app from Angular
that's just 1 command, but the SSR app isn't as nicely organized as Nuxt.js
. It comes with a price that to generate Nuxt.js
app from Vue.js
, you basically have to generate a new Nuxt.js
project and copy files due to quite some differences between Nuxt.js
and Vue.js
setup. Don't know how React
/Next.js
and Svelte
/Sapper
solves this, but if similarly to Angular
then you also might consider reading further.
Now, you've some server-related logic in a separated folder called server and let say the file is called main.ts
. Maybe apart SSR in that file, you can also have sending mail (nodemailer
?) logic. Then you'd like to use process.env
, but apparently it doesn't work, even though you have the logic defined in webpack
. That's where the require('dotenv').config();
is needed, even if you're using different syntax for import (such as import { Express } from 'express';
for example), require('dotenv').config();
will work like that. Don't feel confused. As long as .env
is in the root of your app (don't confuse with server
folder) and the variables have correct syntax inside that file, e.g.
[email protected]
MAIL_HOST=smtp.mydomain.com
MAIL_PORT=587
It'll work.
Last scenario, in the SSR app you realised that to host this app you need something called Serverless/Cloud Functions/FaaS. Here, I know only Firebase
scenario. In your project, to deploy such app you might have functions
folder, from which you deploy the SSR app to the Cloud Functions for Firebase
, in this example. What a surprise, on a deployment mail is not working and after hours of figuring out what's happening in the logs you can see process.env.VARIABLE_NAME returning undefined
. The reason is that as of today the CLI cannot merge files from other locations and indeed the .env file has to be manually copied to the functions folder. Once copy/paste the .env
file to functions
and deploy, it'll work.
What you can use for debugging is one of those:
console.log(require('dotenv').config());
console.log(require('dotenv').config({debug: true}));
However, be careful with your secrets, because these will be revealed when your .env
setup will be done. Trying to access one of the secrets and trying to log its value in the logs might be more secure option. Especially, if you have many secrets and don't want to rewrite all.
Hope so this one post will cover most of the scenarios.
Upvotes: 5
Reputation: 89
This is how i fix my issue
Intially had this in .env of the root of my project
const db_port = 90101
const db_host="localhost"
const db_username="name"
const db_password="pwd"
const db_name="db"
And all my env variables where undefined.
I fixed it by removing all the const and using just key=value insted of const key="value"
db_port = 90101
db_host=localhost
db_username=name
db_password=pws
db_name=db
Upvotes: 2
Reputation: 621
I've noticed something here myself.
I've defined .env
correctly, etc and i'd defined DATABASE_URL
in there but despite doing so another DATABASE_URL was being referenced, perhaps a global environment variable is referenced if it exists?
Anyhow, I found that when I defined TEST
and CONNECTION_STRING
within .env
these both were referenced correctly where as DATABASE_URL
continues to not be.
Thanks,
Michael
Upvotes: 0
Reputation: 557
On some operating sytems (mostly some linux distros, I am looking at you raspbian), .env files don't work. rename them and import that
Upvotes: 0
Reputation: 125
My code structure using is as shown below
-.env
-app.js
-build
-src
|-modules
|-users
|-controller
|-userController.js
I have required .env at the top of my app.js
require('dotenv').config();
import express = require('express');
import bodyParser from 'body-parser';
import mongoose = require('mongoose');
The process.env.PORT works in my app.listen function. However, on my userController file not sure how this is happening but my problem was I was getting the secretKey value and type as string when I checked using console.log() but getting undefined when trying it on jwt.sign() e.g.
console.log('Type: '+ process.env.ACCESS_TOKEN_SECRET)
console.log(process.env.ACCESS_TOKEN_SECRET)
Result:
string
secret
jwt.sign giving error
let accessToken = jwt.sign(userObj, process.env.ACCESS_TOKEN_SECRET); //not working
Error was
Argument of type 'string | undefined' is not assignable to parameter of type 'Secret'.
Type 'undefined' is not assignable to type 'Secret'.
My Solution: After reading the documentation. I required the env again in my file( which I probably should have in the first place ) and saved it to variable 'environment'
let environment = require('dotenv').config();
console logging environment this gives:
{
parsed: {
DB_HOST: 'localhost',
DB_USER: 'root',
DB_PASS: 'pass',
PORT: '3000',
ACCESS_TOKEN_SECRET: 'secretKey',
}
}
Using it on jwt.sign not works
let accessToken = jwt.sign(userObj, environment.parsed.ACCESS_TOKEN_SECRET);
Hope this helps, I was stuck on it for hours. Please feel free to add anything to my answer which may help explain more on this.
Upvotes: 5
Reputation: 350
I had the same problem. I had created a file named .env, but in reality the file ended up being .env.txt.
I created a new file, saved it in form of 'No Extension' and boom, the file was real .env and worked perfectly.
Upvotes: 1
Reputation: 1298
Working Solution:
If you are using webpack (which you definitely should), use a very handy plugin dotenv-webpack which solves the issue of reading environment variables from .env
file
Make sure
.env
is in root directory of your project.
Steps to install the plugin:
npm i -D dotenv-webpack
webpack.config
file: const Dotenv = require('dotenv-webpack');
module.exports = {
...
plugins: [
new Dotenv(),
...
],
...
};
Now you can call any environment variable defined in .env
file using process.env
in any js
file
Upvotes: 5
Reputation: 13
const dotenv = require('dotenv'),
path = require('path')
dotenv.config({path: path.join(__dirname, '../.env')})
Upvotes: 1
Reputation: 63
I cloned a repo from Github and went through every one of the suggestions here. After a lot of frustration, I realized that npm install
did not install any of the modules and my node_modules
folder was empty the whole time.
QUICK FIX:
1) delete your node_modules
folder
2) delete your package-lock.json
3) run npm install
Upvotes: 1
Reputation: 43
If you use "firebase-functions" to host your sever-side-rendered application, you should be aware of this one:
error: Error: ENOENT: no such file or directory, open 'C:\Codes\url_shortener\functions\.env'
Means you have to store the .env file in the functions folder as well.
Found this one by:
console.log(require('dotenv').config())
Upvotes: 1
Reputation: 11
is dotenv installed in your project?
Try to install it using npm install dotenv
in your project.
Once it is installed load it in any files where you need it using const env = require('dotenv').config()
.
You can then use in any line where you need to. For example to call port from .env use: process.env.PORT
Upvotes: 1
Reputation: 1271
I am using NodeJS on windows 10. I used process.env.var-name to access the variables but failed because it gives me windows path variables as a JSON object, so I installed dotenv ( npm install dotenv ). dotenv gets process envirnoment variables from your project's .evn file
Upvotes: 6
Reputation: 2513
For React apps created with the create-react-app
template, you don't need to use dotenv
directly. react-scripts
does that for you.
Simply creates a .env
file in the top level directory of your project and add all your envs there, but notice that they MUST start with REACT_APP
prefix, otherwise they will be ignored.
More details in their documentation. I just spent a couple of hours dealing with this and hope it will save you some time.
Upvotes: 3
Reputation: 115
I spent a lot of time going through these fixes. I was developing locally and just had to restart the server because the .env file isn't hot reloaded.
Upvotes: 1
Reputation: 998
If you are facing this problem it could be that the environment variable(s) is added/loaded after the file that requires the specific variable
const express = require('express');
const app = express();
const mongoose = require('mongoose');
const dotenv = require('dotenv');
const morgan = require('morgan');
const passport = require('passport'); //you want to use process.env.JWT_SECRET (you will get undefined)
dotenv.config();
in the above case, you will get undefined
for the process.env.JWT_SECRET
So the solution is that you put dotenv.config()
before const passport = require('passport');
const express = require('express');
const app = express();
const mongoose = require('mongoose');
const dotenv = require('dotenv');
const morgan = require('morgan');
dotenv.config();
const passport = require('passport'); //you want to use process.env.JWT_SECRET (you will get the value for the enviroment variable)
Upvotes: 2
Reputation: 15367
In my case, every time I tried to get a key from the .env
file using process.env.MY_KEY
, it returned undefined
.
I suffered from this problem for two hours just because I named the file something like keys.env
which is not considered to be a .env
file.
So here is the troubleshooting list:
The filename should be .env
(I believe .env.test
is also acceptable).
Make sure you are requiring it as early as possible in your application using this statement require('dotenv').config();
The .env
file should be in the root directory of your project.
Follow the "file writing rules" like DB_HOST=localhost
, no need to wrap values in double/single quotes.
Also, check the documentation of the package on the NPM site.
Upvotes: 164
Reputation: 861
Had the same issue recently. Check your .env
file and use equal sign not colon. Here's an example:
key=value
instead of:
key:value
Upvotes: 24
Reputation: 891
I solved this using:
require('dotenv').config({path: __dirname + '/.env'})
or with an absolute path:
C:\\asd\\auhsd\\.env
If it does not find the .env
file, it will return undefined
.
Upvotes: 76
Reputation: 411
I solved this just renaming the file to .env to y file was named config.env , when I renamed to .env , it works.
Upvotes: 1
Reputation: 11
I had to literally use no name for the .env file, just have the .env extension and save the file like that and it worked.
Upvotes: 1
Reputation: 21
In my case, I've created a wrapper JS file in which I have the logic to select the correct variables according to my environment, dynamically.
I have these two functions, one it's a wrapper of a simple dotenv functionality, and the other discriminate between environments and set the result to the process.env object.
setEnvVariablesByEnvironment : ()=>{
return new Promise((resolve)=>{
if (process.env.NODE_ENV === undefined || process.env.NODE_ENV ==='development'){
logger.info('Lower / Development environment was detected');
environmentManager.getEnvironmentFromEnvFile()
.then(envFile => {
resolve(envFile);
});
}else{
logger.warn('Production or Stage environment was detected.');
resolve({
payload: process.env,
flag: true,
status: 0,
log: 'Returned environment variables placed in .env file.'
});
}
});
} ,
/*
Get environment variables from .env file, using dotEnv npm module.
*/
getEnvironmentFromEnvFile: () => {
return new Promise((resolve)=>{
logger.info('Trying to get configuration of environment variables from .env file');
env.config({
debug: (process.env.NODE_ENV === undefined || process.env.NODE_ENV === 'development')
});
resolve({
payload: process.env,
flag: true,
status: 0,
log: 'Returned environment variables placed in .env file.'
});
});
},
So, in my server.js file i only added the reference:
const envManager = require('./lib/application/config/environment/environment-manager');
And in my entry-point (server.js), it's just simple as use it.
envManager.setEnvVariablesByEnvironment()
.then(envVariables=>{
process.env= envVariables.payload;
const port = process.env.PORT_EXPOSE;
microService.listen(port, '0.0.0.0' , () =>{
let welcomeMessage = `Micro Service started at ${Date.now()}`;
logger.info(welcomeMessage);
logger.info(`${configuration.about.name} port configured -> : ${port}`);
logger.info(`App Author: ${configuration.about.owner}`);
logger.info(`App Version: ${configuration.about.version}`);
logger.info(`Created by: ${configuration.about.author}`);
});
});
Upvotes: 1
Reputation: 2885
Save yourself some troubleshooting time and log your require call, like so:
console.log(require('dotenv').config())
You should see an error with more detailed info on the problem.
Upvotes: 72