Skip to content

Commit 4e13f43

Browse files
committed
doc: add environment variables specification
1 parent aaca18b commit 4e13f43

File tree

1 file changed

+222
-0
lines changed

1 file changed

+222
-0
lines changed

doc/api/process.md

+222
Original file line numberDiff line numberDiff line change
@@ -2309,6 +2309,227 @@ import { loadEnvFile } from 'node:process';
23092309
loadEnvFile();
23102310
```
23112311
2312+
### Environment variables file parsing specification
2313+
2314+
This section describes how the environment variables file parsing reads a file
2315+
and sets up the environment variables in Node.js.
2316+
While `.env` files descend from shell scripts that export environment
2317+
variables, there are important distinctions in how they handle quoting,
2318+
spacing, and escaping values.
2319+
Additionally, the [Dotenv][] package has played a significant role in
2320+
popularizing this format.
2321+
2322+
#### Basic parsing
2323+
2324+
* The parser reads line by line, splitting each line into a key and a value
2325+
at the first `=` sign.
2326+
* Lines without an `=` are ignored.
2327+
2328+
```bash
2329+
BASIC=basic
2330+
WITHOUT_EQUAL
2331+
```
2332+
2333+
```cjs
2334+
const assert = require('node:assert');
2335+
const process = require('node:process');
2336+
assert.strictEqual(process.env.BASIC, 'basic');
2337+
assert.strictEqual(process.env.WITHOUT_EQUAL, undefined);
2338+
```
2339+
2340+
```mjs
2341+
import assert from 'node:assert';
2342+
import process from 'node:process';
2343+
assert.strictEqual(process.env.BASIC, 'basic');
2344+
assert.strictEqual(process.env.WITHOUT_EQUAL, undefined);
2345+
```
2346+
2347+
#### Whitespace handling
2348+
2349+
* Leading and trailing whitespaces characters around keys and values are
2350+
ignored unless they are enclosed within quotes.
2351+
2352+
```bash
2353+
SPACED_KEY = parsed
2354+
```
2355+
2356+
```cjs
2357+
const assert = require('node:assert');
2358+
const process = require('node:process');
2359+
assert.strictEqual(process.env.SPACED_KEY, 'parsed');
2360+
```
2361+
2362+
```mjs
2363+
import assert from 'node:assert';
2364+
import process from 'node:process';
2365+
assert.strictEqual(process.env.SPACED_KEY, 'parsed');
2366+
```
2367+
2368+
#### Comments
2369+
2370+
* Lines starting with `#` are treated as comments and ignored.
2371+
* Inline comments (starting with `#` after a value) are ignored, and do not
2372+
affect parsing of the value.
2373+
2374+
```bash
2375+
# COMMENTS=work
2376+
INLINE_COMMENTS=inline comments # work
2377+
```
2378+
2379+
```cjs
2380+
const assert = require('node:assert');
2381+
const process = require('node:process');
2382+
assert.strictEqual(process.env.COMMENTS, undefined);
2383+
assert.strictEqual(process.env.INLINE_COMMENTS, 'inline comments');
2384+
```
2385+
2386+
```mjs
2387+
import assert from 'node:assert';
2388+
import process from 'node:process';
2389+
assert.strictEqual(process.env.COMMENTS, undefined);
2390+
assert.strictEqual(process.env.INLINE_COMMENTS, 'inline comments');
2391+
```
2392+
2393+
#### Empty values
2394+
2395+
* Variables with no value assigned (just a key followed by `=`) are set to
2396+
an empty string.
2397+
2398+
```bash
2399+
EMPTY=
2400+
```
2401+
2402+
```cjs
2403+
const assert = require('node:assert');
2404+
const process = require('node:process');
2405+
assert.strictEqual(process.env.EMPTY, '');
2406+
```
2407+
2408+
```mjs
2409+
import assert from 'node:assert';
2410+
import process from 'node:process';
2411+
assert.strictEqual(process.env.EMPTY, '');
2412+
```
2413+
2414+
#### Quoted values
2415+
2416+
* Single (`'`), double (`"`), and backtick (`` ` ``) quotes are recognized.
2417+
The content within the quotes is taken as is, including leading and
2418+
trailing spaces.
2419+
* Quotes within a different quote type are preserved.
2420+
2421+
```bash
2422+
FIRST_NAME=' John '
2423+
MIXED_QUOTES="Say 'Hello!'"
2424+
BACKTICK_IN_QUOTES="Using `backticks` in double quotes"
2425+
```
2426+
2427+
```cjs
2428+
const assert = require('node:assert');
2429+
const process = require('node:process');
2430+
assert.strictEqual(process.env.FIRST_NAME, ' John ');
2431+
assert.strictEqual(process.env.MIXED_QUOTES, "Say 'Hello!'");
2432+
assert.strictEqual(process.env.BACKTICK_IN_QUOTES,
2433+
'Using `backticks` in double quotes');
2434+
```
2435+
2436+
```mjs
2437+
import assert from 'node:assert';
2438+
import process from 'node:process';
2439+
assert.strictEqual(process.env.FIRST_NAME, ' John ');
2440+
assert.strictEqual(process.env.MIXED_QUOTES, "Say 'Hello!'");
2441+
assert.strictEqual(process.env.BACKTICK_IN_QUOTES,
2442+
'Using `backticks` in double quotes');
2443+
```
2444+
2445+
#### Multiline values
2446+
2447+
* Values enclosed in quotes described above that span multiple
2448+
lines are accepted and stored with newline characters.
2449+
2450+
```bash
2451+
MULTI_DOUBLE_QUOTED="double
2452+
quoted"
2453+
2454+
MULTI_SINGLE_QUOTED='single
2455+
quoted'
2456+
2457+
MULTI_BACKTICKED=`this
2458+
"multiline"
2459+
value`
2460+
```
2461+
2462+
```cjs
2463+
const assert = require('node:assert');
2464+
const process = require('node:process');
2465+
assert.strictEqual(process.env.MULTI_DOUBLE_QUOTED, 'double\nquoted');
2466+
assert.strictEqual(process.env.MULTI_SINGLE_QUOTED, 'single\nquoted');
2467+
assert.strictEqual(process.env.MULTI_BACKTICKED,
2468+
'this\n"multiline"\nvalue');
2469+
```
2470+
2471+
```mjs
2472+
import assert from 'node:assert';
2473+
import process from 'node:process';
2474+
assert.strictEqual(process.env.MULTI_DOUBLE_QUOTED, 'double\nquoted');
2475+
assert.strictEqual(process.env.MULTI_SINGLE_QUOTED, 'single\nquoted');
2476+
assert.strictEqual(process.env.MULTI_BACKTICKED,
2477+
'this\n"multiline"\nvalue');
2478+
```
2479+
2480+
#### Escapes
2481+
2482+
* Newlines in double-quoted values are expanded to newline characters.
2483+
* Other escapes (e.g., `\n`) are treated as literal text in single-quoted
2484+
or unquoted values.
2485+
2486+
```bash
2487+
EXPAND_NEWLINES="expand\nnew\nlines"
2488+
DONT_EXPAND_UNQUOTED=dontexpand\nnewlines
2489+
DONT_EXPAND_SQUOTED='dontexpand\nnewlines'
2490+
```
2491+
2492+
```cjs
2493+
const assert = require('node:assert');
2494+
const process = require('node:process');
2495+
assert.strictEqual(process.env.EXPAND_NEWLINES, 'expand\nnew\nlines');
2496+
assert.strictEqual(process.env.DONT_EXPAND_UNQUOTED,
2497+
'dontexpand\\nnewlines');
2498+
assert.strictEqual(process.env.DONT_EXPAND_SQUOTED,
2499+
'dontexpand\\nnewlines');
2500+
```
2501+
2502+
```mjs
2503+
import assert from 'node:assert';
2504+
import process from 'node:process';
2505+
assert.strictEqual(process.env.EXPAND_NEWLINES, 'expand\nnew\nlines');
2506+
assert.strictEqual(process.env.DONT_EXPAND_UNQUOTED,
2507+
'dontexpand\\nnewlines');
2508+
assert.strictEqual(process.env.DONT_EXPAND_SQUOTED,
2509+
'dontexpand\\nnewlines');
2510+
```
2511+
2512+
#### Export statements
2513+
2514+
* Any `export` keyword before a key is ignored, allowing compatibility with
2515+
shell scripts. The line is parsed as if `export` weren't there.
2516+
2517+
```bash
2518+
export EXPORT_EXAMPLE = ignore export
2519+
```
2520+
2521+
```cjs
2522+
const assert = require('node:assert');
2523+
const process = require('node:process');
2524+
assert.strictEqual(process.env.EXPORT_EXAMPLE, 'ignore export');
2525+
```
2526+
2527+
```mjs
2528+
import assert from 'node:assert';
2529+
import process from 'node:process';
2530+
assert.strictEqual(process.env.EXPORT_EXAMPLE, 'ignore export');
2531+
```
2532+
23122533
## `process.mainModule`
23132534

23142535
<!-- YAML
@@ -3995,6 +4216,7 @@ cases:
39954216
[Android building]: https://github.com/nodejs/node/blob/HEAD/BUILDING.md#androidandroid-based-devices-eg-firefox-os
39964217
[Child Process]: child_process.md
39974218
[Cluster]: cluster.md
4219+
[Dotenv]: https://github.com/motdotla/dotenv
39984220
[Duplex]: stream.md#duplex-and-transform-streams
39994221
[Event Loop]: https://nodejs.org/en/learn/asynchronous-work/event-loop-timers-and-nexttick#understanding-processnexttick
40004222
[LTS]: https://github.com/nodejs/Release

0 commit comments

Comments
 (0)