point cli to built version

This commit is contained in:
Moshe Brevda 2022-12-19 11:53:38 +02:00
parent e09d92dc52
commit 84464b7750

View File

@ -8,10 +8,27 @@ require("../tools/tty");
var fs = require("fs");
var info = require("../package.json");
var path = require("path");
var UglifyJS = require("../tools/node");
var UglifyJS = require("..");
var skip_keys = [ "cname", "fixed", "in_arg", "inlined", "length_read", "parent_scope", "redef", "scope", "unused" ];
var truthy_keys = [ "optional", "pure", "terminal", "uses_arguments", "uses_eval", "uses_with" ];
var skip_keys = [
"cname",
"fixed",
"in_arg",
"inlined",
"length_read",
"parent_scope",
"redef",
"scope",
"unused",
];
var truthy_keys = [
"optional",
"pure",
"terminal",
"uses_arguments",
"uses_eval",
"uses_with",
];
var files = {};
var options = {};
@ -41,7 +58,8 @@ while (args.length) {
break;
} else if (arg[1] == "-") {
process_option(arg.slice(2));
} else [].forEach.call(arg.slice(1), function(letter, index, arg) {
} else
[].forEach.call(arg.slice(1), function (letter, index, arg) {
if (!(letter in short_forms)) fatal("invalid option -" + letter);
process_option(short_forms[letter], index + 1 < arg.length);
});
@ -63,28 +81,39 @@ function process_option(name, no_value) {
for (var name in defaults) {
var option = defaults[name];
if (option && typeof option == "object") {
text.push("--" + ({
text.push(
"--" +
({
output: "beautify",
sourceMap: "source-map",
}[name] || name) + " options:");
}[name] || name) +
" options:"
);
text.push(format_object(option));
text.push("");
} else {
if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
toplevels.push([ {
if (padding.length < name.length)
padding = Array(name.length + 1).join(" ");
toplevels.push([
{
keep_fargs: "keep-fargs",
keep_fnames: "keep-fnames",
nameCache: "name-cache",
}[name] || name, option ]);
}[name] || name,
option,
]);
}
}
toplevels.forEach(function(tokens) {
text.push("--" + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]);
toplevels.forEach(function (tokens) {
text.push(
"--" + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]
);
});
print(text.join("\n"));
break;
default:
print([
print(
[
"Usage: uglifyjs [files...] [options]",
"",
"Options:",
@ -127,7 +156,8 @@ function process_option(name, no_value) {
"(internal debug use only)",
" --in-situ Warning: replaces original source files with minified output.",
" --reduce-test Reduce a standalone test case (assumes cloned repository).",
].join("\n"));
].join("\n")
);
}
process.exit();
case "version":
@ -135,10 +165,17 @@ function process_option(name, no_value) {
process.exit();
case "config-file":
var config = JSON.parse(read_file(read_value(true)));
if (config.mangle && config.mangle.properties && config.mangle.properties.regex) {
config.mangle.properties.regex = UglifyJS.parse(config.mangle.properties.regex, {
if (
config.mangle &&
config.mangle.properties &&
config.mangle.properties.regex
) {
config.mangle.properties.regex = UglifyJS.parse(
config.mangle.properties.regex,
{
expression: true,
}).value;
}
).value;
}
for (var key in config) if (!(key in options)) options[key] = config[key];
break;
@ -195,11 +232,18 @@ function process_option(name, no_value) {
break;
case "define":
if (typeof options.compress != "object") options.compress = {};
options.compress.global_defs = parse_js(read_value(true), options.compress.global_defs, "define");
options.compress.global_defs = parse_js(
read_value(true),
options.compress.global_defs,
"define"
);
break;
case "mangle-props":
if (typeof options.mangle != "object") options.mangle = {};
options.mangle.properties = parse_js(read_value(), options.mangle.properties);
options.mangle.properties = parse_js(
read_value(),
options.mangle.properties
);
break;
case "module":
options.module = true;
@ -239,9 +283,11 @@ function process_option(name, no_value) {
return args.shift();
}
}
if (!output && options.sourceMap && options.sourceMap.url != "inline") fatal("cannot write source map to STDOUT");
if (specified["beautify"] && specified["output-opts"]) fatal("--beautify cannot be used with --output-opts");
[ "compress", "mangle" ].forEach(function(name) {
if (!output && options.sourceMap && options.sourceMap.url != "inline")
fatal("cannot write source map to STDOUT");
if (specified["beautify"] && specified["output-opts"])
fatal("--beautify cannot be used with --output-opts");
["compress", "mangle"].forEach(function (name) {
if (!(name in options)) options[name] = false;
});
if (/^ast|spidermonkey$/.test(output)) {
@ -249,38 +295,47 @@ if (/^ast|spidermonkey$/.test(output)) {
options.output.ast = true;
options.output.code = false;
}
if (options.parse && (options.parse.acorn || options.parse.spidermonkey)
&& options.sourceMap && options.sourceMap.content == "inline") {
if (
options.parse &&
(options.parse.acorn || options.parse.spidermonkey) &&
options.sourceMap &&
options.sourceMap.content == "inline"
) {
fatal("inline source map only works with built-in parser");
}
if (options.warnings) {
UglifyJS.AST_Node.log_function(print_error, options.warnings == "verbose");
delete options.warnings;
}
var convert_path = function(name) {
var convert_path = function (name) {
return name;
};
if (typeof options.sourceMap == "object" && "base" in options.sourceMap) {
convert_path = function() {
convert_path = (function () {
var base = options.sourceMap.base;
delete options.sourceMap.base;
return function(name) {
return function (name) {
return path.relative(base, name);
};
}();
})();
}
if (specified["self"]) {
if (paths.length) UglifyJS.AST_Node.warn("Ignoring input files since --self was passed");
if (paths.length)
UglifyJS.AST_Node.warn("Ignoring input files since --self was passed");
if (!options.wrap) options.wrap = "UglifyJS";
paths = UglifyJS.FILES;
} else if (paths.length) {
paths = simple_glob(paths);
}
if (specified["in-situ"]) {
if (output && output != "spidermonkey" || specified["reduce-test"] || specified["self"]) {
if (
(output && output != "spidermonkey") ||
specified["reduce-test"] ||
specified["self"]
) {
fatal("incompatible options specified");
}
paths.forEach(function(name) {
paths.forEach(function (name) {
print(name);
if (/^ast|spidermonkey$/.test(name)) fatal("invalid file name specified");
files = {};
@ -289,19 +344,29 @@ if (specified["in-situ"]) {
run();
});
} else if (paths.length) {
paths.forEach(function(name) {
paths.forEach(function (name) {
files[convert_path(name)] = read_file(name);
});
run();
} else {
var timerId = process.stdin.isTTY && process.argv.length < 3 && setTimeout(function() {
print_error("Waiting for input... (use `--help` to print usage information)");
var timerId =
process.stdin.isTTY &&
process.argv.length < 3 &&
setTimeout(function () {
print_error(
"Waiting for input... (use `--help` to print usage information)"
);
}, 1500);
var chunks = [];
process.stdin.setEncoding("utf8");
process.stdin.once("data", function() {
process.stdin
.once("data", function () {
clearTimeout(timerId);
}).on("data", process.stdin.isTTY ? function(chunk) {
})
.on(
"data",
process.stdin.isTTY
? function (chunk) {
// emulate console input termination via Ctrl+D / Ctrl+Z
var match = /[\x04\x1a]\r?\n?$/.exec(chunk);
if (match) {
@ -311,9 +376,12 @@ if (specified["in-situ"]) {
} else {
chunks.push(chunk);
}
} : function(chunk) {
}
: function (chunk) {
chunks.push(chunk);
}).once("end", function() {
}
)
.once("end", function () {
files = { STDIN: chunks.join("") };
run();
});
@ -321,14 +389,16 @@ if (specified["in-situ"]) {
}
function convert_ast(fn) {
return UglifyJS.AST_Node.from_mozilla_ast(Object.keys(files).reduce(fn, null));
return UglifyJS.AST_Node.from_mozilla_ast(
Object.keys(files).reduce(fn, null)
);
}
function run() {
var content = options.sourceMap && options.sourceMap.content;
if (content && content != "inline") {
UglifyJS.AST_Node.info("Using input source map: {content}", {
content : content,
content: content,
});
options.sourceMap.content = read_file(content, content);
}
@ -336,19 +406,19 @@ function run() {
if (options.parse) {
if (options.parse.acorn) {
var annotations = Object.create(null);
files = convert_ast(function(toplevel, name) {
files = convert_ast(function (toplevel, name) {
var content = files[name];
var list = annotations[name] = [];
var list = (annotations[name] = []);
var prev = -1;
return require("acorn").parse(content, {
allowHashBang: true,
ecmaVersion: "latest",
locations: true,
onComment: function(block, text, start, end) {
onComment: function (block, text, start, end) {
var match = /[@#]__PURE__/.exec(text);
if (!match) {
if (start != prev) return;
match = [ list[prev] ];
match = [list[prev]];
}
while (/\s/.test(content[end])) end++;
list[end] = match[0];
@ -360,20 +430,23 @@ function run() {
sourceType: "module",
});
});
files.walk(new UglifyJS.TreeWalker(function(node) {
files.walk(
new UglifyJS.TreeWalker(function (node) {
if (!(node instanceof UglifyJS.AST_Call)) return;
var list = annotations[node.start.file];
var pure = list[node.start.pos];
if (!pure) {
var tokens = node.start.parens;
if (tokens) for (var i = 0; !pure && i < tokens.length; i++) {
if (tokens)
for (var i = 0; !pure && i < tokens.length; i++) {
pure = list[tokens[i].pos];
}
}
if (pure) node.pure = pure;
}));
})
);
} else if (options.parse.spidermonkey) {
files = convert_ast(function(toplevel, name) {
files = convert_ast(function (toplevel, name) {
var obj = JSON.parse(files[name]);
if (!toplevel) return obj;
toplevel.body = toplevel.body.concat(obj.body);
@ -399,7 +472,9 @@ function run() {
if (result.error) {
var ex = result.error;
if (ex.name == "SyntaxError") {
print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
print_error(
"Parse error at " + ex.filename + ":" + ex.line + "," + ex.col
);
var file = files[ex.filename];
if (file) {
var col = ex.col;
@ -428,17 +503,22 @@ function run() {
if (!options.compress && !options.mangle) {
var toplevel = result.ast;
if (!(toplevel instanceof UglifyJS.AST_Toplevel)) {
if (!(toplevel instanceof UglifyJS.AST_Statement)) toplevel = new UglifyJS.AST_SimpleStatement({
if (!(toplevel instanceof UglifyJS.AST_Statement))
toplevel = new UglifyJS.AST_SimpleStatement({
body: toplevel,
});
toplevel = new UglifyJS.AST_Toplevel({
body: [ toplevel ],
body: [toplevel],
});
}
toplevel.figure_out_scope({});
}
print(JSON.stringify(result.ast, function(key, value) {
if (value) switch (key) {
print(
JSON.stringify(
result.ast,
function (key, value) {
if (value)
switch (key) {
case "enclosed":
return value.length ? value.map(symdef) : undefined;
case "functions":
@ -453,15 +533,18 @@ function run() {
if (value instanceof UglifyJS.Dictionary) return;
if (value instanceof UglifyJS.AST_Node) {
var result = {
_class: "AST_" + value.TYPE
_class: "AST_" + value.TYPE,
};
value.CTOR.PROPS.forEach(function(prop) {
value.CTOR.PROPS.forEach(function (prop) {
result[prop] = value[prop];
});
return result;
}
return value;
}, 2));
},
2
)
);
} else if (output == "spidermonkey") {
print(JSON.stringify(result.ast.to_mozilla_ast(), null, 2));
} else if (output) {
@ -471,7 +554,9 @@ function run() {
for (var name in options.output) {
if (!/^ast|code$/.test(name)) opts[name] = options.output[name];
}
code = UglifyJS.AST_Node.from_mozilla_ast(result.ast.to_mozilla_ast()).print_to_string(opts);
code = UglifyJS.AST_Node.from_mozilla_ast(
result.ast.to_mozilla_ast()
).print_to_string(opts);
} else {
code = result.code;
}
@ -481,14 +566,15 @@ function run() {
print(result.code);
}
if (nameCache) fs.writeFileSync(nameCache, JSON.stringify(options.nameCache));
if (result.timings) for (var phase in result.timings) {
if (result.timings)
for (var phase in result.timings) {
print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s");
}
}
function fatal(message) {
if (message instanceof Error) {
message = message.stack.replace(/^\S*?Error:/, "ERROR:")
message = message.stack.replace(/^\S*?Error:/, "ERROR:");
} else {
message = "ERROR: " + message;
}
@ -501,11 +587,11 @@ function fatal(message) {
// Argument `paths` must be an array of strings.
// Returns an array of strings. Garbage in, garbage out.
function simple_glob(paths) {
return paths.reduce(function(paths, glob) {
return paths.reduce(function (paths, glob) {
if (/\*|\?/.test(glob)) {
var dir = path.dirname(glob);
try {
var entries = fs.readdirSync(dir).filter(function(name) {
var entries = fs.readdirSync(dir).filter(function (name) {
try {
return fs.statSync(path.join(dir, name)).isFile();
} catch (ex) {
@ -514,15 +600,22 @@ function simple_glob(paths) {
});
} catch (ex) {}
if (entries) {
var pattern = "^" + path.basename(glob)
var pattern =
"^" +
path
.basename(glob)
.replace(/[.+^$[\]\\(){}]/g, "\\$&")
.replace(/\*/g, "[^/\\\\]*")
.replace(/\?/g, "[^/\\\\]") + "$";
.replace(/\?/g, "[^/\\\\]") +
"$";
var mod = process.platform === "win32" ? "i" : "";
var rx = new RegExp(pattern, mod);
var results = entries.filter(function(name) {
var results = entries
.filter(function (name) {
return rx.test(name);
}).sort().map(function(name) {
})
.sort()
.map(function (name) {
return path.join(dir, name);
});
if (results.length) {
@ -547,10 +640,12 @@ function read_file(path, default_value) {
function parse_js(value, options, flag) {
if (!options || typeof options != "object") options = Object.create(null);
if (typeof value == "string") try {
if (typeof value == "string")
try {
UglifyJS.parse(value, {
expression: true
}).walk(new UglifyJS.TreeWalker(function(node) {
expression: true,
}).walk(
new UglifyJS.TreeWalker(function (node) {
if (node instanceof UglifyJS.AST_Assign) {
var name = node.left.print_to_string();
var value = node.right;
@ -563,7 +658,10 @@ function parse_js(value, options, flag) {
}
return true;
}
if (node instanceof UglifyJS.AST_Symbol || node instanceof UglifyJS.AST_PropAccess) {
if (
node instanceof UglifyJS.AST_Symbol ||
node instanceof UglifyJS.AST_PropAccess
) {
var name = node.print_to_string();
options[name] = true;
return true;
@ -571,11 +669,14 @@ function parse_js(value, options, flag) {
if (!(node instanceof UglifyJS.AST_Sequence)) throw node;
function to_string(value) {
return value instanceof UglifyJS.AST_Constant ? value.value : value.print_to_string({
quote_keys: true
return value instanceof UglifyJS.AST_Constant
? value.value
: value.print_to_string({
quote_keys: true,
});
}
}));
})
);
} catch (ex) {
if (flag) {
fatal("cannot parse arguments for '" + flag + "': " + value);
@ -587,13 +688,15 @@ function parse_js(value, options, flag) {
}
function skip_property(key, value) {
return skip_keys.indexOf(key) >= 0
return (
skip_keys.indexOf(key) >= 0 ||
// only skip truthy_keys if their value is falsy
|| truthy_keys.indexOf(key) >= 0 && !value;
(truthy_keys.indexOf(key) >= 0 && !value)
);
}
function symdef(def) {
var ret = (1e6 + def.id) + " " + def.name;
var ret = 1e6 + def.id + " " + def.name;
if (def.mangled_name) ret += " " + def.mangled_name;
return ret;
}
@ -601,11 +704,16 @@ function symdef(def) {
function format_object(obj) {
var lines = [];
var padding = "";
Object.keys(obj).map(function(name) {
if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
return [ name, JSON.stringify(obj[name]) ];
}).forEach(function(tokens) {
lines.push(" " + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]);
Object.keys(obj)
.map(function (name) {
if (padding.length < name.length)
padding = Array(name.length + 1).join(" ");
return [name, JSON.stringify(obj[name])];
})
.forEach(function (tokens) {
lines.push(
" " + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]
);
});
return lines.join("\n");
}