Dotenv unable to overwrite key value pair - javascript

I am trying to implement environment variables using dotenv on my node server, however I am having trouble loading them in from the .env file which is located in the root. When I run const dotenv = require("dotenv").config({debug: true}); I encounter the following message: "USER" is already defined in process.env and will not be overwritten
Additionally when I try to load the page, it encounter the following error: ER_DBACCESS_DENIED_ERROR: Access denied for user ''#'localhost' to database '_api'
.env:
USER=root
PASS=

From the Variables overwriting/priority.
Environment variables that are already set will not be overwritten, that means that the command line variables have a higher priority over all those defined in env files;
And this What happens to environment variables that were already set?
We will never modify any environment variables that have already been set. In particular, if there is a variable in your .env file which collides with one that already exists in your environment, then that variable will be skipped. This behavior allows you to override all .env configurations with a machine-specific environment, although it is not recommended.
If you want to override process.env you can do something like this:
const fs = require('fs')
const dotenv = require('dotenv')
const envConfig = dotenv.parse(fs.readFileSync('.env.override'))
for (const k in envConfig) {
process.env[k] = envConfig[k]
}

As of version 16.0.1, you can override process.env values with require('dotenv').config({ override: true }).
.env:
access_token=aa
index.js:
require('dotenv').config({ override: true })
process.env.access_token = bb
console.log(process.env.access_token) //bb

Related

Type error: expected parameter accessToken in react Js

