153 lines
4.2 KiB
JavaScript
153 lines
4.2 KiB
JavaScript
'use strict';
|
|
const through = require("through2");
|
|
const uglify = require('terser');
|
|
const minimatch = require('minimatch');
|
|
const path = require('path');
|
|
const Vinyl = require('vinyl');
|
|
const PluginError = require('plugin-error');
|
|
const colors = require('ansi-colors');
|
|
const reSourceMapComment = /\n\/\/# sourceMappingURL=.+?$/;
|
|
const pathSeparatorRe = /[\/\\]/g;
|
|
const jsExtensions = /\.m?js$/;
|
|
|
|
function parseExt(ext, byDefault = ".js") {
|
|
|
|
let _ext = {};
|
|
|
|
if (!ext) {
|
|
_ext = {
|
|
min: "-min" + byDefault,
|
|
src: byDefault
|
|
}
|
|
} else if (typeof ext === "string") {
|
|
_ext = {
|
|
min: ext,
|
|
src: byDefault
|
|
}
|
|
} else {
|
|
_ext = {
|
|
min: ext.min || "-min" + byDefault,
|
|
src: ext.src || byDefault
|
|
}
|
|
}
|
|
|
|
return _ext;
|
|
|
|
}
|
|
|
|
function formatError(error, file) {
|
|
let filePath = error.file === 'stdin' ? file.path : error.file;
|
|
let message = '';
|
|
|
|
filePath = filePath ? filePath : file.path;
|
|
let relativePath = path.relative(process.cwd(), filePath);
|
|
|
|
message += colors.underline(relativePath) + '\n';
|
|
message += error.message + ' (line: ' + error.line + ', col: ' + error.col + ', pos: ' + error.pos;
|
|
error.message = colors.red(message);
|
|
return error;
|
|
}
|
|
|
|
module.exports = function(opt) {
|
|
|
|
//Set the options to the one provided or an empty object.
|
|
let options = opt || {};
|
|
|
|
//Set options output to itself, or, if null an empty object.
|
|
options.output = options.output || {};
|
|
|
|
function minify(file, encoding, callback) {
|
|
|
|
if (file.isNull()) {
|
|
this.push(file);
|
|
return callback();
|
|
}
|
|
|
|
if (file.isStream()) {
|
|
this.emit('end');
|
|
return new callback(PluginError('gulp-minify', 'Streaming not supported:' + file.path));
|
|
}
|
|
|
|
let ignore = false;
|
|
|
|
if (options.exclude) {
|
|
ignore = options.exclude.some(function(item) {
|
|
return path.dirname(file.path).split(pathSeparatorRe).some(function(pathName) {
|
|
return minimatch(pathName, item);
|
|
});
|
|
});
|
|
}
|
|
|
|
if (!ignore && options.ignoreFiles) {
|
|
ignore = options.ignoreFiles.some(function(item) {
|
|
return minimatch(path.basename(file.path), item);
|
|
});
|
|
}
|
|
|
|
if (ignore || !path.extname(file.path).match(jsExtensions)) {
|
|
this.push(file);
|
|
return callback();
|
|
}
|
|
|
|
let mangled, originalSourceMap;
|
|
|
|
if (file.sourceMap) {
|
|
options.outSourceMap = file.relative;
|
|
if (file.sourceMap.mappings !== '') {
|
|
options.inSourceMap = file.sourceMap;
|
|
}
|
|
originalSourceMap = file.sourceMap;
|
|
}
|
|
|
|
if (options.preserveComments === 'all') {
|
|
options.output.comments = true;
|
|
} else if (options.preserveComments === 'some') {
|
|
|
|
options.output.comments = /^!|@preserve|@license|@cc_on/i;
|
|
} else if (typeof options.preserveComments === 'function') {
|
|
options.output.comments = options.preserveComments;
|
|
}
|
|
options.fromString = options.hasOwnProperty("fromString") ? options.fromString : true;
|
|
|
|
//Parse the extensions form the options.
|
|
let ext = parseExt(options.ext, path.extname(file.path));
|
|
|
|
let min_file = new Vinyl({
|
|
base: file.base,
|
|
path: Array.isArray(ext.min) ? file.path.replace(ext.min[0], ext.min[1]) : file.path.replace(jsExtensions, ext.min),
|
|
});
|
|
|
|
const uglifyOptions = {
|
|
mangle : options.mangle !== undefined ? options.mangle : true,
|
|
output : options.output !== undefined ? options.output : null,
|
|
compress : options.compress !== undefined ? options.compress : {},
|
|
sourceMap: !!file.sourceMap
|
|
};
|
|
|
|
try {
|
|
mangled = uglify.minify(String(file.contents), uglifyOptions);
|
|
min_file.contents = new Buffer(mangled.code.replace(reSourceMapComment, ''));
|
|
} catch (e) {
|
|
this.emit('end');
|
|
return callback(new PluginError('gulp-minify', formatError(e, file)));
|
|
}
|
|
|
|
if (file.sourceMap) {
|
|
min_file.sourceMap = JSON.parse(mangled.map);
|
|
min_file.sourceMap.sourcesContent = originalSourceMap.sourcesContent;
|
|
min_file.sourceMap.sources = originalSourceMap.sources;
|
|
}
|
|
|
|
this.push(min_file);
|
|
|
|
if (options.noSource !== true) {
|
|
file.path = file.path.replace(jsExtensions, ext.src);
|
|
this.push(file);
|
|
}
|
|
|
|
callback();
|
|
}
|
|
|
|
return through.obj(minify);
|
|
};
|