grunt-contrib-uglify = function (grunt) { // Internal lib. var uglify = require('./lib/uglify').init(grunt); var getAvailableFiles = function (filesArray) { return filesArray.filter(function (filepath) { if (!grunt.file.exists(filepath)) { grunt.log.warn('Source file ' + chalk.cyan(filepath) + ' not found'); return false; } return true; }); }; grunt.registerMultiTask('uglify', 'Minify files with UglifyJS.', function() { // Merge task-specific and/or target-specific options with these defaults. var options = this.options({ banner: '', footer: '', compress: { warnings: false }, mangle: {}, beautify: false, report: 'min', expression: false, maxLineLen: 32000, ASCIIOnly: false, screwIE8: true, quoteStyle: 0 }); var footer = normalizeLf(options.footer); var mapNameGenerator, mapInNameGenerator; var created = { maps: 0, files: 0 }; var size = { before: 0, after: 0 }; // Iterate over all src-dest file pairs. this.files.forEach(function (f) { var availableFiles = getAvailableFiles(f.src); if (availableFiles.length === 0) { grunt.log.warn('Destination ' + chalk.cyan(f.dest) + ' not written because src files were empty.'); return; } // Warn on incompatible options if (options.expression && (options.compress || options.mangle)) { grunt.log.warn('Option ' + chalk.cyan('expression') + ' not compatible with ' + chalk.cyan('compress and mangle')); options.compress = false; options.mangle = false; } // function to get the name of the sourceMap if (typeof options.sourceMapName === 'function') { mapNameGenerator = options.sourceMapName; } // function to get the name of the sourceMapIn file if (typeof options.sourceMapIn === 'function') { if (availableFiles.length !== 1) { grunt.fail.warn('Cannot generate `sourceMapIn` for multiple source files.'); } mapInNameGenerator = options.sourceMapIn; } // dynamically create destination sourcemap name if (mapNameGenerator) { try { options.generatedSourceMapName = mapNameGenerator(f.dest); } catch (e) { err = new Error('SourceMap failed.'); err.origError = e; grunt.fail.warn(err); } // If no name is passed append .map to the filename } else if (!options.sourceMapName) { options.generatedSourceMapName = f.dest + '.map'; } else { options.generatedSourceMapName = options.sourceMapName; } // Dynamically create incoming sourcemap names if (mapInNameGenerator) { try { options.sourceMapIn = mapInNameGenerator(availableFiles[0]); } catch (e) { err = new Error('SourceMapInName failed.'); err.origError = e; grunt.fail.warn(err); } } // Calculate the path from the dest file to the sourcemap for the // sourceMappingURL reference // If sourceMapUrl is defined, use this instead if (options.sourceMap) { var destToSourceMapPath, sourceMapBasename; if (!options.sourceMapUrl) { destToSourceMapPath = relativePath(f.dest, options.generatedSourceMapName); sourceMapBasename = path.basename(options.generatedSourceMapName); options.destToSourceMap = destToSourceMapPath + sourceMapBasename; } else { options.destToSourceMap = options.sourceMapUrl; } } // Minify files, warn and fail on error. var result; try { result = uglify.minify(availableFiles, f.dest, options); } catch (e) { console.log(e); err = new Error('Uglification failed.'); if (e.message) { err.message += '\n' + e.message + '. \n'; if (e.line) { err.message += 'Line ' + e.line + ' in ' + availableFiles + '\n'; } } err.orig ...
n/a
init = function (grunt) { var exports = {}; // Minify with UglifyJS. // From https://github.com/mishoo/UglifyJS2 // API docs at http://lisperator.net/uglifyjs/ exports.minify = function(files, dest, options) { options = options || {}; grunt.verbose.write('Minifying with UglifyJS...'); var topLevel = null; var totalCode = ''; var sourcesContent = {}; var outputOptions = getOutputOptions(options, dest); var output = UglifyJS.OutputStream(outputOptions); // Grab and parse all source files files.forEach(function(file) { var code = grunt.file.read(file); totalCode += code; // The src file name must be relative to the source map for things to work var basename = path.basename(file); var fileDir = path.dirname(file); var sourceMapDir = path.dirname(options.generatedSourceMapName); var relativePath = path.relative(sourceMapDir, fileDir); var pathPrefix = relativePath ? relativePath + path.sep : ''; var bare_returns = options.bare_returns || undefined; // Convert paths to use forward slashes for sourcemap use in the browser file = uriPath(pathPrefix + basename); sourcesContent[file] = code; topLevel = UglifyJS.parse(code, { filename: file, toplevel: topLevel, expression: options.expression, bare_returns: bare_returns }); }); // Wrap code in a common js wrapper. if (options.wrap) { topLevel = topLevel.wrap_commonjs(options.wrap, options.exportAll); } // Wrap code in closure with configurable arguments/parameters list. if (options.enclose) { var argParamList = Object.keys(options.enclose).map(function(key) { return key + ':' + options.enclose[key]; }); topLevel = topLevel.wrap_enclose(argParamList); } var topLevelCache = null; if (options.nameCache) { topLevelCache = UglifyJS.readNameCache(options.nameCache, 'vars'); } // Need to call this before we mangle or compress, // and call after any compression or ast altering if (options.expression === false) { topLevel.figure_out_scope({ screw_ie8: options.screwIE8, cache: topLevelCache }); } if (options.compress !== false) { if (options.compress === true) { options.compress = {}; } if (options.compress.warnings !== true) { options.compress.warnings = false; } if (options.screwIE8 === false) { options.compress.screw_ie8 = false; } var compressor = UglifyJS.Compressor(options.compress); topLevel = compressor.compress(topLevel); // Need to figure out scope again after source being altered if (options.expression === false) { topLevel.figure_out_scope({ screw_ie8: options.screwIE8, cache: topLevelCache }); } } var mangleExclusions = { vars: [], props: [] }; if (options.reserveDOMProperties) { mangleExclusions = UglifyJS.readDefaultReservedFile(); } if (options.exceptionsFiles) { try { options.exceptionsFiles.forEach(function(filename) { mangleExclusions = UglifyJS.readReservedFile(filename, mangleExclusions); }); } catch (ex) { grunt.warn(ex); } } var cache = null; if (options.nameCache) { cache = UglifyJS.readNameCache(options.nameCache, 'props'); } if (typeof options.mangleProperties !== 'undefined' && options.mangleProperties !== false) { // if options.mangleProperties is a boolean (true) convert it into an object if (typeof options.mangleProperties !== 'object') { options.mangleProperties = {}; } options.mangleProperties.reserved = mangleExclusions ? mangleExclusions.props : null; options.mangleProperties.cache = cache; topLevel = UglifyJS.mangle_properties(topLevel, options.mangleProperties); if (options.nameCache) { UglifyJS.writeNameCache(options.nameCache, 'props', cache); } ...
...
// Converts \r\n to \n
function normalizeLf(string) {
return string.replace(/\r\n/g, '\n');
}
module.exports = function(grunt) {
// Internal lib.
var uglify = require('./lib/uglify').init(grunt);
var getAvailableFiles = function (filesArray) {
return filesArray.filter(function (filepath) {
if (!grunt.file.exists(filepath)) {
grunt.log.warn('Source file ' + chalk.cyan(filepath) + ' not found');
return false;
}
...