Dotenv: Using with ES6 modules

Created on 3 Apr 2016  路  16Comments  路  Source: motdotla/dotenv

In the case of using ES6 modules via import, configuring dotenv in the base file doesn't set the environment vars in sub-modules. For example:

index.js
import dotenv from 'dotenv'
dotenv.config({ silent: true })
import hello from './hello'
hello.js
console.log(process.env) /* this doesn't have the environment vars in it */

This is because babel compiles the above as

var dotenv = require('dotenv')
var hello = require('./hello')
dotenv.config({ silent: true })

It works if I do import 'dotenv/config' instead, but then I can't specify the silent flag, so it throws an error if .env doesn't exist (for example, if running in production). I think a simple solution would be to allow something such as import 'dotenv/register' for a one-line, silent setup of the variables.

Most helpful comment

I faced this problem as well, and I couldn't figure out how to use node preload script because I was running nodemon (this is for development). What I did was to move the dotenv call into a separate file and then import it in index.js.

index.js
import _ from './env'
import hello from './hello'
env.js
import dotenv from 'dotenv'
dotenv.config({ silent: true })

Hope this is helpful for anyone who faces this issue.

All 16 comments

I see that there were a few other issues for this in the past, but I didn't see that a solution was ever reached? I know preloading the module was recommended, but unfortunately that's not an option in this case. I'd be happy to submit a PR for this if you'd like.

hey @jsonmaur you can set options using the preload script. You can pass in the options via the a arg on the command.

node -r dotenv/config your_script.js dotenv_config_silent=true

closing this, if this does not work for you let me know

I faced this problem as well, and I couldn't figure out how to use node preload script because I was running nodemon (this is for development). What I did was to move the dotenv call into a separate file and then import it in index.js.

index.js
import _ from './env'
import hello from './hello'
env.js
import dotenv from 'dotenv'
dotenv.config({ silent: true })

Hope this is helpful for anyone who faces this issue.

Thanks @ngzhian this fix worked for me!

import './env';

Should do it if you don't want to pollute the scope

I doesn't work for me with babel-node.

@morajabi Have you found a workaround for babel-node?

@sa-adebayo Yes and the solution is simply don't use babel-node. It's advised to run your code with babel and dotenv this way:

node --require 'dotenv/config' --require 'babel-register'

now you don't need to require or import dotenv nor babel-register inside your code.

How to use dotenv with stenciljs ?

This worked for me:

babel-node src/index.js --require 'dotenv/config'

Keep in mind that it won't work if you put the --require argument before the script (babel-node --require 'dotenv/config' src/index.js)

I was able to get babel-node to work with putting the --require option before the script if I provided a complete path, absolute or relative, instead of the module name. For example:

babel-node --require node_modules/dotenv/config script

The above call works as an NPM script with babel-node installed locally (it probably works from the command-line too if babel-node is installed globally but I didn't test it).

To run it from the command-line with babel-node installed locally, call like:

node_modules/.bin/babel-node --require node_modules/dotenv/config script

Although adding node_modules/ may not be pretty, the require option now won't look like it is being used by script. Also, '--require' and 'dotenv/config' won't show in process.argv. But any options listed after script will show up in process.argv as expected. Note: -- not required. If used, then it will show up in process.argv. For example:

babel-node --require node_modules/dotenv/config script these opts are in process.argv
// script.js
console.log(process.argv); // [ 'node', 'full/path/to/script', 'these', 'opts', 'are', 'in', 'process.argv' ]

Note: This was tested with @babel/node version 7.0.0-beta.51 with node version v8.11.2.

I'm currently using this plugin of babel and it's working in the same way

babel-plugin-inline-dotenv

The difference is that I don't need to require and load it in my entry points.

/* .babelrc */
{
  "presets": ["env"],
  "plugins": ["inline-dotenv"]
}

Hope my 2 cents help.

Trying to do this in a TypeScript environment:

env.ts:

import dotenv from 'dotenv'
dotenv.config({ silent: true })

After installing @types/dotenv, I now get a 'has no default export.' error on dotenv. I am pretty new to JS and completely new to TS. The following is working for me but I have no idea whether this is an appropriate way to handle the import or not:

env.ts:

import * as dotenv from 'dotenv'
dotenv.config()

@dmark see #362 for an example of using dotenv in a TypeScript environment. Your import * as dotenv is totally fine. Destructuring in the example (import { config } from "dotenv") is another approach that gets the same result.

I am new to Express with TypeScript, but nothing of this works for me. I am getting an error dotenv module does not exist at all.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

DesignByOnyx picture DesignByOnyx  路  4Comments

ffxsam picture ffxsam  路  4Comments

AndrewChen1982 picture AndrewChen1982  路  4Comments

ycmjason picture ycmjason  路  4Comments

shellscape picture shellscape  路  3Comments