160 lines
4.4 KiB
JavaScript
160 lines
4.4 KiB
JavaScript
/*
|
|
* grunt-contrib-uglify
|
|
* https://gruntjs.com/
|
|
*
|
|
* Copyright (c) 2017 "Cowboy" Ben Alman, contributors
|
|
* Licensed under the MIT license.
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
// External libs.
|
|
var path = require('path');
|
|
var UglifyJS = require('uglify-js');
|
|
var uriPath = require('uri-path');
|
|
var domprops = require('uglify-js/tools/domprops');
|
|
|
|
// Converts \r\n to \n
|
|
function normalizeLf(string) {
|
|
return string.replace(/\r\n/g, '\n');
|
|
}
|
|
|
|
function toCache(cache, key) {
|
|
if (cache[key]) {
|
|
cache[key].props = UglifyJS.Dictionary.fromObject(cache[key].props);
|
|
} else {
|
|
cache[key] = {
|
|
cname: -1,
|
|
props: new UglifyJS.Dictionary()
|
|
};
|
|
}
|
|
return cache[key];
|
|
}
|
|
|
|
exports.init = function(grunt) {
|
|
var exports = {};
|
|
|
|
// Minify with UglifyJS.
|
|
// From https://github.com/mishoo/UglifyJS2
|
|
exports.minify = function(files, dest, options) {
|
|
options = options || {};
|
|
|
|
grunt.verbose.write('Minifying with UglifyJS...');
|
|
|
|
var totalCode = '';
|
|
var minifyOptions = {
|
|
compress: options.compress,
|
|
ie8: options.ie8,
|
|
keep_fnames: options.keep_fnames,
|
|
mangle: options.mangle,
|
|
output: options.output || {},
|
|
parse: options.parse || {},
|
|
sourceMap: options.sourceMap,
|
|
toplevel: options.toplevel,
|
|
wrap: options.wrap
|
|
};
|
|
|
|
if (options.banner) {
|
|
minifyOptions.output.preamble = normalizeLf(options.banner);
|
|
}
|
|
|
|
if (options.beautify) {
|
|
minifyOptions.output.beautify = true;
|
|
for (var key in options.beautify) {
|
|
minifyOptions.output[key] = options.beautify[key];
|
|
}
|
|
}
|
|
|
|
var cache;
|
|
if (options.nameCache) {
|
|
try {
|
|
cache = JSON.parse(grunt.file.read(options.nameCache));
|
|
} catch (ex) {
|
|
cache = {};
|
|
}
|
|
}
|
|
|
|
if (minifyOptions.mangle) {
|
|
if (typeof minifyOptions.mangle !== 'object') {
|
|
minifyOptions.mangle = {};
|
|
}
|
|
if (cache) {
|
|
minifyOptions.mangle.cache = toCache(cache, 'vars');
|
|
}
|
|
if (!Array.isArray(minifyOptions.mangle.reserved)) {
|
|
minifyOptions.mangle.reserved = [];
|
|
}
|
|
if (minifyOptions.mangle.properties) {
|
|
if (typeof minifyOptions.mangle.properties !== 'object') {
|
|
minifyOptions.mangle.properties = {};
|
|
}
|
|
if (cache) {
|
|
minifyOptions.mangle.properties.cache = toCache(cache, 'props');
|
|
}
|
|
if (!Array.isArray(minifyOptions.mangle.properties.reserved)) {
|
|
minifyOptions.mangle.properties.reserved = [];
|
|
}
|
|
if (options.reserveDOMProperties) {
|
|
domprops.forEach(function(name) {
|
|
UglifyJS.push_uniq(minifyOptions.mangle.properties.reserved, name);
|
|
});
|
|
}
|
|
}
|
|
if (options.exceptionsFiles) {
|
|
options.exceptionsFiles.forEach(function(file) {
|
|
try {
|
|
var obj = JSON.parse(grunt.file.read(file));
|
|
if (minifyOptions.mangle && obj.vars) {
|
|
obj.vars.forEach(function(name) {
|
|
UglifyJS.push_uniq(minifyOptions.mangle.reserved, name);
|
|
});
|
|
}
|
|
if (minifyOptions.mangle.properties && obj.props) {
|
|
obj.props.forEach(function(name) {
|
|
UglifyJS.push_uniq(minifyOptions.mangle.properties.reserved, name);
|
|
});
|
|
}
|
|
} catch (ex) {
|
|
grunt.warn(ex);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
var result = UglifyJS.minify(files.reduce(function(o, 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 : '';
|
|
|
|
// Convert paths to use forward slashes for sourcemap use in the browser
|
|
o[uriPath(pathPrefix + basename)] = code;
|
|
return o;
|
|
}, {}), minifyOptions);
|
|
if (result.error) {
|
|
throw result.error;
|
|
}
|
|
|
|
if (options.nameCache) {
|
|
grunt.file.write(options.nameCache, JSON.stringify(cache, function(key, value) {
|
|
return value instanceof UglifyJS.Dictionary ? value.toObject() : value;
|
|
}));
|
|
}
|
|
|
|
grunt.verbose.ok();
|
|
|
|
return {
|
|
max: totalCode,
|
|
min: result.code,
|
|
sourceMap: result.map
|
|
};
|
|
};
|
|
|
|
return exports;
|
|
};
|