grunt-env is a Grunt plugin that enables specifying environment variable configurations for task chains in Grunt build processes. It provides comprehensive environment variable management with support for different configuration formats (INI, JSON, YAML), dynamic environment manipulation through options like add, replace, push, and unshift operations, and the ability to load environment settings from external files or using envdir-style directory structures.
npm install grunt-envSince this is a Grunt plugin, it's loaded using Grunt's task loading system:
grunt.loadNpmTasks('grunt-env');The plugin automatically registers the env multi-task with Grunt when loaded.
For advanced use cases requiring direct access to utilities:
const utils = require('grunt-env/lib/utils');// Basic environment variable setting
grunt.initConfig({
env: {
dev: {
NODE_ENV: 'development',
DEST: 'temp'
},
prod: {
NODE_ENV: 'production',
DEST: 'dist'
}
}
});
// Use in task chains
grunt.registerTask('dev', ['env:dev', 'lint', 'server', 'watch']);
grunt.registerTask('build', ['env:prod', 'lint', 'other:build:tasks']);grunt-env follows Grunt's plugin architecture and consists of:
env multi-task that processes configuration objectsutils module provides a unified interface for parsing different file formats (JSON, YAML, INI, plain text)Internal utilities for parsing configuration files in different formats. While primarily used internally by the plugin, these utilities are available for advanced use cases.
/**
* Parse a configuration file based on its extension
* @param {Object} grunt - Grunt instance
* @param {string} file - Path to the file to parse
* @returns {Object} Parsed configuration object
*/
function parse(grunt, file);The parse function automatically detects file format based on extension:
.json - Parsed as JSON.yaml, .yml - Parsed as YAML.ini, .env - Parsed as INI formatSets environment variables directly from configuration objects. The plugin registers the env multi-task with Grunt.
/**
* Grunt multi-task registration function for environment variable management
* Automatically registered when the plugin is loaded
*/
grunt.registerMultiTask('env', description, taskFunction);Configuration Schema:
// Grunt task configuration
env: {
[targetName]: {
[VARIABLE_NAME]: string | (() => string);
// Additional environment variables...
}
}Usage Example:
env: {
development: {
NODE_ENV: 'development',
DEBUG: 'true',
PORT: '3000'
},
production: {
NODE_ENV: 'production',
DEBUG: 'false',
PORT: '8080'
}
}Environment variables can be set using functions for dynamic values.
[VARIABLE_NAME]: () => stringUsage Example:
env: {
build: {
BUILD_TIME: function() {
return new Date().toISOString();
},
GIT_HASH: function() {
return require('child_process').execSync('git rev-parse HEAD').toString().trim();
}
}
}Load environment variables from external files in various formats.
// Grunt task configuration with file sources
env: {
[targetName]: {
src: string | string[];
// Other configuration...
}
}Supported file formats:
.json files.yaml, .yml files.ini, .env filesUsage Example:
env: {
dev: {
src: "dev.json"
},
prod: {
src: "settings.yaml"
},
heroku: {
src: ".env"
},
multiple: {
src: [".env", "config.json", "secrets.ini"]
}
}Load environment variables from directory structures similar to daemontools envdir.
// Grunt task configuration with envdir option
env: {
[targetName]: {
src: string[];
options: {
envdir: boolean;
}
}
}Usage Example:
env: {
production: {
src: ["envdir/*"],
options: {
envdir: true
}
}
}With envdir mode, each file in the directory becomes an environment variable where:
Dynamic environment manipulation through special directive options.
// Grunt task configuration with directives
env: {
[targetName]: {
[VARIABLE_NAME]: string;
options: {
add?: { [key: string]: string };
replace?: { [key: string]: string };
push?: { [key: string]: string | { value: string; delimiter?: string } };
unshift?: { [key: string]: string | { value: string; delimiter?: string } };
concat?: { [key: string]: string | { value: string; delimiter?: string } };
}
}
}Adds environment variables only if they don't already exist.
options: {
add: {
[variableName]: string;
}
}Usage Example:
env: {
dev: {
options: {
add: {
DEBUG: '1', // Only set if DEBUG doesn't exist
LOG_LEVEL: 'verbose' // Only set if LOG_LEVEL doesn't exist
}
}
}
}Replaces existing environment variables with new values. Only replaces if the variable already exists.
options: {
replace: {
[variableName]: string;
}
}Usage Example:
env: {
prod: {
options: {
replace: {
NODE_ENV: 'production', // Only replaces if NODE_ENV exists
DEBUG: 'false' // Only replaces if DEBUG exists
}
}
}
}Appends values to existing environment variables with optional delimiter.
options: {
push: {
[variableName]: string | {
value: string;
delimiter?: string;
}
}
}Usage Example:
env: {
dev: {
options: {
push: {
PATH: {
value: '~/bin',
delimiter: ':'
},
CLASSPATH: '/new/lib' // Uses empty delimiter
}
}
}
}Prepends values to existing environment variables with optional delimiter.
options: {
unshift: {
[variableName]: string | {
value: string;
delimiter?: string;
}
}
}Usage Example:
env: {
dev: {
options: {
unshift: {
PATH: {
value: '/priority/bin',
delimiter: ':'
},
LD_LIBRARY_PATH: '/usr/local/lib:'
}
}
}
}Functionally identical to push directive, provided for readability.
options: {
concat: {
[variableName]: string | {
value: string;
delimiter?: string;
}
}
}Options that apply to all targets within the env task configuration.
env: {
options: {
[optionName]: any;
}
}Usage Example:
env: {
options: {
// Global options shared across all targets
globalSetting: 'shared-value'
},
dev: {
NODE_ENV: 'development'
},
prod: {
NODE_ENV: 'production'
}
}grunt.initConfig({
env: {
options: {
// Global options
SHARED_SECRET: 'global-value'
},
// Development environment
dev: {
NODE_ENV: 'development',
DEBUG: 'true',
PORT: '3000',
// Load from external files
src: ['dev.env', 'secrets.json'],
options: {
add: {
LOG_LEVEL: 'verbose'
},
push: {
PATH: {
value: 'node_modules/.bin',
delimiter: ':'
}
}
}
},
// Production environment
prod: {
NODE_ENV: 'production',
DEBUG: 'false',
PORT: '8080',
// Dynamic function
BUILD_TIME: function() {
return new Date().toISOString();
},
options: {
replace: {
NODE_ENV: 'production'
},
unshift: {
PATH: '/usr/local/bin:'
}
}
},
// Envdir-style loading
docker: {
src: ['docker-env/*'],
options: {
envdir: true
}
}
}
});
// Task definitions
grunt.registerTask('dev', ['env:dev', 'serve', 'watch']);
grunt.registerTask('build', ['env:prod', 'clean', 'concat', 'uglify']);
grunt.registerTask('docker-build', ['env:docker', 'build']);// Environment variable value types
type EnvValue = string | (() => string);
// Directive value types
type DirectiveValue = string | {
value: string;
delimiter?: string;
};
// Main configuration interfaces
interface EnvTaskConfig {
[targetName: string]: EnvTargetConfig;
options?: GlobalOptions;
}
interface EnvTargetConfig {
[variableName: string]: EnvValue;
src?: string | string[];
options?: EnvTargetOptions;
}
interface EnvTargetOptions {
envdir?: boolean;
add?: { [key: string]: string };
replace?: { [key: string]: string };
push?: { [key: string]: DirectiveValue };
unshift?: { [key: string]: DirectiveValue };
concat?: { [key: string]: DirectiveValue };
}
interface GlobalOptions {
[key: string]: any;
}