The google-closure-compiler package provides a Grunt plugin for integrating Closure Compiler into Grunt-based build workflows with support for multiple file sets, parallel compilation, and flexible configuration.
Register the Closure Compiler task with Grunt using the plugin factory function.
/**
* Create and register the closure-compiler Grunt task
* @param grunt - Grunt instance
* @param pluginOptions - Global plugin configuration options
* @returns Grunt task function
*/
function gruntPlugin(grunt: any, pluginOptions?: {
platform?: string | Array<string>;
extraArguments?: Array<string>;
max_parallel_compilations?: number;
}): Function;Basic Setup:
// Gruntfile.js
import { grunt as closureCompiler } from 'google-closure-compiler';
export default function(grunt) {
// Register the plugin
closureCompiler(grunt);
// Configure tasks
grunt.initConfig({
'closure-compiler': {
// Task configurations here
}
});
}Configure compilation tasks using Grunt's multi-task format.
// Grunt task configuration
interface GruntTaskConfig {
options?: CompilerOptions & {
args?: CompilerOptions | Array<string>; // Alternative options format
};
files?: Array<{
src: Array<string>; // Source files
dest: string; // Output file
}>;
}
interface CompilerOptions {
js?: string | Array<string>;
compilation_level?: 'WHITESPACE_ONLY' | 'SIMPLE' | 'ADVANCED';
js_output_file?: string;
create_source_map?: boolean | string;
warning_level?: 'QUIET' | 'DEFAULT' | 'VERBOSE';
[key: string]: any; // All Closure Compiler flags supported
}Usage Examples:
// Gruntfile.js with multiple targets
grunt.initConfig({
'closure-compiler': {
options: {
compilation_level: 'SIMPLE',
warning_level: 'VERBOSE'
},
// Development build
dev: {
options: {
debug: true,
formatting: 'PRETTY_PRINT'
},
files: [{
src: ['src/**/*.js'],
dest: 'build/app.debug.js'
}]
},
// Production build
prod: {
options: {
compilation_level: 'ADVANCED',
create_source_map: 'build/app.min.js.map'
},
files: [{
src: ['src/**/*.js'],
dest: 'build/app.min.js'
}]
},
// Multiple outputs
modules: {
files: [
{
src: ['src/core/**/*.js'],
dest: 'build/core.min.js'
},
{
src: ['src/utils/**/*.js'],
dest: 'build/utils.min.js'
}
]
}
}
});Global options that apply to all task configurations.
interface PluginOptions {
// Platform preference for compiler execution
platform?: string | Array<string>;
// Additional command-line arguments for all compilations
extraArguments?: Array<string>;
// Maximum number of parallel compilations (0 = unlimited)
max_parallel_compilations?: number;
}Usage Examples:
// Gruntfile.js with plugin options
import { grunt as closureCompiler } from 'google-closure-compiler';
export default function(grunt) {
// Register with global options
closureCompiler(grunt, {
platform: ['native', 'java'], // Try native first, fallback to Java
extraArguments: ['--use_types_for_optimization'],
max_parallel_compilations: 4 // Limit parallel builds
});
grunt.initConfig({
'closure-compiler': {
main: {
files: [{
src: ['src/**/*.js'],
dest: 'dist/app.min.js'
}]
}
}
});
}Control parallel execution of multiple compilation targets.
// Plugin options for parallel compilation
interface ParallelOptions {
max_parallel_compilations?: number; // Max concurrent compilations
compile_in_batches?: number; // Deprecated: use max_parallel_compilations
}Usage Examples:
// Limit to 2 parallel compilations
closureCompiler(grunt, {
max_parallel_compilations: 2
});
// Configuration with many targets
grunt.initConfig({
'closure-compiler': {
module1: { files: [{ src: ['src/m1/**/*.js'], dest: 'dist/m1.js' }] },
module2: { files: [{ src: ['src/m2/**/*.js'], dest: 'dist/m2.js' }] },
module3: { files: [{ src: ['src/m3/**/*.js'], dest: 'dist/m3.js' }] },
module4: { files: [{ src: ['src/m4/**/*.js'], dest: 'dist/m4.js' }] }
// Only 2 will compile concurrently due to max_parallel_compilations: 2
}
});Use the args option for direct compiler flag specification.
// Alternative configuration using args
interface ArgsConfig {
options: {
args: CompilerOptions | Array<string>;
};
}Usage Examples:
grunt.initConfig({
'closure-compiler': {
// Using args object format
target1: {
options: {
args: {
js: ['src/**/*.js'],
compilation_level: 'ADVANCED',
js_output_file: 'dist/app.min.js'
}
}
},
// Using args array format (raw compiler flags)
target2: {
options: {
args: [
'--js', 'src/**/*.js',
'--compilation_level', 'SIMPLE',
'--js_output_file', 'dist/app.simple.js'
]
}
}
}
});The plugin provides integrated error handling and progress logging.
// Error handling behavior:
// - Missing source files generate warnings but don't fail the build
// - Compilation errors fail the build with detailed error messages
// - Success messages show the output file pathUsage Examples:
// Run with error handling
grunt.registerTask('build', function() {
grunt.task.run('closure-compiler:prod');
});
// Custom error handling
grunt.registerTask('safe-build', function() {
try {
grunt.task.run('closure-compiler:prod');
} catch (error) {
grunt.log.warn('Compilation failed, using unminified version');
// Fallback logic here
}
});The plugin automatically processes file paths and validates source files.
// File processing behavior:
interface FileProcessing {
// Filters out non-existent files with warnings
filterExistingFiles(filepaths: Array<string>): Array<string>;
// Warns about empty source file sets
validateSourceFiles(src: Array<string>): boolean;
// Sets js_output_file automatically from Grunt file configuration
setOutputFile(dest: string): void;
}The Grunt plugin uses internal stream classes for file processing and Gulp integration.
// VinylStream class for converting file paths to vinyl streams (internal)
// Available from: google-closure-compiler/lib/grunt/vinyl-stream.js
/**
* Readable stream that converts file paths to vinyl files
*/
class VinylStream extends Readable {
constructor(files: Array<string>, opts: { base?: string });
// Stream properties
_base: string;
_files: Array<string>;
// Readable stream implementation
_read(): Promise<void>;
}grunt.initConfig({
watch: {
js: {
files: ['src/**/*.js'],
tasks: ['closure-compiler:dev']
}
},
'closure-compiler': {
dev: {
options: {
compilation_level: 'WHITESPACE_ONLY',
formatting: 'PRETTY_PRINT'
},
files: [{
src: ['src/**/*.js'],
dest: 'build/app.js'
}]
}
}
});grunt.initConfig({
'closure-compiler': {
// Stage 1: Type checking only
typecheck: {
options: {
checks_only: true,
compilation_level: 'ADVANCED'
},
files: [{
src: ['src/**/*.js'],
dest: '/dev/null' // No output needed for type checking
}]
},
// Stage 2: Development build
dev: {
options: {
compilation_level: 'SIMPLE'
},
files: [{
src: ['src/**/*.js'],
dest: 'build/app.js'
}]
},
// Stage 3: Production build
prod: {
options: {
compilation_level: 'ADVANCED'
},
files: [{
src: ['src/**/*.js'],
dest: 'dist/app.min.js'
}]
}
}
});
grunt.registerTask('dev-build', ['closure-compiler:typecheck', 'closure-compiler:dev']);
grunt.registerTask('prod-build', ['closure-compiler:typecheck', 'closure-compiler:prod']);