grunt-contrib-concat is a Grunt plugin that provides comprehensive file concatenation functionality for JavaScript build processes. It enables developers to combine multiple source files into single output files with configurable options including custom separators, banner and footer text, source map generation, and JavaScript banner comment stripping.
npm install grunt-contrib-concat --save-devLoading the plugin in your Gruntfile:
grunt.loadNpmTasks('grunt-contrib-concat');grunt.initConfig({
concat: {
options: {
separator: ';'
},
dist: {
src: ['src/intro.js', 'src/project.js', 'src/outro.js'],
dest: 'dist/built.js'
}
}
});Running the task:
grunt concat
grunt concat:targetgrunt-contrib-concat is built around several key components:
concat multi-task with Grunt for file concatenation operationsThe main multi-task that performs file concatenation with extensive configuration options.
/**
* Grunt multi-task for concatenating files
* Registered as 'concat' task in Grunt
* Command Usage: grunt concat
*/
grunt.registerMultiTask('concat', function() {
// Task implementation
});
/**
* Task configuration options
*/
interface ConcatOptions {
/** String to join concatenated files (default: grunt.util.linefeed) */
separator?: string;
/** String prepended to output, processed as template (default: '') */
banner?: string;
/** String appended to output, processed as template (default: '') */
footer?: string;
/** Strip JavaScript banner comments (default: false) */
stripBanners?: boolean | StripBannersOptions;
/** Process files before concatenation (default: false) */
process?: boolean | object | ProcessFunction;
/** Generate source map (default: false) */
sourceMap?: boolean;
/** Custom source map name/location (default: undefined) */
sourceMapName?: string | SourceMapNameFunction;
/** Source map style: 'embed', 'link', or 'inline' (default: 'embed') */
sourceMapStyle?: 'embed' | 'link' | 'inline';
}
interface StripBannersOptions {
/** Strip all block comments (default: false) */
block?: boolean;
/** Strip leading line comments (default: false) */
line?: boolean;
}
type ProcessFunction = (src: string, filepath: string) => string;
type SourceMapNameFunction = (dest: string) => string;Basic Configuration Examples:
// Simple concatenation with custom separator
grunt.initConfig({
concat: {
options: {
separator: ';'
},
dist: {
src: ['src/intro.js', 'src/project.js', 'src/outro.js'],
dest: 'dist/built.js'
}
}
});
// With banner and footer templates
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
stripBanners: true,
banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %> */',
footer: '\n/* End of file */'
},
dist: {
src: ['src/project.js'],
dest: 'dist/built.js'
}
}
});
// Multiple targets
grunt.initConfig({
concat: {
basic: {
src: ['src/main.js'],
dest: 'dist/basic.js'
},
extras: {
src: ['src/main.js', 'src/extras.js'],
dest: 'dist/with_extras.js'
}
}
});
// With source maps
grunt.initConfig({
concat: {
options: {
sourceMap: true,
sourceMapStyle: 'link'
},
dist: {
src: ['src/file1.js', 'src/file2.js'],
dest: 'dist/combined.js'
}
}
});Utility module for stripping banner comments from JavaScript source files.
/**
* Factory function that creates comment utilities
* @param grunt - Grunt instance
* @returns Object with comment utility methods
*/
function init(grunt) {
return {
stripBanner: stripBanner
};
}
/**
* Strip banner comments from source code
* @param src - Source code to process
* @param options - Stripping options
* @returns Source code with banners stripped
*/
function stripBanner(src, options) {
// Implementation strips various comment patterns
}
interface StripBannerOptions {
/** Strip leading line comments (//) */
line?: boolean;
/** Strip all block comments (/* */) vs preserving /*! */ comments */
block?: boolean;
}Usage Example:
var comment = require('./tasks/lib/comment').init(grunt);
// Strip default banners (/* */ but not /*! */)
var cleaned = comment.stripBanner(sourceCode);
// Strip all block comments
var cleaned = comment.stripBanner(sourceCode, { block: true });
// Strip line comments and block comments
var cleaned = comment.stripBanner(sourceCode, { block: true, line: true });Utility module for generating and managing source maps during file concatenation.
/**
* Factory function that creates sourcemap utilities
* @param grunt - Grunt instance
* @returns Object with sourcemap utility methods
*/
function init(grunt) {
return {
helper: helper
};
}
/**
* Create a source map concatenation helper
* @param files - Grunt files object with src/dest
* @param options - Source map generation options
* @returns SourceMapConcatHelper instance
*/
function helper(files, options) {
return new SourceMapConcatHelper(options);
}
/**
* Helper class for managing source map generation during concatenation
*/
class SourceMapConcatHelper {
constructor(options);
/** Add content without source mapping */
add(src: string): void;
/** Add file content with source mapping */
addlines(src: string, filename: string): string;
/** Write source map to file (unless inline style) */
write(): void;
/** Generate sourceMappingURL comment */
url(): string;
}Usage Example:
var sourcemap = require('./tasks/lib/sourcemap').init(grunt);
// Create helper for source map generation
var sourceMapHelper = sourcemap.helper(files, {
sourceMapStyle: 'embed',
sourceMapName: 'custom.map'
});
// Add banner
sourceMapHelper.add(banner);
// Add file content with mapping
var processedSrc = sourceMapHelper.addlines(fileContent, filepath);
// Write source map and get URL
sourceMapHelper.write();
var sourceMappingURL = sourceMapHelper.url();Advanced file processing with custom functions for complex build scenarios.
/**
* Custom process function signature
* @param src - Source file content
* @param filepath - Path to the source file
* @returns Processed source content
*/
type ProcessFunction = (src: string, filepath: string) => string;Usage Example:
grunt.initConfig({
concat: {
dist: {
options: {
banner: "'use strict';\n",
process: function(src, filepath) {
// Remove all 'use strict' statements and add single one at top
return '// Source: ' + filepath + '\n' +
src.replace(/(^|\n)[ \t]*('use strict'|"use strict");?\s*/g, '$1');
}
},
files: {
'dist/built.js': ['src/project.js']
}
}
}
});The plugin provides warnings and error handling for common issues:
nonull: true is set)stripBanners with sourceMapStyle: 'link')// Enable warnings for missing files
grunt.initConfig({
concat: {
missing: {
src: ['src/invalid_or_missing_file.js'],
dest: 'compiled.js',
nonull: true // Enables warnings for missing files
}
}
});/**
* Grunt files configuration object
*/
interface GruntFiles {
src: string[];
dest: string;
}
/**
* Template processing options for Grunt templates
*/
interface TemplateProcessOptions {
data?: object;
delimiters?: string;
}