Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moving toward a cleaner implementation #608

Merged
merged 10 commits into from Jan 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 23 additions & 1 deletion CHANGELOG.md
Expand Up @@ -2,7 +2,29 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

## [Unreleased](https://github.com/motdotla/dotenv/compare/v14.3.2...master)
## [Unreleased](https://github.com/motdotla/dotenv/compare/v15.0.0...master)

## [15.0.0](https://github.com/motdotla/dotenv/compare/v14.3.2...v15.0.0) (2022-01-26)

`v15.0.0` is a major new release with some important breaking changes.

### Added

- _Breaking:_ Multiline parsing support (just works. no need for the flag.)

### Changed

- _Breaking:_ `#` marks the beginning of a comment (UNLESS the value is wrapped in quotes. Please update your `.env` files to wrap in quotes any values containing `#`. For example: `SECRET_HASH="something-with-a-#-hash"`).

..Understandably, (as some teams have noted) this is tedious to do across the entire team. To make it less tedious, we recommend using [dotenv cli](https://github.com/dotenv-org/cli) going forward. It's an optional plugin that will keep your `.env` files in sync between machines, environments, or team members.

### Removed

- _Breaking:_ Remove multiline option (just works out of the box now. no need for the flag.)

### Changed

- Preserve backwards compatibility on values containing `#` 🐞 ([#603](https://github.com/motdotla/dotenv/pull/603))

## [14.3.2](https://github.com/motdotla/dotenv/compare/v14.3.1...v14.3.2) (2022-01-25)

Expand Down
170 changes: 81 additions & 89 deletions README.md
Expand Up @@ -28,54 +28,110 @@ Or installing with yarn? `yarn add dotenv`

## Usage

Usage is easy!

### 1. Create a `.env` file in the **root directory** of your project.
Create a `.env` file in the root of your project:

```dosini
# .env file
#
# Add environment-specific variables on new lines in the form of NAME=VALUE
#
DB_HOST=localhost
DB_USER=root
DB_PASS=s1mpl3
S3_BUCKET="YOURS3BUCKET"
SECRET_KEY="YOURSECRETKEYGOESHERE"
```

### 2. As early as possible in your application, import and configure dotenv.
As early as possible in your application, import and configure dotenv:

```javascript
// index.js
require('dotenv').config()

console.log(process.env) // remove this after you've confirmed it working
```

.. or using ES6?

```javascript
// 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! 🎉

`process.env` now has the keys and values you defined in your `.env` file.
That's it. `process.env` now has the keys and values you defined in your `.env` file:

```javascript
require('dotenv').config()

...

const db = require('db')
db.connect({
host: process.env.DB_HOST,
username: process.env.DB_USER,
password: process.env.DB_PASS
})
s3.getBucketCors({Bucket: process.env.S3_BUCKET}, function(err, data) {})
```

### Multiline values

If you need multiline variables, for example private keys, those are now supported (`>= v15.0.0`) with line breaks:

```dosini
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
...
Kh9NV...
...
-----END DSA PRIVATE KEY-----"
```

Alternatively, you can double quote strings and use the `\n` character:

```dosini
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\Kh9NV...\n-----END DSA PRIVATE KEY-----\n"
```

### Comments

Comments may be added to your file on their own line or inline:

```dosini
# This is a comment
SECRET_KEY=YOURSECRETKEYGOESHERE # comment
SECRET_HASH="something-with-a-#-hash"
```

Comments begin where a `#` exists, so if your value contains a `#` please wrap it in quotes. This is a breaking change from `>= v15.0.0` and on.

### Parsing

The engine which parses the contents of your file containing environment variables is available to use. It accepts a String or Buffer and will return an Object with the parsed keys and values.

```javascript
const dotenv = require('dotenv')
const buf = Buffer.from('BASIC=basic')
const config = dotenv.parse(buf) // will return an object
console.log(typeof config, config) // object { BASIC : 'basic' }
```

### Preload

You can use the `--require` (`-r`) [command line option](https://nodejs.org/api/cli.html#cli_r_require_module) to preload dotenv. By doing this, you do not need to require and load dotenv in your application code.

```bash
$ node -r dotenv/config your_script.js
```

The configuration options below are supported as command line arguments in the format `dotenv_config_<option>=value`

```bash
$ node -r dotenv/config your_script.js dotenv_config_path=/custom/path/to/.env dotenv_config_debug=true
```

Additionally, you can use environment variables to set configuration options. Command line arguments will precede these.

```bash
$ DOTENV_CONFIG_<OPTION>=value node -r dotenv/config your_script.js
```

```bash
$ DOTENV_CONFIG_ENCODING=latin1 DOTENV_CONFIG_DEBUG=true node -r dotenv/config your_script.js dotenv_config_path=/custom/path/to/.env
```

### Variable Expansion

You need to add the value of another variable in one of your variables? Use [dotenv-expand](https://github.com/motdotla/dotenv-expand).

### Syncing

You need to keep `.env` files in sync between machines, environments, or team members? Use [dotenv cli](https://github.com/dotenv-org/cli).

## Examples

See [examples](https://github.com/dotenv-org/examples) of using dotenv with various frameworks, languages, and configurations.
Expand Down Expand Up @@ -163,27 +219,6 @@ Override any environment variables that have already been set on your machine wi
require('dotenv').config({ override: true })
```

##### Multiline

Default: `false`

Turn on multiline line break parsing.

```js
require('dotenv').config({ multiline: true })
```

This allows specifying multiline values in this format:

```
PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
MIGT...
7ure...
-----END PRIVATE KEY-----"
```

Ensure that the value begins with a single or double quote character, and it ends with the same character.

### Parse

The engine which parses the contents of your file containing environment
Expand Down Expand Up @@ -213,51 +248,8 @@ const config = dotenv.parse(buf, opt)
// expect a debug message because the buffer is not in KEY=VAL form
```

##### Multiline

Default: `false`

Turn on multiline line break parsing.

```js
require('dotenv').config({ multiline: true })
```

This allows specifying multiline values in this format:

```
PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
MIGT...
7ure...
-----END PRIVATE KEY-----"
```

## Other Usage

### Preload

You can use the `--require` (`-r`) [command line option](https://nodejs.org/api/cli.html#cli_r_require_module) to preload dotenv. By doing this, you do not need to require and load dotenv in your application code. This is the preferred approach when using `import` instead of `require`.

```bash
$ node -r dotenv/config your_script.js
```

The configuration options below are supported as command line arguments in the format `dotenv_config_<option>=value`

```bash
$ node -r dotenv/config your_script.js dotenv_config_path=/custom/path/to/.env dotenv_config_debug=true
```

Additionally, you can use environment variables to set configuration options. Command line arguments will precede these.

```bash
$ DOTENV_CONFIG_<OPTION>=value node -r dotenv/config your_script.js
```

```bash
$ DOTENV_CONFIG_ENCODING=latin1 DOTENV_CONFIG_DEBUG=true node -r dotenv/config your_script.js dotenv_config_path=/custom/path/to/.env
```

## FAQ

### Why is the `.env` file not loading my environment variables successfully?
Expand Down Expand Up @@ -294,7 +286,7 @@ The parsing engine currently supports the following rules:
- `BASIC=basic` becomes `{BASIC: 'basic'}`
- empty lines are skipped
- lines beginning with `#` are treated as comments
- whitespace followed by `#` marks the beginning of an inline comment (unless when the value is wrapped in quotes)
- `#` marks the beginning of a comment (unless when the value is wrapped in quotes)
- empty values become empty strings (`EMPTY=` becomes `{EMPTY: ''}`)
- inner quotes are maintained (think JSON) (`JSON={"foo": "bar"}` becomes `{JSON:"{\"foo\": \"bar\"}"`)
- whitespace is removed from both ends of unquoted values (see more on [`trim`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim)) (`FOO= some value ` becomes `{FOO: 'some value'}`)
Expand Down Expand Up @@ -383,7 +375,7 @@ errorReporter.report(new Error('documented example'))

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:
There are two 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. 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)
Expand Down
29 changes: 1 addition & 28 deletions lib/main.d.ts
@@ -1,32 +1,6 @@
// TypeScript Version: 3.0
/// <reference types="node" />

export interface DotenvParseOptions {
/**
* Default: `false`
*
* Turn on logging to help debug why certain keys or values are not being set as you expect.
*
* example: `dotenv.parse('KEY=value', { debug: true })`
*/
debug?: boolean;

/**
* Default: `false`
*
* Turn on multiline line break parsing.
*
* example:
*
* MY_VAR="this
* is
* a
* multiline
* string"
*/
multiline?: boolean;
}

export interface DotenvParseOutput {
[name: string]: string;
}
Expand All @@ -41,8 +15,7 @@ export interface DotenvParseOutput {
* @returns an object with keys and values based on `src`. example: `{ DB_HOST : 'localhost' }`
*/
export function parse<T extends DotenvParseOutput = DotenvParseOutput>(
src: string | Buffer,
options?: DotenvParseOptions
src: string | Buffer
): T;

export interface DotenvConfigOptions {
Expand Down