Skip to content

Commit

Permalink
Merge pull request #593 from motdotla/readme-updates
Browse files Browse the repository at this point in the history
Readme updates
  • Loading branch information
motdotla committed Jan 16, 2022
2 parents b652872 + d16fa72 commit 72c66fc
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 23 deletions.
62 changes: 42 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ dotenv.config()
console.log(process.env) // remove this after you've confirmed it working
```

.. or using typescript or esm?
.. or using ES6?

```javascript
// index.mjs
import dotenv from 'dotenv'
dotenv.config()
// index.mjs (ESM)
import 'dotenv/config' // see https://github.com/motdotla/dotenv#how-do-i-use-dotenv-with-import
import express from 'express'
```

### 3. That's it! 🎉
Expand Down Expand Up @@ -89,8 +89,10 @@ See [examples](https://github.com/dotenv-org/examples) of using dotenv with vari
* [typescript](https://github.com/dotenv-org/examples/tree/master/dotenv-typescript)
* [typescript parse](https://github.com/dotenv-org/examples/tree/master/dotenv-typescript-parse)
* [webpack](https://github.com/dotenv-org/examples/tree/master/dotenv-webpack)
* [webpack (plugin)](https://github.com/dotenv-org/examples/tree/master/dotenv-webpack2)
* [react](https://github.com/dotenv-org/examples/tree/master/dotenv-react)
* [react (typescript)](https://github.com/dotenv-org/examples/tree/master/dotenv-react-typescript)
* [express](https://github.com/dotenv-org/examples/tree/master/dotenv-express)

## Documentation

Expand Down Expand Up @@ -257,9 +259,7 @@ for (const k in envConfig) {

### Can I customize/write plugins for dotenv?

For `dotenv@2.x.x`: Yes. `dotenv.config()` now returns an object representing
the parsed `.env` file. This gives you everything you need to continue
setting values on `process.env`. For example:
Yes! `dotenv.config()` returns an object representing the parsed `.env` file. This gives you everything you need to continue setting values on `process.env`. For example:

```js
const dotenv = require('dotenv')
Expand All @@ -274,37 +274,59 @@ Try [dotenv-expand](https://github.com/motdotla/dotenv-expand)

### How do I use dotenv with `import`?

ES2015 and beyond offers modules that allow you to `export` any top-level `function`, `class`, `var`, `let`, or `const`.
Simply..

```javascript
// index.mjs (ESM)
import 'dotenv/config' // see https://github.com/motdotla/dotenv#how-do-i-use-dotenv-with-import
import express from 'express'
```

A little background..

> 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.
>
> [ES6 In Depth: Modules](https://hacks.mozilla.org/2015/08/es6-in-depth-modules/)
You must run `dotenv.config()` before referencing any environment variables. Here's an example of problematic code:

`errorReporter.js`:
What does this mean in plain language? It means you would think the following would work but it won't.

```js
// errorReporter.mjs
import { Client } from 'best-error-reporting-service'

export const client = new Client(process.env.BEST_API_KEY)
export default new Client(process.env.API_KEY)

// index.mjs
import dotenv from 'dotenv'
dotenv.config()

import errorReporter from './errorReporter.mjs'
errorReporter.report(new Error('documented example'))
```

`index.js`:
`process.env.API_KEY` will be blank.

Instead the above code should be written as..

```js
import dotenv from 'dotenv'
import errorReporter from './errorReporter'
// errorReporter.mjs
import { Client } from 'best-error-reporting-service'

dotenv.config()
errorReporter.client.report(new Error('faq example'))
export default new Client(process.env.API_KEY)

// index.mjs
import 'dotenv/config'

import errorReporter from './errorReporter.mjs'
errorReporter.report(new Error('documented example'))
```

`client` will not be configured correctly because it was constructed before `dotenv.config()` was executed. There are (at least) 3 ways to make this work.
Does that make sense? It's a bit unintuitive, but it is how importing of ES6 modules work. Here is a [working example of this pitfall](https://github.com/dotenv-org/examples/tree/master/dotenv-es6-import-pitfall).

There are also 2 alternatives to this approach:

1. Preload dotenv: `node --require dotenv/config index.js` (_Note: you do not need to `import` dotenv with this approach_)
2. Import `dotenv/config` instead of `dotenv` (_Note: you do not need to call `dotenv.config()` and must pass options via the command line or environment variables with this approach_)
3. Create a separate file that will execute `config` first as outlined in [this comment on #133](https://github.com/motdotla/dotenv/issues/133#issuecomment-255298822)
2. Create a separate file that will execute `config` first as outlined in [this comment on #133](https://github.com/motdotla/dotenv/issues/133#issuecomment-255298822)

## Contributing Guide

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "dotenv",
"version": "12.0.3",
"version": "12.0.4",
"description": "Loads environment variables from .env file",
"main": "lib/main.js",
"types": "lib/main.d.ts",
"exports": {
".": {
"require": "./lib/main.js",
"default": "./lib/main.js",
"types": "./lib/main.d.ts"
"types": "./lib/main.d.ts",
"default": "./lib/main.js"
},
"./config": "./config.js",
"./config.js": "./config.js",
Expand Down

0 comments on commit 72c66fc

Please sign in to comment.