grunt-umd is a Grunt plugin that wraps JavaScript code with the Universal Module Definition (UMD) pattern, making code compatible with multiple module systems including AMD (RequireJS), CommonJS/Node.js, and global browser environments.
npm install grunt-umd// Load the task in your Gruntfile.js
grunt.loadNpmTasks('grunt-umd');// Gruntfile.js configuration
grunt.initConfig({
umd: {
all: {
options: {
src: 'src/library.js',
dest: 'dist/library.js',
objectToExport: 'Library',
amdModuleId: 'library',
globalAlias: 'Library',
deps: {
'default': ['dependency1', 'dependency2'],
amd: ['dep1', 'dep2'],
cjs: ['dependency1', 'dependency2'],
global: ['Dep1', 'Dep2']
}
}
}
}
});
// Run the task
grunt umd:allThe plugin registers a multi-task named 'umd' with Grunt.
/**
* Main module export that registers the 'umd' Grunt multi-task
* @param grunt - The Grunt instance
*/
function(grunt: any): void;Configure the UMD wrapping behavior through Grunt's configuration system.
interface UmdTaskOptions {
/** Source files to process (required) */
src: string | string[];
/** Destination path for output files (optional) */
dest?: string;
/** Handlebars template to use for UMD wrapping (optional) */
template?: string;
/** Internal object name that will be exported (optional) */
objectToExport?: string;
/** AMD module identifier (optional) */
amdModuleId?: string;
/** Name of the global variable for browser environments (optional) */
globalAlias?: string;
/** Number of spaces for code indentation (optional) */
indent?: number;
/** Dependencies for different module systems (optional) */
deps?: UmdDependencies;
}
interface UmdDependencies {
/** Default dependencies used as fallback */
'default'?: string[];
/** AMD-specific dependencies */
amd?: string[] | AdvancedDependencyConfig;
/** CommonJS-specific dependencies */
cjs?: string[] | AdvancedDependencyConfig;
/** Global/browser-specific dependencies */
global?: (string | GlobalDependency)[] | AdvancedDependencyConfig;
/** Arguments passed to the factory function */
args?: string[];
/** Rails asset pipeline dependencies */
pipeline?: AdvancedDependencyConfig;
}
interface AdvancedDependencyConfig {
/** Array of dependency items */
items: string[] | (string | GlobalDependency)[];
/** Indentation level for formatting */
indent?: number;
/** Prefix string for each dependency */
prefix?: string;
/** Separator between dependencies */
separator?: string;
/** Suffix string for each dependency */
suffix?: string;
}
interface GlobalDependency {
/** Dependency name */
depName: string;
/** Parameter name in factory function */
param: string;
}Usage Examples:
// Basic configuration
grunt.initConfig({
umd: {
basic: {
options: {
src: 'src/my-lib.js',
dest: 'dist/my-lib.js'
}
}
}
});
// Advanced configuration with dependencies
grunt.initConfig({
umd: {
advanced: {
options: {
src: ['src/*.js'],
dest: 'dist/',
template: 'umd',
objectToExport: 'MyLibrary',
amdModuleId: 'my-library',
globalAlias: 'MyLib',
indent: 4,
deps: {
'default': ['jquery', 'lodash'],
amd: ['jquery', 'lodash'],
cjs: ['jquery', 'lodash'],
global: ['jQuery', 'lodash']
}
}
}
}
});
// Advanced dependency formatting
grunt.initConfig({
umd: {
rails: {
options: {
src: 'src/library.js',
dest: 'dist/library.js',
template: 'umd+rails.hbs',
objectToExport: 'Library',
indent: 2,
deps: {
args: ['$', '_', 'Backbone'],
'default': ['$', '_', 'Backbone'],
amd: {
indent: 6,
items: ['jquery', 'underscore', 'backbone'],
prefix: '\'',
separator: ',\n',
suffix: '\''
},
cjs: {
indent: 6,
items: ['jquery', 'underscore', 'backbone'],
prefix: 'require(\'',
separator: ',\n',
suffix: '\')'
},
global: {
items: ['jQuery', '_', 'Backbone']
},
pipeline: {
indent: 0,
items: ['jquery', 'vendor/underscore-min', 'vendor/backbone-min'],
prefix: '//= require ',
separator: '\n'
}
}
}
}
}
});
// Multiple files with directory output
grunt.initConfig({
umd: {
multiple: {
options: {
src: 'src/**/*.js',
dest: 'dist/' // Directory - maintains source structure
}
}
}
});Specify which UMD template to use for wrapping code.
/**
* Template configuration options
*/
interface TemplateOptions {
/**
* Template identifier or file path
* Built-in templates: 'umd', 'unit', 'returnExportsGlobal'
* Custom: relative path to .hbs file
*/
template?: 'umd' | 'unit' | 'returnExportsGlobal' | string;
}Built-in Templates:
'umd' (default): Standard UMD template based on umd/returnExports.js'unit': Modified template for wrapping standalone CommonJS/Node modules'returnExportsGlobal': Template optimized for global variable export scenariosTemplate Examples:
// Using returnExportsGlobal template
grunt.initConfig({
umd: {
globalOptimized: {
options: {
src: 'src/library.js',
dest: 'dist/library.global.js',
template: 'returnExportsGlobal',
objectToExport: 'MyLib',
globalAlias: 'MyLib',
deps: {
args: ['_'],
'default': ['_'],
amd: ['lodash'],
cjs: ['lodash'],
global: ['_']
}
}
}
}
});Custom Templates:
grunt.initConfig({
umd: {
custom: {
options: {
src: 'src/library.js',
template: 'templates/my-custom-umd.hbs'
}
}
}
});The task processes files according to the following rules:
/**
* File processing configuration
*/
interface FileProcessing {
/** Source file patterns expanded using grunt.file.expand() */
src: string | string[];
/**
* Destination handling:
* - If ends with .js: treated as output file path
* - Otherwise: treated as output directory, maintains source structure
*/
dest?: string;
}Processing Examples:
// Single file to single file
{
src: 'src/library.js',
dest: 'dist/library.umd.js' // .js extension = file output
}
// Multiple files to directory
{
src: 'src/**/*.js',
dest: 'dist/' // No .js extension = directory output
}
// Files processed in place (no dest)
{
src: 'src/library.js' // Overwrites source file
}The plugin provides comprehensive error handling and validation.
/**
* Error conditions and handling
*/
interface ErrorHandling {
/** Throws Error if src option is missing */
missingSource: 'Missing source file (src).';
/** Uses grunt.warn() with exit code 3 for processing errors */
processingErrors: 'grunt.warn(error, 3)';
}Common Error Scenarios:
src option in configurationControl the indentation of the generated UMD code.
/**
* Indentation configuration
*/
interface IndentationOptions {
/** Number of spaces to use for indenting generated code */
indent?: number;
}Example:
grunt.initConfig({
umd: {
indented: {
options: {
src: 'src/library.js',
dest: 'dist/library.js',
indent: 4 // Use 4 spaces for indentation
}
}
}
});The plugin maintains backward compatibility for legacy dependency configurations.
/**
* Legacy dependency format conversion
* Arrays are automatically converted to object format
*/
interface BackwardCompatibility {
/** Legacy format (automatically converted) */
legacy: {
deps: {
amd: string[];
cjs: string[];
global: string[];
};
};
/** Modern format (after conversion) */
modern: {
deps: {
amd: { items: string[] };
cjs: { items: string[] };
global: { items: string[] };
};
};
}Conversion Example:
// Legacy configuration (still supported)
deps: {
amd: ['jquery', 'lodash'],
cjs: ['jquery', 'lodash']
}
// Automatically converted to
deps: {
amd: { items: ['jquery', 'lodash'] },
cjs: { items: ['jquery', 'lodash'] }
}/**
* Main plugin export function
*/
declare function gruntUmd(grunt: any): void;
/**
* Complete task configuration interface
*/
interface UmdTaskConfig {
options: UmdTaskOptions;
}
/**
* Grunt task context
*/
interface GruntTaskContext {
data: any;
options(): any;
}