Error screenshot:
While running react project by npm start, it shows error related to contentful.js. why does the package shows these types of error? I attached the screenshot with this post. How to solve this issue?
.env file
CONTENTFUL_ACCESS_TOKEN: process.env.REACT_APP_CONTENTFUL_ACCESS_TOKEN,
config file
import SETTINGS from "../env";
const contentfulClient = contentful.createClient({
space: SETTINGS.CONTENTFUL_SPACE,
accessToken: SETTINGS.CONTENTFUL_ACCESS_TOKEN
});
Do i need to enter api token anywhere?
.env
const SETTINGS = {
LANDING_BLOG_POSTS: "",
ICON_TYPE: "svg",
CONTENTFUL_SPACE: process.env.REACT_APP_CONTENTFUL_SPACE,
CONTENTFUL_ACCESS_TOKEN: process.env.REACT_APP_CONTENTFUL_ACCESS_TOKEN,
CLOUDINARY_UNSIGNED_PRESET: process.env.REACT_APP_CLOUDINARY_UNSIGNED_PRESET,
CLOUDINARY_CLOUD_NAME: process.env.REACT_APP_CLOUDINARY_CLOUD_NAME,
SERVER_7CHIP: process.env.REACT_APP_SERVER_7HIP || false,
HARD_CODED_USERNAME: process.env.REACT_APP_TOKEN_USERNAME || "**********",
HARD_CODED_PASSWORD: process.env.REACT_APP_TOKEN_PASSWORD || "************",
FACEBOOK_API_ID: process.env.REACT_APP_FACEBOOK_APP_ID,
FACEBOOK_PAGE_TOKEN: process.env.REACT_APP_FACEBOOK_PAGE_TOKEN,
FACEBOOK_PAGE_ID: process.env.REACT_APP_FACEBOOK_PAGE_ID || "**************",
FACEBOOK_SERVER_CALL: true
};
export default SETTINGS;
Since your code got as far as getting into the createClient function, that tells me your SETTINGS object is loading (otherwise you'd get a TypeError from accessToken: SETTINGS.CONTENTFUL_ACCESS_TOKEN). However the error message says that no accessToken was provided.
Therefore SETTINGS.CONTENTFUL_ACCESS_TOKEN is undefined, null or an empty string. Since that value is set to process.env.REACT_APP_CONTENTFUL_ACCESS_TOKEN this probably means that you have not set your REACT_APP_CONTENTFUL_ACCESS_TOKEN environment variable before running the program.
Try setting that environment variable to your access token value, then running the program.
If that works, you might want to reconsider the approach. You have an "env" file but is getting values from system environment variables. Usually you have an "env" file so that you can hardcode values into it, not rely on them being set externally. If they have to be set externally you might as well not use an "env" file and just use process.env.VARIABLE_NAME directly in your code.
Note that if you hardcode access tokens or other private information in an "env" file, you should add that file to .gitignore so that passwords/keys are not stored in git.
You created .env.development file same location as package.json file.
hope, this will help you.
For me, I had the variables in the .env file in the source directory and just had to source it. I ran . ./.env and that sorted out the error in my case.
In my case environment variables weren't accessible, because I created the .env file when my server was already running. I had to restart the server and everything worked like a charm.

How do I setup environment variables for multiple environments?

I have a Next.js application and I have currently got this next.config.js setup to access my .env file when working locally, which works fine:
// Initialize doteenv library
require("dotenv").config();
module.exports = {
webpack: config => {
// Fixes npm packages that depend on `fs` module
config.node = {
fs: "empty"
};
/**
* Returns environment variables as an object
*/
const env = Object.keys(process.env).reduce((acc, curr) => {
acc[`process.env.${curr}`] = JSON.stringify(process.env[curr]);
return acc;
}, {});
/** Allows you to create global constants which can be configured
* at compile time, which in our case is our environment variables
*/
config.plugins.push(new webpack.DefinePlugin(env));
return config;
}
};
However when the app is built on the live (platform.sh) environment I need to access platform.sh variables instead of my .env variables. Platform.sh provide this code snippet as an example:
function read_base64_json(varName) {
try {
return JSON.parse(new Buffer(process.env[varName], 'base64').toString());
} catch (err) {
throw new Error(`no ${varName} environment variable`);
}
};
// A simple variable.
let projectId = process.env.PLATFORM_PROJECT;
// A JSON-encoded value.
let variables = read_base64_json('PLATFORM_VARIABLES');
However I am unsure where to use this and how to it working so that locally it uses my .env file and on the live environment to use the platform.sh variables. What is the best way to do this?
In your webpack.config you can reconfigure plugin section like this
plugins: [
new webpack.DefinePlugin({
VARIABLE_NAME:
process.env.NODE_ENV === "production"
? VARIABLE_PRODUCTION_VALUE
: VARIABLE_LOCAL_VALUE
})
]
You can use VARIABLE_NAME anywhere in your app and it will change depending on the environment.
dotenv overrides your environment variables with the contents of the file. You probably want to rm .env in your build hook.

Difference between export SOME_ENV_VAR=KEY and SOMEOTHER_ENV_VAR=KEY in dotenv?

I am relatively new to Node.js. I want to export environment variables from .env file to my javascript files. In order to do that I am using dotenv.
Which method should I use to export the environment variables to my main javascript files ( say- app.js)
export GEOCODER_API_KEY= someKeyXYZ // inside .env file
GEOCODER_API_KEY_1 = someKeyXYZ // inside .env file
One thing to note is that upon console.log(process.env) in the app.js, the GEOCODER_API_KEY_1 shows up as env variable, but not GEOCODER_API_KEY? Why is that. What use is the first one then, since it is not accessible?
A more confusing thing is that:
var options = {
provider: 'google',
httpAdapter: 'https',
apiKey: process.env.GEOCODER_API_KEY,
formatter: null
}; // this works
... // some javascript
console.log(process.env.GEOCODER_API_KEY) //SHOWS UNDEFINED
I basically want to export the API_KEY (unrestricted) safely to my project. Is there a catch that I might be missing?
The correct way of writing portable variable declarations in an .env file is:
FOO=BAR
This is - when you use dotenv implementations like dotenv.
require('dotenv').config();
console.log(process.env);
When using export in .env in a Unix/Bash environment (what you have probably seen in the wild) - sourcing the file will yield differences concerning the scope of the declared variable:
# .env
export GEOCODER_API_KEY=someKeyXYZ
GEOCODER_API_KEY_1=someKeyXYZ
# main.sh
#!/bin/bash
. ./.env
./subprocess.sh
# subprocess.sh
#!/bin/bash
echo "GEOCODER_API_KEY": $GEOCODER_API_KEY
echo "GEOCODER_API_KEY_1": $GEOCODER_API_KEY_1
./main.sh
GEOCODER_API_KEY: someKeyXYZ
GEOCODER_API_KEY_1:

Setting environment variables in Gatsby

I used this tutorial: https://github.com/gatsbyjs/gatsby/blob/master/docs/docs/environment-variables.md
Steps I followed:
1) install dotenv#4.0.0
2) Create two files in root folder: ".env.development" and ".env.production"
3) "follow their setup instructions" (example on dotenv npm docs)
In gatsby-config.js:
const fs = require('fs');
const dotenv = require('dotenv');
const envConfig =
dotenv.parse(fs.readFileSync(`.env.${process.env.NODE_ENV}`));
for (var k in envConfig) {
process.env[k] = envConfig[k];
}
Unfortunately, when i run gatsby develop, NODE_ENV isn't set yet:
error Could not load gatsby-config
Error: ENOENT: no such file or directory, open 'E:\Front-End Projects\Gatsby\sebhewelt.com\.env.undefined'
It works when I set it manually:
dotenv.parse(fs.readFileSync(`.env.development`));
I need environment variables in gatsby-config because I put sensitive data in this file:
{
resolve: `gatsby-source-contentful`,
options: {
spaceId: envConfig.CONTENTFUL_SPACE_ID,
accessToken: envConfig.CONTENTFUL_ACCESS_TOKEN
}
}
How to make it work?
PS: Additional question - As this made me think, I know I shouldn't put passwords and tokens on github, but as netlify builds from github, is there other safe way?
I had a similar issue, I created 2 files in the root ".env.development" and ".env.production" but was still not able to access the env file variables - it was returning undefined in my gatsby-config.js file.
Got it working by npm installing dotenv and doing this:
1) When running gatsby develop process.env.NODE_ENV was returning undefined, but when running gatsby build it was returning 'production' so I define it here:
let env = process.env.NODE_ENV || 'development';
2) Then I used dotenv but specify the filepath based on the process.env.NODE_ENV
require('dotenv').config({path: `./.env.${env}`});
3) Then you can access your variables for your config:
module.exports = {
siteMetadata: {
title: `Gatsby Default Starter`,
},
plugins: [
`gatsby-plugin-react-helmet`,
{
resolve: `gatsby-source-contentful`,
options: {
spaceId: `${process.env.CONTENTFUL_ID}`,
accessToken: `${process.env.CONTENTFUL_TOKEN}`,
},
},
],
}
You should only use env files when you're comfortable checking those into git. For passwords/tokens/etc. add them to Netlify or whatever build tool you use through their dashboard.
These you can access in gatsby-config.js & gatsby-node.js via process.env.ENV_VARIABLE.
You can't access environment variables added this way in the browser however. For this you'll need to use .env.development & .env.production.
I really dislike the .env.production file pattern, our build system sets up and uses env variables and having extra build steps to write those into a file is weird. But Gatsby only whitelists GATSBY_ of the env vars, with no obvious way of adding your own.
But doing that isn't so hard, you can do it by adding something like this in the gatsby-node.js file:
exports.onCreateWebpackConfig = ({ actions, getConfig }) => {
const config = getConfig();
// Allow process.env.MY_WHITELIST_PREFIX_* environment variables
const definePlugin = config.plugins.find(p => p.definitions);
for (const [k, v] of Object.entries(process.env)) {
if (k.startsWith("MY_WHITELIST_PREFIX_")) {
definePlugin.definitions[`process.env.${k}`] = JSON.stringify(v);
}
}
actions.replaceWebpackConfig(config);
};
After doing a few searches, I found that we can set environment variables through netlify website, here are the steps:
Under your own netlify console platform, please go to settings
Choose build & deploy tab (can be found on sidebar)
Choose environment sub-tab option
Click edit variables and add/put your credentials in
Done!

Dotenv not loading properly

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.
It appears that when you specify the path, you need to make it full:
require('dotenv').config({path: __dirname + '/../.env'});
.env being your file
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.
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'})
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
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');
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.

Categories

Resources