The dotenv
option enables webpack's built-in environment variable loading from .env
files. This provides a convenient way to manage environment-specific configuration without external plugins.
dotenv
boolean
object
Enable and configure the built-in Dotenv plugin to load environment variables from .env
files.
webpack.config.js
module.exports = {
//...
dotenv: true,
};
Setting dotenv
to true
enables the plugin with default options. For custom configuration, pass an options object:
module.exports = {
//...
dotenv: {
prefix: 'WEBPACK_',
dir: true,
template: ['.env', '.env.local', '.env.[mode]', '.env.[mode].local'],
},
};
prefix
string
string[]
Default: 'WEBPACK_'
Only expose environment variables that start with the specified prefix(es). This prevents accidental exposure of sensitive variables.
webpack.config.js
module.exports = {
//...
dotenv: {
prefix: 'APP_', // Only expose APP_* variables
},
};
Multiple prefixes:
module.exports = {
//...
dotenv: {
prefix: ['APP_', 'CONFIG_'], // Expose both APP_* and CONFIG_* variables
},
};
dir
boolean
string
Default: true
The directory from which .env
files are loaded.
true
- Load from the project root (context)false
- Disable .env
file loadingstring
- Relative path from project root or absolute pathwebpack.config.js
module.exports = {
//...
dotenv: {
dir: './config', // Load from ./config directory
},
};
Disable loading:
module.exports = {
//...
dotenv: {
dir: false, // Only use process.env variables
},
};
template
string[]
Default: ['.env', '.env.local', '.env.[mode]', '.env.[mode].local']
Template patterns for .env
file names. Use [mode]
as a placeholder for the webpack mode (e.g., development
, production
).
Files are loaded in the order specified, with later files overriding earlier ones.
webpack.config.js
module.exports = {
//...
mode: 'production',
dotenv: {
template: ['.env', '.env.production'], // Only load these two files
},
};
Custom patterns:
module.exports = {
//...
dotenv: {
template: [
'.env',
'.env.local',
'.env.[mode]',
'.env.[mode].local',
'.env.override', // Always loaded last
],
},
};
Environment files are loaded in order, with later files having higher priority:
.env
- Loaded in all modes.env.local
- Loaded in all modes, ignored by git (convention).env.[mode]
- Only loaded in specified mode (e.g., .env.production
).env.[mode].local
- Only loaded in specified mode, ignored by gitVariables from later files override those from earlier files. Additionally, variables already set in process.env
take the highest priority.
Environment variables are automatically expanded using the dotenv-expand syntax:
.env
WEBPACK_API_BASE=https://api.example.com
WEBPACK_API_URL=${WEBPACK_API_BASE}/v1
WEBPACK_PORT=${WEBPACK_PORT:-3000} # Use WEBPACK_PORT from process.env, or 3000 as default
In your code:
console.log(process.env.WEBPACK_API_URL); // "https://api.example.com/v1"
console.log(process.env.WEBPACK_PORT); // Value of process.env.WEBPACK_PORT if set, otherwise "3000"
Expansion behavior example:
# .env file
WEBPACK_API_URL=${API_BASE:-https://default.com}/api
# Run with environment variable
API_BASE=https://custom.com npm run build
Result: process.env.WEBPACK_API_URL
will be "https://custom.com/api"
because API_BASE
from process.env
is used during expansion, even though API_BASE
itself won't be exposed in the bundle (it lacks the WEBPACK_
prefix).
Create a .env
file in your project root:
.env
WEBPACK_API_URL=https://api.example.com
WEBPACK_FEATURE_FLAG=true
SECRET_KEY=should-not-be-exposed # Won't be exposed (no WEBPACK_ prefix)
webpack.config.js
module.exports = {
//...
dotenv: true, // Uses default prefix "WEBPACK_"
};
In your application:
console.log(process.env.WEBPACK_API_URL); // "https://api.example.com"
console.log(process.env.WEBPACK_FEATURE_FLAG); // "true"
console.log(process.env.SECRET_KEY); // undefined (not exposed)
Create mode-specific files:
.env
WEBPACK_API_URL=https://api.example.com
WEBPACK_DEBUG=false
.env.production
WEBPACK_API_URL=https://prod-api.example.com
WEBPACK_DEBUG=false
.env.development
WEBPACK_API_URL=https://dev-api.example.com
WEBPACK_DEBUG=true
When building with --mode production
, WEBPACK_API_URL
will be "https://prod-api.example.com"
.
Expose variables with different prefixes:
.env
APP_NAME=MyApp
APP_VERSION=1.0.0
CONFIG_TIMEOUT=5000
CONFIG_RETRY=3
PRIVATE_KEY=secret # Won't be exposed
webpack.config.js
module.exports = {
//...
dotenv: {
prefix: ['APP_', 'CONFIG_'],
},
};
Load environment files from a custom location with custom naming:
webpack.config.js
module.exports = {
//...
dotenv: {
dir: './environments',
template: ['.env.base', '.env.[mode]'],
},
};
This will load:
./environments/.env.base
./environments/.env.production
(in production mode).gitignore
to exclude .env.local
and .env.[mode].local
files''
as a prefix.env
files for different environments.gitignore
# local env files
.env.local
.env.*.local