The google-closure-compiler package provides a Gulp plugin for stream-based JavaScript compilation with vinyl file support, source map integration, and flexible configuration options.
Creates a Transform stream for integrating Closure Compiler into Gulp pipelines.
/**
* Create a Closure Compiler transform stream
* @param compilationOptions - Compiler configuration options
* @param pluginOptions - Plugin-specific configuration
* @returns CompilationStream for use in Gulp pipelines
*/
function gulpPlugin(
compilationOptions: Object | Array<string>,
pluginOptions?: {
streamMode?: 'BOTH' | 'IN';
logger?: any;
pluginName?: string;
platform?: string | Array<string>;
requireStreamInput?: boolean;
extraCommandArguments?: Array<string>;
}
): CompilationStream;Basic Usage:
import gulp from 'gulp';
import { gulp as closureCompiler } from 'google-closure-compiler';
export function minifyJs() {
return gulp.src('src/**/*.js')
.pipe(closureCompiler({
compilation_level: 'SIMPLE',
warning_level: 'VERBOSE',
output_wrapper: '(function(){%output%})();'
}))
.pipe(gulp.dest('dist/'));
}The returned stream extends Node.js Transform stream with additional functionality.
class CompilationStream extends Transform {
constructor(compilationOptions: Object | Array<string>, pluginOptions?: Object);
// Properties
compilationOptions_: Object | Array<string>;
streamMode_: 'BOTH' | 'IN';
logger_: any;
PLUGIN_NAME_: string;
extraCommandArgs_: Array<string>;
fileList_: Array<vinyl.File>;
platform: 'native' | 'java';
// Create stream without requiring input files
src(): CompilationStream;
// Stream processing methods (inherited from Transform)
_transform(file: vinyl.File, encoding: string, callback: Function): void;
_flush(callback: Function): Promise<void>;
}The Gulp plugin uses several internal utilities for file format conversion and stream management.
// File format conversion utilities (internal)
// Available from: google-closure-compiler/lib/gulp/...
/**
* Convert vinyl files to JSON format for compiler input
* @param files - Array of vinyl files
* @returns Array of JSON file objects
*/
function filesToJson(files: Array<vinyl.File>): Array<{
src: string;
path?: string;
sourceMap?: string;
}>;
/**
* Convert JSON file objects back to vinyl files
* @param fileList - Array of JSON file objects from compiler output
* @returns Array of vinyl files
*/
function jsonToVinyl(fileList: Array<{
path: string;
src: string;
source_map?: string;
sourceMap?: string;
}>): Array<vinyl.File>;Control how the plugin handles input and output streams.
interface StreamModeOptions {
streamMode?: 'BOTH' | 'IN';
}
// 'BOTH' (default): Full streaming with input and output files
// 'IN': Input streaming only (used internally by Grunt plugin)Usage Examples:
// Standard streaming mode (BOTH)
gulp.src('src/**/*.js')
.pipe(closureCompiler({
compilation_level: 'ADVANCED'
}))
.pipe(gulp.dest('dist/'));
// Input-only streaming mode
gulp.src('src/**/*.js')
.pipe(closureCompiler({
compilation_level: 'SIMPLE',
js_output_file: 'dist/bundle.js'
}, {
streamMode: 'IN'
}));Seamless integration with gulp-sourcemaps for source map processing.
// Source map support through vinyl-sourcemaps-apply
// Automatically applies source maps when create_source_map is usedUsage Examples:
import gulp from 'gulp';
import sourcemaps from 'gulp-sourcemaps';
import { gulp as closureCompiler } from 'google-closure-compiler';
export function buildWithSourceMaps() {
return gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(closureCompiler({
compilation_level: 'ADVANCED',
create_source_map: true,
source_map_format: 'V3'
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('dist/'));
}Configure compiler platform preferences and execution options.
interface PlatformOptions {
platform?: string | Array<string>; // Platform preference
extraCommandArguments?: Array<string>; // Additional compiler arguments
}Usage Examples:
// Force native binary usage
gulp.src('src/**/*.js')
.pipe(closureCompiler({
compilation_level: 'SIMPLE'
}, {
platform: 'native'
}))
.pipe(gulp.dest('dist/'));
// Platform fallback with extra arguments
gulp.src('src/**/*.js')
.pipe(closureCompiler({
compilation_level: 'ADVANCED'
}, {
platform: ['native', 'java'],
extraCommandArguments: ['--use_types_for_optimization']
}))
.pipe(gulp.dest('dist/'));Use the plugin without input streams for compiler flag-based compilation.
// Create stream without input files using src() method
interface StandaloneOptions {
requireStreamInput?: boolean; // Set to false for standalone mode
}Usage Examples:
// Compile files specified in compiler flags
export function compileStandalone() {
return closureCompiler({
js: ['src/file1.js', 'src/file2.js'],
compilation_level: 'ADVANCED',
js_output_file: 'dist/bundle.js'
}, {
requireStreamInput: false
})
.src() // Creates empty input stream
.pipe(gulp.dest('dist/'));
}
// Alternative: Files from glob patterns in compiler options
export function compileGlob() {
return closureCompiler({
js: 'src/**/*.js',
compilation_level: 'SIMPLE',
js_output_file: 'dist/app.js'
})
.src()
.pipe(gulp.dest('dist/'));
}Comprehensive error handling with detailed error reporting.
// Error types handled:
// - PluginError: Custom error class for build tool integration
// - Process spawn errors: Java/native binary execution issues
// - Compilation errors: Closure Compiler syntax/type errors
// - JSON parsing errors: Internal stream communication issuesUsage Examples:
import gulp from 'gulp';
import { gulp as closureCompiler } from 'google-closure-compiler';
export function buildWithErrorHandling() {
return gulp.src('src/**/*.js')
.pipe(closureCompiler({
compilation_level: 'ADVANCED',
warning_level: 'VERBOSE'
}))
.on('error', function(err) {
console.error('Compilation failed:', err.message);
this.emit('end'); // Continue pipeline
})
.pipe(gulp.dest('dist/'));
}
// Global error handling
gulp.on('error', (err) => {
console.error('Gulp error:', err);
});Integration with Gulp logging systems and custom loggers.
interface LoggingOptions {
logger?: any; // Custom logger (fancy-log, gulp-util.log, console)
pluginName?: string; // Plugin name for error messages
}Usage Examples:
import fancyLog from 'fancy-log';
export function buildWithLogging() {
return gulp.src('src/**/*.js')
.pipe(closureCompiler({
compilation_level: 'ADVANCED'
}, {
logger: fancyLog,
pluginName: 'my-closure-compiler'
}))
.pipe(gulp.dest('dist/'));
}import gulp from 'gulp';
import { gulp as closureCompiler } from 'google-closure-compiler';
// Development build
export function buildDev() {
return gulp.src('src/**/*.js')
.pipe(closureCompiler({
compilation_level: 'WHITESPACE_ONLY',
formatting: 'PRETTY_PRINT',
debug: true
}))
.pipe(gulp.dest('build/dev/'));
}
// Production build
export function buildProd() {
return gulp.src('src/**/*.js')
.pipe(closureCompiler({
compilation_level: 'ADVANCED',
warning_level: 'VERBOSE',
create_source_map: true
}))
.pipe(gulp.dest('build/prod/'));
}
// Parallel builds
export const buildAll = gulp.parallel(buildDev, buildProd);// Compile separate modules
export function buildModules() {
const modules = ['core', 'utils', 'ui'];
const tasks = modules.map(module => {
return gulp.src(`src/${module}/**/*.js`)
.pipe(closureCompiler({
compilation_level: 'SIMPLE',
module_resolution: 'NODE',
process_common_js_modules: true
}))
.pipe(gulp.dest(`dist/${module}/`));
});
return Promise.all(tasks);
}import gulp from 'gulp';
import babel from 'gulp-babel';
import uglify from 'gulp-uglify';
import { gulp as closureCompiler } from 'google-closure-compiler';
// Multi-stage processing pipeline
export function buildComplete() {
return gulp.src('src/**/*.js')
// Stage 1: Babel transpilation
.pipe(babel({
presets: ['@babel/preset-env']
}))
// Stage 2: Closure Compiler optimization
.pipe(closureCompiler({
compilation_level: 'SIMPLE',
language_out: 'ECMASCRIPT5'
}))
// Stage 3: Additional minification
.pipe(uglify())
.pipe(gulp.dest('dist/'));
}import gulp from 'gulp';
import { gulp as closureCompiler } from 'google-closure-compiler';
// Watch task with fast compilation
export function watchJs() {
return gulp.watch('src/**/*.js', () => {
return gulp.src('src/**/*.js')
.pipe(closureCompiler({
compilation_level: 'WHITESPACE_ONLY' // Fast compilation for development
}))
.pipe(gulp.dest('build/'));
});
}
// Production watch (slower but optimized)
export function watchProd() {
return gulp.watch('src/**/*.js', gulp.series(buildProd));
}interface FullPluginOptions {
// Stream behavior
streamMode?: 'BOTH' | 'IN';
requireStreamInput?: boolean;
// Execution environment
platform?: string | Array<string>;
extraCommandArguments?: Array<string>;
// Logging and debugging
logger?: any;
pluginName?: string;
}
interface CompilationOptions {
// All Closure Compiler flags supported
js?: string | Array<string>;
compilation_level?: 'WHITESPACE_ONLY' | 'SIMPLE' | 'ADVANCED';
js_output_file?: string;
create_source_map?: boolean | string;
warning_level?: 'QUIET' | 'DEFAULT' | 'VERBOSE';
language_in?: string;
language_out?: string;
module_resolution?: 'BROWSER' | 'NODE' | 'WEBPACK';
[key: string]: any;
}