node-uglifier-es
Version:
Fully auto merging and uglifying a whole NodeJs project into one file with external files option. Recompiled from Zsolt Istvan Szabo's work with uglify-es instead of uglify-js-harmony.
308 lines (280 loc) • 10.2 kB
JavaScript
// Generated by CoffeeScript 2.3.1
(function() {
///*!
// * node-uglifier
// * Copyright (c) 2014 Zsolt Szabo Istvan
// * MIT Licensed
// *
// */
var UglifyJS, _, fs, fsExtra, packageUtils, path, strEscapeMap;
fsExtra = require('fs-extra');
fs = require('fs');
UglifyJS = require('uglify-es');
path = require('path');
_ = require('underscore');
packageUtils = module.exports;
// Check if `module` is a native module (like `net` or `tty`).
packageUtils.isNative = function(module) {
var err;
try {
return require.resolve(module) === module;
} catch (error) {
err = error;
return false;
}
};
packageUtils.readFile = function(pathAbs, encoding = 'utf8') {
var options;
options = {encoding};
return fs.readFileSync(pathAbs, options);
};
packageUtils.getAst = function(code) {
return UglifyJS.parse(code);
};
//absolulte file path
packageUtils.getMatchingFiles = function(rootPath, dirAndFileArray) {
var destination, dirOrFile, fileName, filestats, j, len, me, r, rootDir;
r = [];
rootDir = fs.lstatSync(rootPath).isDirectory() ? path.resolve(rootPath) : path.dirname(path.resolve(rootPath));
for (j = 0, len = dirAndFileArray.length; j < len; j++) {
dirOrFile = dirAndFileArray[j];
destination = path.resolve(rootDir, dirOrFile);
try {
filestats = fs.lstatSync(destination);
} catch (error) {
me = error;
//probably missing extension, file not found
filestats = null;
}
if (filestats && filestats.isDirectory()) {
//we have directory
fs.readdirSync(destination).reduce((function(prev, curr) {
prev.push(path.join(destination, curr));
return prev;
}), r);
} else {
if (path.extname(destination) === "") {
fileName = path.basename(destination);
fs.readdirSync(path.dirname(destination)).filter(function(fileNameLoc) {
return fileNameLoc.indexOf(fileName) !== -1;
}).reduce((function(prev, curr) {
prev.push(path.join(destination, curr));
return prev;
}), r);
} else {
r.push(destination);
}
}
}
return r;
};
packageUtils.getIfNonNativeNotFilteredNonNpm = function(fileAbs, filters, possibleExtensions) {
var existingExtensions, r;
//if path can be resolved and it is file than it is non native, non npm
r = null;
if (path.extname(fileAbs) === "") {
existingExtensions = possibleExtensions.filter(function(ext) {
return fs.existsSync(fileAbs + "." + ext);
});
if (existingExtensions.length > 1) {
throw new Error(" multiple matching extensions problem for " + fileAbs);
}
r = existingExtensions.length === 1 ? fileAbs + "." + existingExtensions[0] : null;
} else {
r = fs.existsSync(fileAbs) ? fileAbs : null;
}
if (r) {
if (filters.filter(function(fFile) {
return path.normalize(fFile) === path.normalize(r);
}).length > 0) {
r = null;
console.log(fileAbs + " was filtered ");
}
}
return r;
};
packageUtils.walkExpressions = function(astNode, parentNode, depth) {
if (depth > 5) {
return null;
}
if (astNode.name === "require") {
return (parentNode != null ? parentNode.args : void 0) || astNode.args;
} else if (astNode.expression != null) {
return packageUtils.walkExpressions(astNode.expression, astNode, depth + 1);
}
};
//assume no directory is native module
//returns the file path of modules if file exists
//if no extension specified first existing possibleExtensions is used
packageUtils.getRequireStatements = function(ast, file, possibleExtensions = ["js", "coffee"], packNodeModules = false) {
var fileDir, handleRequireNode, r;
r = [];
fileDir = path.dirname(file);
handleRequireNode = function(text, args) {
var hasPathInIt, me, pathOfModule, pathOfModuleLoc, pathOfModuleLocStats, pathOfModuleRaw, rs;
pathOfModuleRaw = args[0].value;
if (pathOfModuleRaw == null) {
throw new Error("probably dynamic");
}
//has / or \ in the string
hasPathInIt = !_.isEmpty(pathOfModuleRaw.match("/")) || !_.isEmpty(pathOfModuleRaw.match(/\\/));
if (hasPathInIt) {
//it is not a module, do nothing
} else if (packNodeModules) {
//find node_module directory, than main in package json if no index.js found
pathOfModuleRaw = require.resolve(pathOfModuleRaw);
} else {
//it is module and not packed
return false;
}
pathOfModuleLoc = path.resolve(fileDir, pathOfModuleRaw);
try {
pathOfModuleLocStats = fs.lstatSync(pathOfModuleLoc);
} catch (error) {
me = error;
}
if (pathOfModuleLocStats && pathOfModuleLocStats.isDirectory()) {
pathOfModuleLoc = path.resolve(pathOfModuleLoc, "index");
}
//if path can be resolved and it is file than it is non native, non npm
pathOfModule = packageUtils.getIfNonNativeNotFilteredNonNpm(pathOfModuleLoc, [], possibleExtensions);
rs = {
text,
path: pathOfModule
};
if (pathOfModule) {
return r.push(rs);
}
};
ast.walk(new UglifyJS.TreeWalker(function(node) {
var args, me, ref, requireArgs, text, text2, walkedArgs;
if ((node instanceof UglifyJS.AST_Call) && (node.start.value === 'require' || (node.start.value === 'new' && node.expression.print_to_string() === "require"))) {
text = node.print_to_string({
beautify: false
});
// console.log(text)
//expression argument takes precedence over the first argument of require
requireArgs = node != null ? (ref = node.expression) != null ? ref.args : void 0 : void 0;
walkedArgs = packageUtils.walkExpressions(node, null, 1);
if (_.isEmpty(requireArgs)) {
requireArgs = node.args;
}
try {
// if args.length != 1 then
// throw new Error ("in file: " + file + " require supposed to have 1 argument: " + text)
if (requireArgs.length !== 1 || !handleRequireNode(text, requireArgs) && !_.isEmpty(walkedArgs)) {
text2 = `require('${walkedArgs[0].value}')`;
handleRequireNode(text2, walkedArgs);
}
} catch (error) {
me = error;
console.log("Warning!:");
console.log("unhandled require type in file: " + file + " the problematic statement: " + text + " probably something fancy going on! " + " the error: " + me.message);
}
return true;
} else if ((node instanceof UglifyJS.AST_Call) && (node.start.value === 'new' && node.expression.start.value === "(" && node.expression.print_to_string().indexOf("require") !== -1)) {
args = node.expression.args;
text = "require" + "('" + args[0].value + "')";
// console.log(text)
handleRequireNode(text, args);
console.log("second " + text);
return true;
} else {
}
}));
return r;
};
strEscapeMap = {
'\b': '\\b',
'\f': '\\f',
'\n': '\\n',
'\r': '\\r',
'\t': '\\t'
};
packageUtils.hexifyString = function(str) {
var char, i, j, r, ref;
r = "";
if (!str.length > 0) {
return r;
}
for (i = j = 0, ref = str.length - 1; (0 <= ref ? j <= ref : j >= ref); i = 0 <= ref ? ++j : --j) {
char = str[i];
if (strEscapeMap[char]) {
r += r[char];
} else if ('\\' === char) {
r += '\\' + str[++i];
} else {
r += '\\x' + str.charCodeAt(i).toString(16);
}
}
return r;
};
packageUtils.deHexifyString = function(str) {
return str.toString();
};
packageUtils.getSourceHexified = function(ast) {
var hexify, stream, transformer;
hexify = function(node) {
var hex, obj, text;
if (node instanceof UglifyJS.AST_String) {
text = node.getValue();
hex = packageUtils.hexifyString(text);
obj = _.extend({}, node);
obj.value = hex;
return new UglifyJS.AST_String(obj);
} else {
}
};
transformer = new UglifyJS.TreeTransformer(null, hexify);
stream = new UglifyJS.OutputStream;
stream.print_string = function(str) {
return this.print('"' + str + '"');
};
ast = ast.transform(transformer);
ast.print(stream);
return stream.toString();
};
//packageUtils.replaceAll=(find, replace, str)->
// return str.replace(new RegExp(find, 'g'), replace);
packageUtils.replaceRequireStatement = function(textIn, orig, replacement) {
var isReplaced, text, withTheOtherQuotation;
text = textIn;
isReplaced = false;
text = text.replace(orig, function(token) {
isReplaced = true;
return replacement;
});
if (!isReplaced) {
withTheOtherQuotation = orig;
if (withTheOtherQuotation.indexOf("'") !== -1) {
withTheOtherQuotation = withTheOtherQuotation.replace(/[']/ig, '"');
} else {
withTheOtherQuotation = withTheOtherQuotation.replace(/["]/ig, "'");
}
text = text.replace(withTheOtherQuotation, function(token) {
isReplaced = true;
return replacement;
});
}
if (!isReplaced) {
throw new Error(orig + " was not replaced with " + replacement);
}
return text;
};
packageUtils.countWords = function(sentence) {
var index, words;
index = {};
words = sentence.replace(/[.,?!;()"'-]/g, " ").replace(/\s+/g, " ").toLowerCase().split(" ");
words.forEach(function(word) {
if (!(index.hasOwnProperty(word))) {
index[word] = 0;
}
return index[word]++;
});
return index;
};
// console.log([text,path.resolve(fileDir,pathOfModule),packageUtils.isNative(pathOfModule)].join(" | "))
//print_to_string({ beautify: false }).replace(/-/g, "_") AST_Assign node.left,right
// return true; no descend
}).call(this);
//# sourceMappingURL=packageUtils.js.map