unify CLI & API under minify()
- refactor `screw_ie8` to `ie8` - compact `sourceMap` options - more stringent verification on input `options` - toplevel shorthands - `ie8` - `keep_fnames` - `toplevel` - deprecated `fromString` in `minify()` - `minify()` no longer handles any `fs` operations - unify order of operations for `mangle_properties()` on CLI & API - `bin/uglifyjs` used to `mangle_properties()` before even `Compressor` - `minify()` used to `mangle_properties()` after `Compressor` but before `mangle_names()` - both will now do `Compressor`, `mangle_names()` then `mangle_properties()` - `options.parse` / `--parse` for parser options beyond `bare_returns` closes #96 closes #1366 fixes #124 fixes #263 fixes #379 fixes #423 fixes #576 fixes #737 fixes #958 fixes #1036 fixes #1175 fixes #1220 fixes #1223 fixes #1280
This commit is contained in:
parent
2244743545
commit
1a56c2f31d
822
bin/uglifyjs
822
bin/uglifyjs
|
|
@ -3,633 +3,257 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var UglifyJS = require("../tools/node");
|
|
||||||
var sys = require("util");
|
|
||||||
var yargs = require("yargs");
|
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
|
var info = require("../package.json");
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
var acorn;
|
var program = require("commander");
|
||||||
var screw_ie8 = true;
|
var UglifyJS = require("../tools/node");
|
||||||
var ARGS = yargs
|
|
||||||
.usage("$0 input1.js [input2.js ...] [options]\n\
|
|
||||||
Use a single dash to read input from the standard input.\
|
|
||||||
\n\n\
|
|
||||||
NOTE: by default there is no mangling/compression.\n\
|
|
||||||
Without [options] it will simply parse input files and dump the AST\n\
|
|
||||||
with whitespace and comments discarded. To achieve compression and\n\
|
|
||||||
mangling you need to use `-c` and `-m`.\
|
|
||||||
")
|
|
||||||
.describe("source-map", "Specify an output file where to generate source map.")
|
|
||||||
.describe("source-map-root", "The path to the original source to be included in the source map.")
|
|
||||||
.describe("source-map-url", "The path to the source map to be added in //# sourceMappingURL. Defaults to the value passed with --source-map.")
|
|
||||||
.describe("source-map-inline", "Write base64-encoded source map to the end of js output. Disabled by default")
|
|
||||||
.describe("source-map-include-sources", "Pass this flag if you want to include the content of source files in the source map as sourcesContent property.")
|
|
||||||
.describe("in-source-map", "Input source map, useful if you're compressing JS that was generated from some other original code.")
|
|
||||||
.describe("screw-ie8", "Do not support Internet Explorer 6/7/8. This flag is enabled by default.")
|
|
||||||
.describe("support-ie8", "Support non-standard Internet Explorer 6/7/8 javascript.")
|
|
||||||
.describe("expr", "Parse a single expression, rather than a program (for parsing JSON)")
|
|
||||||
.describe("p", "Skip prefix for original filenames that appear in source maps. \
|
|
||||||
For example -p 3 will drop 3 directories from file names and ensure they are relative paths. \
|
|
||||||
You can also specify -p relative, which will make UglifyJS figure out itself the relative paths between original sources, \
|
|
||||||
the source map and the output file.")
|
|
||||||
.describe("o", "Output file (default STDOUT).")
|
|
||||||
.describe("b", "Beautify output/specify output options.")
|
|
||||||
.describe("m", "Mangle names/pass mangler options.")
|
|
||||||
.describe("r", "Reserved names to exclude from mangling.")
|
|
||||||
.describe("c", "Enable compressor/pass compressor options. \
|
|
||||||
Pass options like -c hoist_vars=false,if_return=false. \
|
|
||||||
Use -c with no argument to use the default compression options.")
|
|
||||||
.describe("d", "Global definitions")
|
|
||||||
.describe("e", "Embed everything in a big function, with a configurable parameter/argument list.")
|
|
||||||
|
|
||||||
.describe("comments", "Preserve copyright comments in the output. \
|
var files = {};
|
||||||
By default this works like Google Closure, keeping JSDoc-style comments that contain \"@license\" or \"@preserve\". \
|
var options = {
|
||||||
You can optionally pass one of the following arguments to this flag:\n\
|
compress: false,
|
||||||
- \"all\" to keep all comments\n\
|
mangle: false
|
||||||
- a valid JS RegExp like `/foo/`or `/^!/` to keep only matching comments.\n\
|
|
||||||
\
|
|
||||||
Note that currently not *all* comments can be kept when compression is on, \
|
|
||||||
because of dead code removal or cascading statements into sequences.")
|
|
||||||
|
|
||||||
.describe("preamble", "Preamble to prepend to the output. You can use this to insert a \
|
|
||||||
comment, for example for licensing information. This will not be \
|
|
||||||
parsed, but the source map will adjust for its presence.")
|
|
||||||
|
|
||||||
.describe("stats", "Display operations run time on STDERR.")
|
|
||||||
.describe("acorn", "Use Acorn for parsing.")
|
|
||||||
.describe("spidermonkey", "Assume input files are SpiderMonkey AST format (as JSON).")
|
|
||||||
.describe("self", "Build itself (UglifyJS2) as a library (implies --wrap=UglifyJS --export-all)")
|
|
||||||
.describe("wrap", "Embed everything in a big function, making the “exports” and “global” variables available. \
|
|
||||||
You need to pass an argument to this option to specify the name that your module will take when included in, say, a browser.")
|
|
||||||
.describe("export-all", "Only used when --wrap, this tells UglifyJS to add code to automatically export all globals.")
|
|
||||||
.describe("lint", "Display some scope warnings")
|
|
||||||
.describe("v", "Verbose")
|
|
||||||
.describe("V", "Print version number and exit.")
|
|
||||||
.describe("noerr", "Don't throw an error for unknown options in -c, -b or -m.")
|
|
||||||
.describe("bare-returns", "Allow return outside of functions. Useful when minifying CommonJS modules.")
|
|
||||||
.describe("keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.")
|
|
||||||
.describe("quotes", "Quote style (0 - auto, 1 - single, 2 - double, 3 - original)")
|
|
||||||
.describe("reserved-file", "File containing reserved names")
|
|
||||||
.describe("reserve-domprops", "Make (most?) DOM properties reserved for --mangle-props")
|
|
||||||
.describe("mangle-props", "Mangle property names (0 - disabled, 1 - mangle all properties, 2 - mangle unquoted properies)")
|
|
||||||
.describe("mangle-regex", "Only mangle property names matching the regex")
|
|
||||||
.describe("name-cache", "File to hold mangled names mappings")
|
|
||||||
.describe("pure-funcs", "List of functions that can be safely removed if their return value is not used")
|
|
||||||
.describe("dump-spidermonkey-ast", "Dump SpiderMonkey AST to stdout.")
|
|
||||||
.describe("wrap-iife", "Wrap IIFEs in parenthesis. Note: this disables the negate_iife compression option")
|
|
||||||
|
|
||||||
.alias("p", "prefix")
|
|
||||||
.alias("o", "output")
|
|
||||||
.alias("v", "verbose")
|
|
||||||
.alias("b", "beautify")
|
|
||||||
.alias("m", "mangle")
|
|
||||||
.alias("c", "compress")
|
|
||||||
.alias("d", "define")
|
|
||||||
.alias("r", "reserved")
|
|
||||||
.alias("V", "version")
|
|
||||||
.alias("e", "enclose")
|
|
||||||
.alias("q", "quotes")
|
|
||||||
|
|
||||||
.string("source-map")
|
|
||||||
.string("source-map-root")
|
|
||||||
.string("source-map-url")
|
|
||||||
.string("b")
|
|
||||||
.string("beautify")
|
|
||||||
.string("m")
|
|
||||||
.string("mangle")
|
|
||||||
.string("mangle-props-debug")
|
|
||||||
.string("c")
|
|
||||||
.string("compress")
|
|
||||||
.string("d")
|
|
||||||
.string("define")
|
|
||||||
.string("e")
|
|
||||||
.string("enclose")
|
|
||||||
.string("comments")
|
|
||||||
.string("wrap")
|
|
||||||
.string("p")
|
|
||||||
.string("prefix")
|
|
||||||
.string("name-cache")
|
|
||||||
|
|
||||||
.array("reserved-file")
|
|
||||||
.array("pure-funcs")
|
|
||||||
|
|
||||||
.boolean("expr")
|
|
||||||
.boolean("source-map-inline")
|
|
||||||
.boolean("source-map-include-sources")
|
|
||||||
.boolean("screw-ie8")
|
|
||||||
.boolean("support-ie8")
|
|
||||||
.boolean("export-all")
|
|
||||||
.boolean("self")
|
|
||||||
.boolean("v")
|
|
||||||
.boolean("verbose")
|
|
||||||
.boolean("stats")
|
|
||||||
.boolean("acorn")
|
|
||||||
.boolean("spidermonkey")
|
|
||||||
.boolean("dump-spidermonkey-ast")
|
|
||||||
.boolean("lint")
|
|
||||||
.boolean("V")
|
|
||||||
.boolean("version")
|
|
||||||
.boolean("noerr")
|
|
||||||
.boolean("bare-returns")
|
|
||||||
.boolean("keep-fnames")
|
|
||||||
.boolean("reserve-domprops")
|
|
||||||
.boolean("wrap-iife")
|
|
||||||
|
|
||||||
.wrap(80)
|
|
||||||
|
|
||||||
.argv
|
|
||||||
;
|
|
||||||
|
|
||||||
normalize(ARGS);
|
|
||||||
|
|
||||||
if (ARGS.noerr) {
|
|
||||||
UglifyJS.DefaultsError.croak = function(msg, defs) {
|
|
||||||
print_error("WARN: " + msg);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.version || ARGS.V) {
|
|
||||||
var json = require("../package.json");
|
|
||||||
print(json.name + ' ' + json.version);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.ast_help) {
|
|
||||||
var desc = UglifyJS.describe_ast();
|
|
||||||
print(typeof desc == "string" ? desc : JSON.stringify(desc, null, 2));
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.h || ARGS.help) {
|
|
||||||
print(yargs.help());
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.acorn) {
|
|
||||||
acorn = require("acorn");
|
|
||||||
}
|
|
||||||
|
|
||||||
var COMPRESS = getOptions("c", true);
|
|
||||||
var MANGLE = getOptions("m", true);
|
|
||||||
var BEAUTIFY = getOptions("b", true);
|
|
||||||
var RESERVED = null;
|
|
||||||
|
|
||||||
if (ARGS.reserved_file) ARGS.reserved_file.forEach(function(filename){
|
|
||||||
RESERVED = UglifyJS.readReservedFile(filename, RESERVED);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (ARGS.reserve_domprops) {
|
|
||||||
RESERVED = UglifyJS.readDefaultReservedFile(RESERVED);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.d) {
|
|
||||||
if (COMPRESS) COMPRESS.global_defs = getOptions("d");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.pure_funcs) {
|
|
||||||
if (COMPRESS) COMPRESS.pure_funcs = ARGS.pure_funcs;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.r) {
|
|
||||||
if (MANGLE) MANGLE.except = ARGS.r.replace(/^\s+|\s+$/g).split(/\s*,+\s*/);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RESERVED && MANGLE) {
|
|
||||||
if (!MANGLE.except) MANGLE.except = RESERVED.vars;
|
|
||||||
else MANGLE.except = MANGLE.except.concat(RESERVED.vars);
|
|
||||||
}
|
|
||||||
|
|
||||||
function readNameCache(key) {
|
|
||||||
return UglifyJS.readNameCache(ARGS.name_cache, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
function writeNameCache(key, cache) {
|
|
||||||
return UglifyJS.writeNameCache(ARGS.name_cache, key, cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
function extractRegex(str) {
|
|
||||||
if (/^\/.*\/[a-zA-Z]*$/.test(str)) {
|
|
||||||
var regex_pos = str.lastIndexOf("/");
|
|
||||||
return new RegExp(str.substr(1, regex_pos - 1), str.substr(regex_pos + 1));
|
|
||||||
} else {
|
|
||||||
throw new Error("Invalid regular expression: " + str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.quotes === true) {
|
|
||||||
ARGS.quotes = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.mangle_props === true) {
|
|
||||||
ARGS.mangle_props = 1;
|
|
||||||
} else if (ARGS.mangle_props === "unquoted") {
|
|
||||||
ARGS.mangle_props = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
var OUTPUT_OPTIONS = {
|
|
||||||
beautify : BEAUTIFY ? true : false,
|
|
||||||
max_line_len : 32000,
|
|
||||||
preamble : ARGS.preamble || null,
|
|
||||||
quote_style : ARGS.quotes != null ? ARGS.quotes : 0,
|
|
||||||
};
|
};
|
||||||
|
program._name = info.name;
|
||||||
if (ARGS.mangle_props == 2) {
|
program.version(info.version);
|
||||||
OUTPUT_OPTIONS.keep_quoted_props = true;
|
program.parseArgv = program.parse;
|
||||||
if (COMPRESS && !("properties" in COMPRESS))
|
program.parse = undefined;
|
||||||
COMPRESS.properties = false;
|
program.option("-p --parse <options>", "Specify parser options.", parseJS("parse", true));
|
||||||
|
program.option("-c --compress [options]", "Enable compressor/specify compressor options.", parseJS("compress", true));
|
||||||
|
program.option("-m --mangle [options]", "Mangle names/specify mangler options.", parseJS("mangle", true));
|
||||||
|
program.option("-b --beautify [options]", "Beautify output/specify output options.", parseJS("beautify", true));
|
||||||
|
program.option("-o --output <file>", "Output file (default STDOUT).");
|
||||||
|
program.option("--comments [filter]", "Preserve copyright comments in the output.");
|
||||||
|
program.option("--config-file <file>", "Read minify() options from JSON file.");
|
||||||
|
program.option("-d --define <expr>[=value]", "Global definitions.", parseJS("define"));
|
||||||
|
program.option("--ie8", "Support non-standard Internet Explorer 8.");
|
||||||
|
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
|
||||||
|
program.option("--self", "Build UglifyJS2 as a library (implies --wrap UglifyJS)");
|
||||||
|
program.option("--source-map [options]", "Enable source map/specify source map options.", parseSourceMap());
|
||||||
|
program.option("--stats", "Display operations run time on STDERR.")
|
||||||
|
program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
|
||||||
|
program.option("--wrap <name>", "Embed everything as a function with “exports” corresponding to “name” globally.");
|
||||||
|
program.arguments("[files...]").parseArgv(process.argv);
|
||||||
|
if (program.configFile) {
|
||||||
|
options = JSON.parse(readFile(program.configFile));
|
||||||
}
|
}
|
||||||
|
if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
||||||
if (ARGS.support_ie8 === true && ARGS.screw_ie8 !== true) {
|
fatal("ERROR: cannot write source map to STDOUT");
|
||||||
screw_ie8 = false;
|
|
||||||
}
|
}
|
||||||
|
[
|
||||||
if (COMPRESS) COMPRESS.screw_ie8 = screw_ie8;
|
"compress",
|
||||||
if (MANGLE) MANGLE.screw_ie8 = screw_ie8;
|
"ie8",
|
||||||
OUTPUT_OPTIONS.screw_ie8 = screw_ie8;
|
"mangle",
|
||||||
|
"sourceMap",
|
||||||
if (ARGS.keep_fnames) {
|
"toplevel",
|
||||||
if (COMPRESS) COMPRESS.keep_fnames = true;
|
"wrap"
|
||||||
if (MANGLE) MANGLE.keep_fnames = true;
|
].forEach(function(name) {
|
||||||
|
if (name in program) {
|
||||||
|
options[name] = program[name];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (program.beautify) {
|
||||||
|
options.output = typeof program.beautify == "object" ? program.beautify : {};
|
||||||
|
if (!("beautify" in options.output)) {
|
||||||
|
options.output.beautify = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (program.comments) {
|
||||||
if (ARGS.wrap_iife) {
|
if (typeof options.output != "object") options.output = {};
|
||||||
if (COMPRESS) COMPRESS.negate_iife = false;
|
options.output.comments = typeof program.comments == "string" ? program.comments : "some";
|
||||||
OUTPUT_OPTIONS.wrap_iife = true;
|
|
||||||
}
|
}
|
||||||
|
if (program.define) {
|
||||||
if (BEAUTIFY)
|
if (typeof options.compress != "object") options.compress = {};
|
||||||
UglifyJS.merge(OUTPUT_OPTIONS, BEAUTIFY);
|
if (typeof options.compress.global_defs != "object") options.compress.global_defs = {};
|
||||||
|
for (var expr in program.define) {
|
||||||
if (ARGS.comments === "") {
|
options.compress.global_defs[expr] = program.define[expr];
|
||||||
OUTPUT_OPTIONS.comments = "some";
|
}
|
||||||
|
}
|
||||||
|
if (program.keepFnames) {
|
||||||
|
options.keep_fnames = true;
|
||||||
|
}
|
||||||
|
if (program.parse) {
|
||||||
|
if (program.parse.acorn || program.parse.spidermonkey) {
|
||||||
|
if (program.sourceMap) fatal("ERROR: inline source map only works with built-in parser");
|
||||||
|
} else {
|
||||||
|
options.parse = program.parse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (program.self) {
|
||||||
|
if (program.args.length) {
|
||||||
|
console.error("WARN: Ignoring input files since --self was passed");
|
||||||
|
}
|
||||||
|
if (!options.wrap) options.wrap = "UglifyJS";
|
||||||
|
simple_glob(UglifyJS.FILES).forEach(function(path) {
|
||||||
|
files[path] = readFile(path);
|
||||||
|
});
|
||||||
|
run();
|
||||||
|
} else if (program.args.length) {
|
||||||
|
simple_glob(program.args).forEach(function(path) {
|
||||||
|
files[path] = readFile(path);
|
||||||
|
});
|
||||||
|
run();
|
||||||
} else {
|
} else {
|
||||||
OUTPUT_OPTIONS.comments = ARGS.comments;
|
var chunks = [];
|
||||||
|
process.stdin.setEncoding('utf-8');
|
||||||
|
process.stdin.on('data', function (chunk) {
|
||||||
|
chunks.push(chunk);
|
||||||
|
}).on('end', function () {
|
||||||
|
files = [ chunks.join("") ];
|
||||||
|
run();
|
||||||
|
});
|
||||||
|
process.openStdin();
|
||||||
}
|
}
|
||||||
|
|
||||||
var files = ARGS._.slice();
|
function convert_ast(fn) {
|
||||||
|
return UglifyJS.AST_Node.from_mozilla_ast(Object.keys(files).reduce(fn, null));
|
||||||
if (process.platform === "win32")
|
|
||||||
files = UglifyJS.simple_glob(files);
|
|
||||||
|
|
||||||
if (ARGS.self) {
|
|
||||||
if (files.length > 0) {
|
|
||||||
print_error("WARN: Ignoring input files since --self was passed");
|
|
||||||
}
|
|
||||||
files = UglifyJS.FILES;
|
|
||||||
if (!ARGS.wrap) ARGS.wrap = "UglifyJS";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var ORIG_MAP = ARGS.in_source_map;
|
function run() {
|
||||||
|
UglifyJS.AST_Node.warn_function = function(msg) {
|
||||||
if (ORIG_MAP && ORIG_MAP != "inline") {
|
console.error("WARN:", msg);
|
||||||
ORIG_MAP = JSON.parse(fs.readFileSync(ORIG_MAP));
|
};
|
||||||
if (files.length == 0) {
|
if (program.stats) program.stats = Date.now();
|
||||||
print_error("INFO: Using file from the input source map: " + ORIG_MAP.file);
|
try {
|
||||||
files = [ ORIG_MAP.file ];
|
if (program.parse) {
|
||||||
}
|
if (program.parse.acorn) {
|
||||||
}
|
files = convert_ast(function(toplevel, name) {
|
||||||
|
return require("acorn").parse(files[name], {
|
||||||
if (files.length == 0) {
|
locations: true,
|
||||||
files = [ "-" ];
|
program: toplevel,
|
||||||
}
|
sourceFile: name
|
||||||
|
});
|
||||||
if (ORIG_MAP == "inline") {
|
});
|
||||||
if (files.length > 1) {
|
} else if (program.parse.spidermonkey) {
|
||||||
print_error("ERROR: Inline source map only works with singular input");
|
files = convert_ast(function(toplevel, name) {
|
||||||
process.exit(1);
|
var obj = JSON.parse(files[name]);
|
||||||
}
|
if (!toplevel) return obj;
|
||||||
if (ARGS.acorn || ARGS.spidermonkey) {
|
toplevel.body = toplevel.body.concat(obj.body);
|
||||||
print_error("ERROR: Inline source map only works with built-in parser");
|
return toplevel;
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (files.indexOf("-") >= 0 && ARGS.source_map) {
|
|
||||||
print_error("ERROR: Source map doesn't work with input from STDIN");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (files.filter(function(el){ return el == "-" }).length > 1) {
|
|
||||||
print_error("ERROR: Can read a single file from STDIN (two or more dashes specified)");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
var STATS = {};
|
|
||||||
var TOPLEVEL = null;
|
|
||||||
var P_RELATIVE = ARGS.p && ARGS.p == "relative";
|
|
||||||
var SOURCES_CONTENT = {};
|
|
||||||
var index = 0;
|
|
||||||
|
|
||||||
!function cb() {
|
|
||||||
if (index == files.length) return done();
|
|
||||||
var file = files[index++];
|
|
||||||
read_whole_file(file, function (err, code) {
|
|
||||||
if (err) {
|
|
||||||
print_error("ERROR: can't read file: " + file);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
if (ORIG_MAP == "inline") {
|
|
||||||
ORIG_MAP = read_source_map(code);
|
|
||||||
}
|
|
||||||
if (ARGS.p != null) {
|
|
||||||
if (P_RELATIVE) {
|
|
||||||
file = path.relative(path.dirname(ARGS.source_map), file).replace(/\\/g, '/');
|
|
||||||
} else {
|
|
||||||
var p = parseInt(ARGS.p, 10);
|
|
||||||
if (!isNaN(p)) {
|
|
||||||
file = file.replace(/^\/+/, "").split(/\/+/).slice(ARGS.p).join("/");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SOURCES_CONTENT[file] = code;
|
|
||||||
time_it("parse", function(){
|
|
||||||
if (ARGS.spidermonkey) {
|
|
||||||
var program = JSON.parse(code);
|
|
||||||
if (!TOPLEVEL) TOPLEVEL = program;
|
|
||||||
else TOPLEVEL.body = TOPLEVEL.body.concat(program.body);
|
|
||||||
}
|
|
||||||
else if (ARGS.acorn) {
|
|
||||||
TOPLEVEL = acorn.parse(code, {
|
|
||||||
locations : true,
|
|
||||||
sourceFile : file,
|
|
||||||
program : TOPLEVEL
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
try {
|
var result = UglifyJS.minify(files, options);
|
||||||
TOPLEVEL = UglifyJS.parse(code, {
|
} catch (ex) {
|
||||||
filename : file,
|
if (ex instanceof UglifyJS.JS_Parse_Error) {
|
||||||
toplevel : TOPLEVEL,
|
console.error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
||||||
expression : ARGS.expr,
|
var col = ex.col;
|
||||||
bare_returns : ARGS.bare_returns,
|
var line = files[ex.filename].split(/\r?\n/)[ex.line - (col ? 1 : 2)];
|
||||||
});
|
if (line) {
|
||||||
} catch(ex) {
|
if (col > 40) {
|
||||||
if (ex instanceof UglifyJS.JS_Parse_Error) {
|
line = line.slice(col - 40);
|
||||||
print_error("Parse error at " + file + ":" + ex.line + "," + ex.col);
|
col = 40;
|
||||||
var col = ex.col;
|
|
||||||
var line = code.split(/\r?\n/)[ex.line - (col ? 1 : 2)];
|
|
||||||
if (line) {
|
|
||||||
if (col > 40) {
|
|
||||||
line = line.slice(col - 40);
|
|
||||||
col = 40;
|
|
||||||
}
|
|
||||||
if (col) {
|
|
||||||
print_error(line.slice(0, 80));
|
|
||||||
print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
|
|
||||||
} else {
|
|
||||||
print_error(line.slice(-40));
|
|
||||||
print_error(line.slice(-40).replace(/\S/g, " ") + "^");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
print_error(ex.stack);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
throw ex;
|
|
||||||
}
|
}
|
||||||
};
|
if (col) {
|
||||||
});
|
console.error(line.slice(0, 80));
|
||||||
cb();
|
console.error(line.slice(0, col).replace(/\S/g, " ") + "^");
|
||||||
});
|
} else {
|
||||||
}();
|
console.error(line.slice(-40));
|
||||||
|
console.error(line.slice(-40).replace(/\S/g, " ") + "^");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fatal("ERROR: " + ex.message);
|
||||||
|
}
|
||||||
|
if (program.output == "spidermonkey") {
|
||||||
|
console.log(JSON.stringify(UglifyJS.parse(result.code).to_mozilla_ast(), null, 2));
|
||||||
|
} else if (program.output) {
|
||||||
|
fs.writeFileSync(program.output, result.code);
|
||||||
|
if (result.map) {
|
||||||
|
fs.writeFileSync(program.output + ".map", result.map);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(result.code);
|
||||||
|
}
|
||||||
|
if (program.stats) console.error("Elapsed:", Date.now() - program.stats);
|
||||||
|
}
|
||||||
|
|
||||||
function done() {
|
function fatal(message) {
|
||||||
var OUTPUT_FILE = ARGS.o;
|
console.error(message);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
var SOURCE_MAP = (ARGS.source_map || ARGS.source_map_inline) ? UglifyJS.SourceMap({
|
// A file glob function that only supports "*" and "?" wildcards in the basename.
|
||||||
file: P_RELATIVE ? path.relative(path.dirname(ARGS.source_map), OUTPUT_FILE) : OUTPUT_FILE,
|
// Example: "foo/bar/*baz??.*.js"
|
||||||
root: ARGS.source_map_root || ORIG_MAP && ORIG_MAP.sourceRoot,
|
// Argument `glob` may be a string or an array of strings.
|
||||||
orig: ORIG_MAP,
|
// Returns an array of strings. Garbage in, garbage out.
|
||||||
}) : null;
|
function simple_glob(glob) {
|
||||||
|
if (Array.isArray(glob)) {
|
||||||
OUTPUT_OPTIONS.source_map = SOURCE_MAP;
|
return [].concat.apply([], glob.map(simple_glob));
|
||||||
|
}
|
||||||
|
if (glob.match(/\*|\?/)) {
|
||||||
|
var dir = path.dirname(glob);
|
||||||
|
try {
|
||||||
|
var entries = fs.readdirSync(dir);
|
||||||
|
} catch (ex) {}
|
||||||
|
if (entries) {
|
||||||
|
var pattern = "^" + path.basename(glob)
|
||||||
|
.replace(/[.+^$[\]\\(){}]/g, "\\$&")
|
||||||
|
.replace(/\*/g, "[^/\\\\]*")
|
||||||
|
.replace(/\?/g, "[^/\\\\]") + "$";
|
||||||
|
var mod = process.platform === "win32" ? "i" : "";
|
||||||
|
var rx = new RegExp(pattern, mod);
|
||||||
|
var results = entries.filter(function(name) {
|
||||||
|
return rx.test(name);
|
||||||
|
}).map(function(name) {
|
||||||
|
return path.join(dir, name);
|
||||||
|
});
|
||||||
|
if (results.length) return results;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [ glob ];
|
||||||
|
}
|
||||||
|
|
||||||
|
function readFile(path) {
|
||||||
try {
|
try {
|
||||||
var output = UglifyJS.OutputStream(OUTPUT_OPTIONS);
|
return fs.readFileSync(path, "utf8");
|
||||||
var compressor = COMPRESS && UglifyJS.Compressor(COMPRESS);
|
} catch (ex) {
|
||||||
} catch(ex) {
|
fatal("ERROR: " + ex.message);
|
||||||
if (ex instanceof UglifyJS.DefaultsError) {
|
|
||||||
print_error(ex.message);
|
|
||||||
print_error("Supported options:");
|
|
||||||
print_error(sys.inspect(ex.defs));
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ARGS.acorn || ARGS.spidermonkey) time_it("convert_ast", function(){
|
function parseJS(flag, constants) {
|
||||||
TOPLEVEL = UglifyJS.AST_Node.from_mozilla_ast(TOPLEVEL);
|
return function(value, options) {
|
||||||
});
|
options = options || {};
|
||||||
|
|
||||||
if (ARGS.wrap != null) {
|
|
||||||
TOPLEVEL = TOPLEVEL.wrap_commonjs(ARGS.wrap, ARGS.export_all);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.enclose != null) {
|
|
||||||
var arg_parameter_list = ARGS.enclose;
|
|
||||||
if (arg_parameter_list === true) {
|
|
||||||
arg_parameter_list = [];
|
|
||||||
}
|
|
||||||
else if (!(arg_parameter_list instanceof Array)) {
|
|
||||||
arg_parameter_list = [arg_parameter_list];
|
|
||||||
}
|
|
||||||
TOPLEVEL = TOPLEVEL.wrap_enclose(arg_parameter_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.mangle_props || ARGS.name_cache) (function(){
|
|
||||||
var reserved = RESERVED ? RESERVED.props : null;
|
|
||||||
var cache = readNameCache("props");
|
|
||||||
var regex;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
regex = ARGS.mangle_regex ? extractRegex(ARGS.mangle_regex) : null;
|
UglifyJS.parse(value, {
|
||||||
} catch (e) {
|
expression: true
|
||||||
print_error("ERROR: Invalid --mangle-regex: " + e.message);
|
}).walk(new UglifyJS.TreeWalker(function(node) {
|
||||||
process.exit(1);
|
if (node instanceof UglifyJS.AST_Assign) {
|
||||||
}
|
var name = node.left.print_to_string();
|
||||||
|
var value = node.right;
|
||||||
TOPLEVEL = UglifyJS.mangle_properties(TOPLEVEL, {
|
if (!constants) {
|
||||||
reserved : reserved,
|
options[name] = value;
|
||||||
cache : cache,
|
} else if (value instanceof UglifyJS.AST_Constant) {
|
||||||
only_cache : !ARGS.mangle_props,
|
options[name] = value.getValue();
|
||||||
regex : regex,
|
} else {
|
||||||
ignore_quoted : ARGS.mangle_props == 2,
|
options[name] = value.print_to_string();
|
||||||
debug : typeof ARGS.mangle_props_debug === "undefined" ? false : ARGS.mangle_props_debug
|
}
|
||||||
});
|
return true;
|
||||||
writeNameCache("props", cache);
|
}
|
||||||
})();
|
if (node instanceof UglifyJS.AST_Symbol || node instanceof UglifyJS.AST_PropAccess) {
|
||||||
|
var name = node.print_to_string();
|
||||||
var SCOPE_IS_NEEDED = COMPRESS || MANGLE || ARGS.lint
|
options[name] = true;
|
||||||
var TL_CACHE = readNameCache("vars");
|
return true;
|
||||||
if (MANGLE) MANGLE.cache = TL_CACHE;
|
}
|
||||||
|
if (!(node instanceof UglifyJS.AST_Sequence)) throw node;
|
||||||
if (SCOPE_IS_NEEDED) {
|
|
||||||
time_it("scope", function(){
|
|
||||||
TOPLEVEL.figure_out_scope(MANGLE || { screw_ie8: screw_ie8, cache: TL_CACHE });
|
|
||||||
if (ARGS.lint) {
|
|
||||||
TOPLEVEL.scope_warnings();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (COMPRESS) {
|
|
||||||
time_it("squeeze", function(){
|
|
||||||
TOPLEVEL = compressor.compress(TOPLEVEL);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SCOPE_IS_NEEDED) {
|
|
||||||
time_it("scope", function(){
|
|
||||||
TOPLEVEL.figure_out_scope(MANGLE || { screw_ie8: screw_ie8, cache: TL_CACHE });
|
|
||||||
if (MANGLE && !TL_CACHE) {
|
|
||||||
TOPLEVEL.compute_char_frequency(MANGLE);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MANGLE) time_it("mangle", function(){
|
|
||||||
TOPLEVEL.mangle_names(MANGLE);
|
|
||||||
});
|
|
||||||
|
|
||||||
writeNameCache("vars", TL_CACHE);
|
|
||||||
|
|
||||||
if (ARGS.source_map_include_sources) {
|
|
||||||
for (var file in SOURCES_CONTENT) {
|
|
||||||
if (SOURCES_CONTENT.hasOwnProperty(file)) {
|
|
||||||
SOURCE_MAP.get().setSourceContent(file, SOURCES_CONTENT[file]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.dump_spidermonkey_ast) {
|
|
||||||
print(JSON.stringify(TOPLEVEL.to_mozilla_ast(), null, 2));
|
|
||||||
} else {
|
|
||||||
time_it("generate", function(){
|
|
||||||
TOPLEVEL.print(output);
|
|
||||||
});
|
|
||||||
|
|
||||||
output = output.get();
|
|
||||||
|
|
||||||
if (SOURCE_MAP) {
|
|
||||||
if (ARGS.source_map_inline) {
|
|
||||||
var base64_string = new Buffer(SOURCE_MAP.toString()).toString('base64');
|
|
||||||
output += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + base64_string;
|
|
||||||
} else {
|
|
||||||
fs.writeFileSync(ARGS.source_map, SOURCE_MAP, "utf8");
|
|
||||||
var source_map_url = ARGS.source_map_url || (
|
|
||||||
P_RELATIVE
|
|
||||||
? path.relative(path.dirname(OUTPUT_FILE), ARGS.source_map)
|
|
||||||
: ARGS.source_map
|
|
||||||
);
|
|
||||||
output += "\n//# sourceMappingURL=" + source_map_url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OUTPUT_FILE) {
|
|
||||||
fs.writeFileSync(OUTPUT_FILE, output, "utf8");
|
|
||||||
} else {
|
|
||||||
print(output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.stats) {
|
|
||||||
print_error(UglifyJS.string_template("Timing information (compressed {count} files):", {
|
|
||||||
count: files.length
|
|
||||||
}));
|
|
||||||
for (var i in STATS) if (STATS.hasOwnProperty(i)) {
|
|
||||||
print_error(UglifyJS.string_template("- {name}: {time}s", {
|
|
||||||
name: i,
|
|
||||||
time: (STATS[i] / 1000).toFixed(3)
|
|
||||||
}));
|
}));
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -----[ functions ]----- */
|
|
||||||
|
|
||||||
function normalize(o) {
|
|
||||||
for (var i in o) if (o.hasOwnProperty(i) && /-/.test(i)) {
|
|
||||||
o[i.replace(/-/g, "_")] = o[i];
|
|
||||||
delete o[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getOptions(flag, constants) {
|
|
||||||
var x = ARGS[flag];
|
|
||||||
if (x == null || x === false) return null;
|
|
||||||
var ret = {};
|
|
||||||
if (x !== "") {
|
|
||||||
if (Array.isArray(x)) x = x.map(function (v) { return "(" + v + ")"; }).join(", ");
|
|
||||||
|
|
||||||
var ast;
|
|
||||||
try {
|
|
||||||
ast = UglifyJS.parse(x, { cli: true, expression: true });
|
|
||||||
} catch(ex) {
|
} catch(ex) {
|
||||||
if (ex instanceof UglifyJS.JS_Parse_Error) {
|
fatal("Error parsing arguments for '" + flag + "': " + value);
|
||||||
print_error("Error parsing arguments for flag `" + flag + "': " + x);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ast.walk(new UglifyJS.TreeWalker(function(node){
|
return options;
|
||||||
if (node instanceof UglifyJS.AST_Sequence) return; // descend
|
|
||||||
if (node instanceof UglifyJS.AST_Assign) {
|
|
||||||
var name = node.left.print_to_string().replace(/-/g, "_");
|
|
||||||
var value = node.right;
|
|
||||||
if (constants)
|
|
||||||
value = new Function("return (" + value.print_to_string() + ")")();
|
|
||||||
ret[name] = value;
|
|
||||||
return true; // no descend
|
|
||||||
}
|
|
||||||
if (node instanceof UglifyJS.AST_Symbol || node instanceof UglifyJS.AST_Binary) {
|
|
||||||
var name = node.print_to_string().replace(/-/g, "_");
|
|
||||||
ret[name] = true;
|
|
||||||
return true; // no descend
|
|
||||||
}
|
|
||||||
print_error(node.TYPE);
|
|
||||||
print_error("Error parsing arguments for flag `" + flag + "': " + x);
|
|
||||||
process.exit(1);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
function read_whole_file(filename, cb) {
|
|
||||||
if (filename == "-") {
|
|
||||||
var chunks = [];
|
|
||||||
process.stdin.setEncoding('utf-8');
|
|
||||||
process.stdin.on('data', function (chunk) {
|
|
||||||
chunks.push(chunk);
|
|
||||||
}).on('end', function () {
|
|
||||||
cb(null, chunks.join(""));
|
|
||||||
});
|
|
||||||
process.openStdin();
|
|
||||||
} else {
|
|
||||||
fs.readFile(filename, "utf-8", cb);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function read_source_map(code) {
|
function parseSourceMap() {
|
||||||
var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
|
var parse = parseJS("sourceMap", true);
|
||||||
if (!match) {
|
return function(value, options) {
|
||||||
print_error("WARN: inline source map not found");
|
var hasContent = options && options.sourceMap && "content" in options.sourceMap;
|
||||||
return null;
|
var settings = parse(value, options);
|
||||||
|
if (!hasContent && settings.content && settings.content != "inline") {
|
||||||
|
console.error("INFO: Using input source map:", settings.content);
|
||||||
|
settings.content = readFile(settings.content);
|
||||||
|
}
|
||||||
|
return settings;
|
||||||
}
|
}
|
||||||
return JSON.parse(new Buffer(match[2], "base64"));
|
|
||||||
}
|
|
||||||
|
|
||||||
function time_it(name, cont) {
|
|
||||||
var t1 = new Date().getTime();
|
|
||||||
var ret = cont();
|
|
||||||
if (ARGS.stats) {
|
|
||||||
var spent = new Date().getTime() - t1;
|
|
||||||
if (STATS[name]) STATS[name] += spent;
|
|
||||||
else STATS[name] = spent;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
function print_error(msg) {
|
|
||||||
console.error("%s", msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
function print(txt) {
|
|
||||||
console.log("%s", txt);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
57
lib/ast.js
57
lib/ast.js
|
|
@ -325,62 +325,13 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
globals: "[Object/S] a map of name -> SymbolDef for all undeclared names",
|
globals: "[Object/S] a map of name -> SymbolDef for all undeclared names",
|
||||||
},
|
},
|
||||||
wrap_enclose: function(arg_parameter_pairs) {
|
wrap_commonjs: function(name) {
|
||||||
var self = this;
|
var body = this.body;
|
||||||
var args = [];
|
var wrapped_tl = "(function(exports){'$ORIG';})(typeof " + name + "=='undefined'?(" + name + "={}):" + name + ");";
|
||||||
var parameters = [];
|
|
||||||
|
|
||||||
arg_parameter_pairs.forEach(function(pair) {
|
|
||||||
var splitAt = pair.lastIndexOf(":");
|
|
||||||
|
|
||||||
args.push(pair.substr(0, splitAt));
|
|
||||||
parameters.push(pair.substr(splitAt + 1));
|
|
||||||
});
|
|
||||||
|
|
||||||
var wrapped_tl = "(function(" + parameters.join(",") + "){ '$ORIG'; })(" + args.join(",") + ")";
|
|
||||||
wrapped_tl = parse(wrapped_tl);
|
wrapped_tl = parse(wrapped_tl);
|
||||||
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
|
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
|
||||||
if (node instanceof AST_Directive && node.value == "$ORIG") {
|
if (node instanceof AST_Directive && node.value == "$ORIG") {
|
||||||
return MAP.splice(self.body);
|
return MAP.splice(body);
|
||||||
}
|
|
||||||
}));
|
|
||||||
return wrapped_tl;
|
|
||||||
},
|
|
||||||
wrap_commonjs: function(name, export_all) {
|
|
||||||
var self = this;
|
|
||||||
var to_export = [];
|
|
||||||
if (export_all) {
|
|
||||||
self.figure_out_scope();
|
|
||||||
self.walk(new TreeWalker(function(node){
|
|
||||||
if (node instanceof AST_SymbolDeclaration && node.definition().global) {
|
|
||||||
if (!find_if(function(n){ return n.name == node.name }, to_export))
|
|
||||||
to_export.push(node);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
var wrapped_tl = "(function(exports, global){ '$ORIG'; '$EXPORTS'; global['" + name + "'] = exports; }({}, (function(){return this}())))";
|
|
||||||
wrapped_tl = parse(wrapped_tl);
|
|
||||||
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
|
|
||||||
if (node instanceof AST_Directive) {
|
|
||||||
switch (node.value) {
|
|
||||||
case "$ORIG":
|
|
||||||
return MAP.splice(self.body);
|
|
||||||
case "$EXPORTS":
|
|
||||||
var body = [];
|
|
||||||
to_export.forEach(function(sym){
|
|
||||||
body.push(new AST_SimpleStatement({
|
|
||||||
body: new AST_Assign({
|
|
||||||
left: new AST_Sub({
|
|
||||||
expression: new AST_SymbolRef({ name: "exports" }),
|
|
||||||
property: new AST_String({ value: sym.name }),
|
|
||||||
}),
|
|
||||||
operator: "=",
|
|
||||||
right: new AST_SymbolRef(sym),
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
return MAP.splice(body);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
return wrapped_tl;
|
return wrapped_tl;
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ function Compressor(options, false_by_default) {
|
||||||
global_defs : {},
|
global_defs : {},
|
||||||
hoist_funs : !false_by_default,
|
hoist_funs : !false_by_default,
|
||||||
hoist_vars : false,
|
hoist_vars : false,
|
||||||
|
ie8 : false,
|
||||||
if_return : !false_by_default,
|
if_return : !false_by_default,
|
||||||
join_vars : !false_by_default,
|
join_vars : !false_by_default,
|
||||||
keep_fargs : true,
|
keep_fargs : true,
|
||||||
|
|
@ -74,7 +75,6 @@ function Compressor(options, false_by_default) {
|
||||||
pure_getters : !false_by_default && "strict",
|
pure_getters : !false_by_default && "strict",
|
||||||
pure_funcs : null,
|
pure_funcs : null,
|
||||||
reduce_vars : !false_by_default,
|
reduce_vars : !false_by_default,
|
||||||
screw_ie8 : true,
|
|
||||||
sequences : !false_by_default,
|
sequences : !false_by_default,
|
||||||
side_effects : !false_by_default,
|
side_effects : !false_by_default,
|
||||||
switches : !false_by_default,
|
switches : !false_by_default,
|
||||||
|
|
@ -2845,10 +2845,11 @@ merge(Compressor.prototype, {
|
||||||
return arg.value;
|
return arg.value;
|
||||||
}).join(",") + "){" + self.args[self.args.length - 1].value + "})()";
|
}).join(",") + "){" + self.args[self.args.length - 1].value + "})()";
|
||||||
var ast = parse(code);
|
var ast = parse(code);
|
||||||
ast.figure_out_scope({ screw_ie8: compressor.option("screw_ie8") });
|
var mangle = { ie8: compressor.option("ie8") };
|
||||||
|
ast.figure_out_scope(mangle);
|
||||||
var comp = new Compressor(compressor.options);
|
var comp = new Compressor(compressor.options);
|
||||||
ast = ast.transform(comp);
|
ast = ast.transform(comp);
|
||||||
ast.figure_out_scope({ screw_ie8: compressor.option("screw_ie8") });
|
ast.figure_out_scope(mangle);
|
||||||
ast.mangle_names();
|
ast.mangle_names();
|
||||||
var fun;
|
var fun;
|
||||||
try {
|
try {
|
||||||
|
|
@ -3294,7 +3295,7 @@ merge(Compressor.prototype, {
|
||||||
&& self.right.operator == "typeof") {
|
&& self.right.operator == "typeof") {
|
||||||
var expr = self.right.expression;
|
var expr = self.right.expression;
|
||||||
if (expr instanceof AST_SymbolRef ? !expr.undeclared()
|
if (expr instanceof AST_SymbolRef ? !expr.undeclared()
|
||||||
: !(expr instanceof AST_PropAccess) || compressor.option("screw_ie8")) {
|
: !(expr instanceof AST_PropAccess && compressor.option("ie8"))) {
|
||||||
self.right = expr;
|
self.right = expr;
|
||||||
self.left = make_node(AST_Undefined, self.left).optimize(compressor);
|
self.left = make_node(AST_Undefined, self.left).optimize(compressor);
|
||||||
if (self.operator.length == 2) self.operator += "=";
|
if (self.operator.length == 2) self.operator += "=";
|
||||||
|
|
@ -3618,7 +3619,7 @@ merge(Compressor.prototype, {
|
||||||
return def.optimize(compressor);
|
return def.optimize(compressor);
|
||||||
}
|
}
|
||||||
// testing against !self.scope.uses_with first is an optimization
|
// testing against !self.scope.uses_with first is an optimization
|
||||||
if (compressor.option("screw_ie8")
|
if (!compressor.option("ie8")
|
||||||
&& self.undeclared()
|
&& self.undeclared()
|
||||||
&& (!self.scope.uses_with || !compressor.find_parent(AST_With))) {
|
&& (!self.scope.uses_with || !compressor.find_parent(AST_With))) {
|
||||||
switch (self.name) {
|
switch (self.name) {
|
||||||
|
|
@ -3938,7 +3939,7 @@ merge(Compressor.prototype, {
|
||||||
var prop = self.property;
|
var prop = self.property;
|
||||||
if (prop instanceof AST_String && compressor.option("properties")) {
|
if (prop instanceof AST_String && compressor.option("properties")) {
|
||||||
prop = prop.getValue();
|
prop = prop.getValue();
|
||||||
if (RESERVED_WORDS(prop) ? compressor.option("screw_ie8") : is_identifier_string(prop)) {
|
if (RESERVED_WORDS(prop) ? !compressor.option("ie8") : is_identifier_string(prop)) {
|
||||||
return make_node(AST_Dot, self, {
|
return make_node(AST_Dot, self, {
|
||||||
expression : self.expression,
|
expression : self.expression,
|
||||||
property : prop
|
property : prop
|
||||||
|
|
@ -3965,7 +3966,7 @@ merge(Compressor.prototype, {
|
||||||
return def.optimize(compressor);
|
return def.optimize(compressor);
|
||||||
}
|
}
|
||||||
var prop = self.property;
|
var prop = self.property;
|
||||||
if (RESERVED_WORDS(prop) && !compressor.option("screw_ie8")) {
|
if (RESERVED_WORDS(prop) && compressor.option("ie8")) {
|
||||||
return make_node(AST_Sub, self, {
|
return make_node(AST_Sub, self, {
|
||||||
expression : self.expression,
|
expression : self.expression,
|
||||||
property : make_node(AST_String, self, {
|
property : make_node(AST_String, self, {
|
||||||
|
|
|
||||||
144
lib/minify.js
Normal file
144
lib/minify.js
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var to_ascii = typeof atob == "undefined" ? function(b64) {
|
||||||
|
return new Buffer(b64, "base64").toString();
|
||||||
|
} : atob;
|
||||||
|
var to_base64 = typeof btoa == "undefined" ? function(str) {
|
||||||
|
return new Buffer(str).toString("base64");
|
||||||
|
} : btoa;
|
||||||
|
|
||||||
|
function read_source_map(code) {
|
||||||
|
var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
|
||||||
|
if (!match) {
|
||||||
|
AST_Node.warn("inline source map not found");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return to_ascii(match[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_shorthand(name, options, keys) {
|
||||||
|
if (options[name]) {
|
||||||
|
keys.forEach(function(key) {
|
||||||
|
if (options[key]) {
|
||||||
|
if (typeof options[key] != "object") options[key] = {};
|
||||||
|
if (!(name in options[key])) options[key][name] = options[name];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function minify(files, options) {
|
||||||
|
var warn_function = AST_Node.warn_function;
|
||||||
|
try {
|
||||||
|
if (typeof files == "string") {
|
||||||
|
files = [ files ];
|
||||||
|
}
|
||||||
|
options = defaults(options, {
|
||||||
|
compress: {},
|
||||||
|
ie8: false,
|
||||||
|
keep_fnames: false,
|
||||||
|
mangle: {},
|
||||||
|
output: {},
|
||||||
|
parse: {},
|
||||||
|
sourceMap: false,
|
||||||
|
toplevel: false,
|
||||||
|
wrap: false,
|
||||||
|
}, true);
|
||||||
|
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
||||||
|
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
||||||
|
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
||||||
|
if (options.mangle) {
|
||||||
|
options.mangle = defaults(options.mangle, {
|
||||||
|
cache: null,
|
||||||
|
eval: false,
|
||||||
|
except: [],
|
||||||
|
ie8: false,
|
||||||
|
keep_fnames: false,
|
||||||
|
properties: false,
|
||||||
|
toplevel: false,
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
if (options.sourceMap) {
|
||||||
|
options.sourceMap = defaults(options.sourceMap, {
|
||||||
|
content: null,
|
||||||
|
filename: null,
|
||||||
|
includeSources: false,
|
||||||
|
root: null,
|
||||||
|
url: null,
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
var warnings = [];
|
||||||
|
if (!AST_Node.warn_function) {
|
||||||
|
AST_Node.warn_function = function(warning) {
|
||||||
|
warnings.push(warning);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var toplevel;
|
||||||
|
if (files instanceof AST_Toplevel) {
|
||||||
|
toplevel = files;
|
||||||
|
} else {
|
||||||
|
options.parse = options.parse || {};
|
||||||
|
options.parse.toplevel = null;
|
||||||
|
for (var name in files) {
|
||||||
|
options.parse.filename = name;
|
||||||
|
options.parse.toplevel = parse(files[name], options.parse);
|
||||||
|
if (options.sourceMap && options.sourceMap.content == "inline") {
|
||||||
|
if (Object.keys(files).length > 1)
|
||||||
|
throw new Error("inline source map only works with singular input");
|
||||||
|
options.sourceMap.content = read_source_map(files[name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
toplevel = options.parse.toplevel;
|
||||||
|
}
|
||||||
|
if (options.wrap) {
|
||||||
|
toplevel = toplevel.wrap_commonjs(options.wrap);
|
||||||
|
}
|
||||||
|
if (options.compress) {
|
||||||
|
toplevel.figure_out_scope(options.mangle);
|
||||||
|
toplevel = new Compressor(options.compress).compress(toplevel);
|
||||||
|
}
|
||||||
|
if (options.mangle) {
|
||||||
|
toplevel.figure_out_scope(options.mangle);
|
||||||
|
base54.reset();
|
||||||
|
toplevel.compute_char_frequency(options.mangle);
|
||||||
|
toplevel.mangle_names(options.mangle);
|
||||||
|
if (options.mangle.properties) {
|
||||||
|
toplevel = mangle_properties(toplevel, options.mangle.properties);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (options.sourceMap) {
|
||||||
|
if (typeof options.sourceMap.content == "string") {
|
||||||
|
options.sourceMap.content = JSON.parse(options.sourceMap.content);
|
||||||
|
}
|
||||||
|
options.output.source_map = SourceMap({
|
||||||
|
file: options.sourceMap.filename,
|
||||||
|
orig: options.sourceMap.content,
|
||||||
|
root: options.sourceMap.root
|
||||||
|
});
|
||||||
|
if (options.sourceMap.includeSources) {
|
||||||
|
for (var name in files) {
|
||||||
|
options.output.source_map.get().setSourceContent(name, files[name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var stream = OutputStream(options.output);
|
||||||
|
toplevel.print(stream);
|
||||||
|
var result = {
|
||||||
|
code: stream.get()
|
||||||
|
};
|
||||||
|
if (options.sourceMap) {
|
||||||
|
result.map = options.output.source_map.toString();
|
||||||
|
if (options.sourceMap.url == "inline") {
|
||||||
|
result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(result.map);
|
||||||
|
} else if (options.sourceMap.url) {
|
||||||
|
result.code += "\n//# sourceMappingURL=" + options.sourceMap.url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (warnings.length) {
|
||||||
|
result.warnings = warnings;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} finally {
|
||||||
|
AST_Node.warn_function = warn_function;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -57,6 +57,7 @@ function OutputStream(options) {
|
||||||
beautify : false,
|
beautify : false,
|
||||||
bracketize : false,
|
bracketize : false,
|
||||||
comments : false,
|
comments : false,
|
||||||
|
ie8 : false,
|
||||||
indent_level : 4,
|
indent_level : 4,
|
||||||
indent_start : 0,
|
indent_start : 0,
|
||||||
inline_script : true,
|
inline_script : true,
|
||||||
|
|
@ -66,7 +67,6 @@ function OutputStream(options) {
|
||||||
preserve_line : false,
|
preserve_line : false,
|
||||||
quote_keys : false,
|
quote_keys : false,
|
||||||
quote_style : 0,
|
quote_style : 0,
|
||||||
screw_ie8 : true,
|
|
||||||
semicolons : true,
|
semicolons : true,
|
||||||
shebang : true,
|
shebang : true,
|
||||||
source_map : null,
|
source_map : null,
|
||||||
|
|
@ -136,7 +136,7 @@ function OutputStream(options) {
|
||||||
case "\t": return "\\t";
|
case "\t": return "\\t";
|
||||||
case "\b": return "\\b";
|
case "\b": return "\\b";
|
||||||
case "\f": return "\\f";
|
case "\f": return "\\f";
|
||||||
case "\x0B": return options.screw_ie8 ? "\\v" : "\\x0B";
|
case "\x0B": return options.ie8 ? "\\x0B" : "\\v";
|
||||||
case "\u2028": return "\\u2028";
|
case "\u2028": return "\\u2028";
|
||||||
case "\u2029": return "\\u2029";
|
case "\u2029": return "\\u2029";
|
||||||
case "\ufeff": return "\\ufeff";
|
case "\ufeff": return "\\ufeff";
|
||||||
|
|
@ -906,7 +906,7 @@ function OutputStream(options) {
|
||||||
function make_then(self, output) {
|
function make_then(self, output) {
|
||||||
var b = self.body;
|
var b = self.body;
|
||||||
if (output.option("bracketize")
|
if (output.option("bracketize")
|
||||||
|| !output.option("screw_ie8") && b instanceof AST_Do)
|
|| output.option("ie8") && b instanceof AST_Do)
|
||||||
return make_block(b, output);
|
return make_block(b, output);
|
||||||
// The squeezer replaces "block"-s that contain only a single
|
// The squeezer replaces "block"-s that contain only a single
|
||||||
// statement with the statement itself; technically, the AST
|
// statement with the statement itself; technically, the AST
|
||||||
|
|
@ -1222,7 +1222,7 @@ function OutputStream(options) {
|
||||||
&& +key + "" == key)
|
&& +key + "" == key)
|
||||||
&& parseFloat(key) >= 0) {
|
&& parseFloat(key) >= 0) {
|
||||||
output.print(make_num(key));
|
output.print(make_num(key));
|
||||||
} else if (RESERVED_WORDS(key) ? output.option("screw_ie8") : is_identifier_string(key)) {
|
} else if (RESERVED_WORDS(key) ? !output.option("ie8") : is_identifier_string(key)) {
|
||||||
if (quote && output.option("keep_quoted_props")) {
|
if (quote && output.option("keep_quoted_props")) {
|
||||||
output.print_string(key, quote);
|
output.print_string(key, quote);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
11
lib/scope.js
11
lib/scope.js
|
|
@ -76,7 +76,7 @@ SymbolDef.prototype = {
|
||||||
else if (!this.mangled_name && !this.unmangleable(options)) {
|
else if (!this.mangled_name && !this.unmangleable(options)) {
|
||||||
var s = this.scope;
|
var s = this.scope;
|
||||||
var sym = this.orig[0];
|
var sym = this.orig[0];
|
||||||
if (!options.screw_ie8 && sym instanceof AST_SymbolLambda)
|
if (options.ie8 && sym instanceof AST_SymbolLambda)
|
||||||
s = s.parent_scope;
|
s = s.parent_scope;
|
||||||
var def;
|
var def;
|
||||||
if (this.defun && (def = this.defun.variables.get(this.name))) {
|
if (this.defun && (def = this.defun.variables.get(this.name))) {
|
||||||
|
|
@ -93,7 +93,7 @@ SymbolDef.prototype = {
|
||||||
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
cache: null,
|
cache: null,
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// pass 1: setup scope chaining and handle definitions
|
// pass 1: setup scope chaining and handle definitions
|
||||||
|
|
@ -220,7 +220,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
|
|
||||||
// pass 3: fix up any scoping issue with IE8
|
// pass 3: fix up any scoping issue with IE8
|
||||||
if (!options.screw_ie8) {
|
if (options.ie8) {
|
||||||
self.walk(new TreeWalker(function(node, descend) {
|
self.walk(new TreeWalker(function(node, descend) {
|
||||||
if (node instanceof AST_SymbolCatch) {
|
if (node instanceof AST_SymbolCatch) {
|
||||||
var name = node.name;
|
var name = node.name;
|
||||||
|
|
@ -400,9 +400,8 @@ AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
||||||
return defaults(options, {
|
return defaults(options, {
|
||||||
eval : false,
|
eval : false,
|
||||||
except : [],
|
except : [],
|
||||||
|
ie8 : false,
|
||||||
keep_fnames : false,
|
keep_fnames : false,
|
||||||
screw_ie8 : true,
|
|
||||||
sort : false, // Ignored. Flag retained for backwards compatibility.
|
|
||||||
toplevel : false,
|
toplevel : false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -452,7 +451,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||||
node.mangled_name = name;
|
node.mangled_name = name;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (options.screw_ie8 && node instanceof AST_SymbolCatch) {
|
if (!options.ie8 && node instanceof AST_SymbolCatch) {
|
||||||
to_mangle.push(node.definition());
|
to_mangle.push(node.definition());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,8 @@
|
||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"source-map": "~0.5.1",
|
"commander": "~2.9.0",
|
||||||
"yargs": "~3.10.0"
|
"source-map": "~0.5.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"acorn": "~0.6.0",
|
"acorn": "~0.6.0",
|
||||||
|
|
|
||||||
|
|
@ -29,11 +29,11 @@ function done() {
|
||||||
var info = results[url];
|
var info = results[url];
|
||||||
console.log();
|
console.log();
|
||||||
console.log(url);
|
console.log(url);
|
||||||
console.log(info.log);
|
|
||||||
var elapsed = 0;
|
var elapsed = 0;
|
||||||
info.log.replace(/: ([0-9]+\.[0-9]{3})s/g, function(match, time) {
|
console.log(info.log.replace(/Elapsed: ([0-9]+)\s*/g, function(match, time) {
|
||||||
elapsed += parseFloat(time);
|
elapsed += 1e-3 * parseInt(time);
|
||||||
});
|
return "";
|
||||||
|
}));
|
||||||
console.log("Run-time:", elapsed.toFixed(3), "s");
|
console.log("Run-time:", elapsed.toFixed(3), "s");
|
||||||
console.log("Original:", info.input, "bytes");
|
console.log("Original:", info.input, "bytes");
|
||||||
console.log("Uglified:", info.output, "bytes");
|
console.log("Uglified:", info.output, "bytes");
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ ascii_only_true: {
|
||||||
options = {}
|
options = {}
|
||||||
beautify = {
|
beautify = {
|
||||||
ascii_only : true,
|
ascii_only : true,
|
||||||
screw_ie8 : true,
|
ie8 : false,
|
||||||
beautify : false,
|
beautify : false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -20,7 +20,7 @@ ascii_only_false: {
|
||||||
options = {}
|
options = {}
|
||||||
beautify = {
|
beautify = {
|
||||||
ascii_only : false,
|
ascii_only : false,
|
||||||
screw_ie8 : true,
|
ie8 : false,
|
||||||
beautify : false,
|
beautify : false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -33,4 +33,3 @@ ascii_only_false: {
|
||||||
}
|
}
|
||||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\v\\f\\r\x0e\x0f"+"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"+\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\'}'
|
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\v\\f\\r\x0e\x0f"+"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"+\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\'}'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ typeof_eq_undefined: {
|
||||||
typeof_eq_undefined_ie8: {
|
typeof_eq_undefined_ie8: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true,
|
comparisons: true,
|
||||||
screw_ie8: false
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = typeof b != "undefined";
|
var a = typeof b != "undefined";
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
screw_ie8: {
|
screw_ie8: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
try { throw "foo"; } catch (x) { console.log(x); }
|
try { throw "foo"; } catch (x) { console.log(x); }
|
||||||
|
|
@ -16,10 +16,10 @@ screw_ie8: {
|
||||||
|
|
||||||
support_ie8: {
|
support_ie8: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
try { throw "foo"; } catch (x) { console.log(x); }
|
try { throw "foo"; } catch (x) { console.log(x); }
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
mangle_catch: {
|
mangle_catch: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -22,11 +22,11 @@ mangle_catch: {
|
||||||
|
|
||||||
mangle_catch_ie8: {
|
mangle_catch_ie8: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -44,11 +44,11 @@ mangle_catch_ie8: {
|
||||||
|
|
||||||
mangle_catch_var: {
|
mangle_catch_var: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -66,11 +66,11 @@ mangle_catch_var: {
|
||||||
|
|
||||||
mangle_catch_var_ie8: {
|
mangle_catch_var_ie8: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -88,11 +88,11 @@ mangle_catch_var_ie8: {
|
||||||
|
|
||||||
mangle_catch_toplevel: {
|
mangle_catch_toplevel: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -110,11 +110,11 @@ mangle_catch_toplevel: {
|
||||||
|
|
||||||
mangle_catch_ie8_toplevel: {
|
mangle_catch_ie8_toplevel: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -132,11 +132,11 @@ mangle_catch_ie8_toplevel: {
|
||||||
|
|
||||||
mangle_catch_var_toplevel: {
|
mangle_catch_var_toplevel: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -154,11 +154,11 @@ mangle_catch_var_toplevel: {
|
||||||
|
|
||||||
mangle_catch_var_ie8_toplevel: {
|
mangle_catch_var_ie8_toplevel: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -176,11 +176,11 @@ mangle_catch_var_ie8_toplevel: {
|
||||||
|
|
||||||
mangle_catch_redef_1: {
|
mangle_catch_redef_1: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -198,11 +198,11 @@ mangle_catch_redef_1: {
|
||||||
|
|
||||||
mangle_catch_redef_1_ie8: {
|
mangle_catch_redef_1_ie8: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -220,11 +220,11 @@ mangle_catch_redef_1_ie8: {
|
||||||
|
|
||||||
mangle_catch_redef_1_toplevel: {
|
mangle_catch_redef_1_toplevel: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -242,11 +242,11 @@ mangle_catch_redef_1_toplevel: {
|
||||||
|
|
||||||
mangle_catch_redef_1_ie8_toplevel: {
|
mangle_catch_redef_1_ie8_toplevel: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -264,11 +264,11 @@ mangle_catch_redef_1_ie8_toplevel: {
|
||||||
|
|
||||||
mangle_catch_redef_2: {
|
mangle_catch_redef_2: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -285,11 +285,11 @@ mangle_catch_redef_2: {
|
||||||
|
|
||||||
mangle_catch_redef_2_ie8: {
|
mangle_catch_redef_2_ie8: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -306,11 +306,11 @@ mangle_catch_redef_2_ie8: {
|
||||||
|
|
||||||
mangle_catch_redef_2_toplevel: {
|
mangle_catch_redef_2_toplevel: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -327,11 +327,11 @@ mangle_catch_redef_2_toplevel: {
|
||||||
|
|
||||||
mangle_catch_redef_2_ie8_toplevel: {
|
mangle_catch_redef_2_ie8_toplevel: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
function_iife_catch: {
|
function_iife_catch: {
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(n) {
|
function f(n) {
|
||||||
|
|
@ -21,7 +21,7 @@ function_iife_catch: {
|
||||||
|
|
||||||
function_iife_catch_ie8: {
|
function_iife_catch_ie8: {
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(n) {
|
function f(n) {
|
||||||
|
|
@ -42,7 +42,7 @@ function_iife_catch_ie8: {
|
||||||
|
|
||||||
function_catch_catch: {
|
function_catch_catch: {
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = 0;
|
var o = 0;
|
||||||
|
|
@ -70,7 +70,7 @@ function_catch_catch: {
|
||||||
|
|
||||||
function_catch_catch_ie8: {
|
function_catch_catch_ie8: {
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = 0;
|
var o = 0;
|
||||||
|
|
|
||||||
|
|
@ -245,7 +245,7 @@ issue_1532: {
|
||||||
issue_186: {
|
issue_186: {
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: false,
|
beautify: false,
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = 3;
|
var x = 3;
|
||||||
|
|
@ -264,7 +264,7 @@ issue_186: {
|
||||||
issue_186_ie8: {
|
issue_186_ie8: {
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: false,
|
beautify: false,
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = 3;
|
var x = 3;
|
||||||
|
|
@ -283,7 +283,7 @@ issue_186_ie8: {
|
||||||
issue_186_beautify: {
|
issue_186_beautify: {
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: true,
|
beautify: true,
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = 3;
|
var x = 3;
|
||||||
|
|
@ -310,7 +310,7 @@ issue_186_beautify: {
|
||||||
issue_186_beautify_ie8: {
|
issue_186_beautify_ie8: {
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: true,
|
beautify: true,
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = 3;
|
var x = 3;
|
||||||
|
|
@ -340,7 +340,7 @@ issue_186_bracketize: {
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: false,
|
beautify: false,
|
||||||
bracketize: true,
|
bracketize: true,
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = 3;
|
var x = 3;
|
||||||
|
|
@ -360,7 +360,7 @@ issue_186_bracketize_ie8: {
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: false,
|
beautify: false,
|
||||||
bracketize: true,
|
bracketize: true,
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = 3;
|
var x = 3;
|
||||||
|
|
@ -380,7 +380,7 @@ issue_186_beautify_bracketize: {
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: true,
|
beautify: true,
|
||||||
bracketize: true,
|
bracketize: true,
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = 3;
|
var x = 3;
|
||||||
|
|
@ -412,7 +412,7 @@ issue_186_beautify_bracketize_ie8: {
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: true,
|
beautify: true,
|
||||||
bracketize: true,
|
bracketize: true,
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = 3;
|
var x = 3;
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ keep_properties: {
|
||||||
dot_properties: {
|
dot_properties: {
|
||||||
options = {
|
options = {
|
||||||
properties: true,
|
properties: true,
|
||||||
screw_ie8: false
|
ie8: true,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
|
|
@ -36,7 +36,7 @@ dot_properties: {
|
||||||
dot_properties_es5: {
|
dot_properties_es5: {
|
||||||
options = {
|
options = {
|
||||||
properties: true,
|
properties: true,
|
||||||
screw_ie8: true
|
ie8: false,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
do_screw: {
|
do_screw: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
beautify = {
|
beautify = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
ascii_only: true,
|
ascii_only: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -14,10 +14,10 @@ do_screw: {
|
||||||
|
|
||||||
dont_screw: {
|
dont_screw: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
beautify = {
|
beautify = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
ascii_only: true,
|
ascii_only: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -28,7 +28,7 @@ dont_screw: {
|
||||||
|
|
||||||
do_screw_constants: {
|
do_screw_constants: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
f(undefined, Infinity);
|
f(undefined, Infinity);
|
||||||
|
|
@ -38,7 +38,7 @@ do_screw_constants: {
|
||||||
|
|
||||||
dont_screw_constants: {
|
dont_screw_constants: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
f(undefined, Infinity);
|
f(undefined, Infinity);
|
||||||
|
|
@ -47,9 +47,15 @@ dont_screw_constants: {
|
||||||
}
|
}
|
||||||
|
|
||||||
do_screw_try_catch: {
|
do_screw_try_catch: {
|
||||||
options = { screw_ie8: true };
|
options = {
|
||||||
mangle = { screw_ie8: true };
|
ie8: false,
|
||||||
beautify = { screw_ie8: true };
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
good = function(e){
|
good = function(e){
|
||||||
return function(error){
|
return function(error){
|
||||||
|
|
@ -75,9 +81,15 @@ do_screw_try_catch: {
|
||||||
}
|
}
|
||||||
|
|
||||||
dont_screw_try_catch: {
|
dont_screw_try_catch: {
|
||||||
options = { screw_ie8: false };
|
options = {
|
||||||
mangle = { screw_ie8: false };
|
ie8: true,
|
||||||
beautify = { screw_ie8: false };
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
bad = function(e){
|
bad = function(e){
|
||||||
return function(error){
|
return function(error){
|
||||||
|
|
@ -103,9 +115,15 @@ dont_screw_try_catch: {
|
||||||
}
|
}
|
||||||
|
|
||||||
do_screw_try_catch_undefined: {
|
do_screw_try_catch_undefined: {
|
||||||
options = { screw_ie8: true };
|
options = {
|
||||||
mangle = { screw_ie8: true };
|
ie8: false,
|
||||||
beautify = { screw_ie8: true };
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
function a(b){
|
function a(b){
|
||||||
try {
|
try {
|
||||||
|
|
@ -132,9 +150,15 @@ do_screw_try_catch_undefined: {
|
||||||
}
|
}
|
||||||
|
|
||||||
dont_screw_try_catch_undefined: {
|
dont_screw_try_catch_undefined: {
|
||||||
options = { screw_ie8: false };
|
options = {
|
||||||
mangle = { screw_ie8: false };
|
ie8: true,
|
||||||
beautify = { screw_ie8: false };
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
function a(b){
|
function a(b){
|
||||||
try {
|
try {
|
||||||
|
|
@ -164,11 +188,11 @@ reduce_vars: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f() {
|
function f() {
|
||||||
|
|
@ -196,10 +220,10 @@ reduce_vars: {
|
||||||
|
|
||||||
issue_1586_1: {
|
issue_1586_1: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f() {
|
function f() {
|
||||||
|
|
@ -215,10 +239,10 @@ issue_1586_1: {
|
||||||
|
|
||||||
issue_1586_2: {
|
issue_1586_2: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f() {
|
function f() {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ describe("bin/uglifyjs", function () {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should be able to filter comments correctly with `--comment all`", function (done) {
|
it("Should be able to filter comments correctly with `--comments all`", function (done) {
|
||||||
var command = uglifyjscmd + ' test/input/comments/filter.js --comments all';
|
var command = uglifyjscmd + ' test/input/comments/filter.js --comments all';
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
|
|
@ -50,8 +50,8 @@ describe("bin/uglifyjs", function () {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should append source map to output when using --source-map-inline", function (done) {
|
it("Should append source map to output when using --source-map url=inline", function (done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1323/sample.js --source-map-inline';
|
var command = uglifyjscmd + " test/input/issue-1323/sample.js --source-map url=inline";
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
@ -61,7 +61,7 @@ describe("bin/uglifyjs", function () {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("should not append source map to output when not using --source-map-inline", function (done) {
|
it("should not append source map to output when not using --source-map url=inline", function (done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1323/sample.js';
|
var command = uglifyjscmd + ' test/input/issue-1323/sample.js';
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
|
|
@ -152,7 +152,7 @@ describe("bin/uglifyjs", function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should process inline source map", function(done) {
|
it("Should process inline source map", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-520/input.js -mc toplevel --in-source-map inline --source-map-inline';
|
var command = uglifyjscmd + " test/input/issue-520/input.js -mc toplevel --source-map content=inline,url=inline";
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
@ -162,40 +162,44 @@ describe("bin/uglifyjs", function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should warn for missing inline source map", function(done) {
|
it("Should warn for missing inline source map", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1323/sample.js --in-source-map inline';
|
var command = uglifyjscmd + " test/input/issue-1323/sample.js --source-map content=inline,url=inline";
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n");
|
assert.strictEqual(stdout, [
|
||||||
|
"var bar=function(){function foo(bar){return bar}return foo}();",
|
||||||
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxHQUFJQSxLQUFNLFdBQ04sUUFBU0MsS0FBS0QsS0FDVixNQUFPQSxLQUdYLE1BQU9DIn0=",
|
||||||
|
"",
|
||||||
|
].join("\n"));
|
||||||
assert.strictEqual(stderr, "WARN: inline source map not found\n");
|
assert.strictEqual(stderr, "WARN: inline source map not found\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should fail with multiple input and inline source map", function(done) {
|
it("Should fail with multiple input and inline source map", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-520/input.js test/input/issue-520/output.js --in-source-map inline --source-map-inline';
|
var command = uglifyjscmd + " test/input/issue-520/input.js test/input/issue-520/output.js --source-map content=inline,url=inline";
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stderr, "ERROR: Inline source map only works with singular input\n");
|
assert.strictEqual(stderr, "ERROR: inline source map only works with singular input\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should fail with acorn and inline source map", function(done) {
|
it("Should fail with acorn and inline source map", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-520/input.js --in-source-map inline --source-map-inline --acorn';
|
var command = uglifyjscmd + " test/input/issue-520/input.js --source-map content=inline,url=inline -p acorn";
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stderr, "ERROR: Inline source map only works with built-in parser\n");
|
assert.strictEqual(stderr, "ERROR: inline source map only works with built-in parser\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should fail with SpiderMonkey and inline source map", function(done) {
|
it("Should fail with SpiderMonkey and inline source map", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-520/input.js --in-source-map inline --source-map-inline --spidermonkey';
|
var command = uglifyjscmd + " test/input/issue-520/input.js --source-map content=inline,url=inline -p spidermonkey";
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stderr, "ERROR: Inline source map only works with built-in parser\n");
|
assert.strictEqual(stderr, "ERROR: inline source map only works with built-in parser\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -208,7 +212,7 @@ describe("bin/uglifyjs", function () {
|
||||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/simple.js:1,12");
|
assert.strictEqual(lines[0], "Parse error at test/input/invalid/simple.js:1,12");
|
||||||
assert.strictEqual(lines[1], "function f(a{}");
|
assert.strictEqual(lines[1], "function f(a{}");
|
||||||
assert.strictEqual(lines[2], " ^");
|
assert.strictEqual(lines[2], " ^");
|
||||||
assert.strictEqual(lines[3], "SyntaxError: Unexpected token punc «{», expected punc «,»");
|
assert.strictEqual(lines[3], "ERROR: Unexpected token punc «{», expected punc «,»");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -221,7 +225,7 @@ describe("bin/uglifyjs", function () {
|
||||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/tab.js:1,12");
|
assert.strictEqual(lines[0], "Parse error at test/input/invalid/tab.js:1,12");
|
||||||
assert.strictEqual(lines[1], "\t\tfoo(\txyz, 0abc);");
|
assert.strictEqual(lines[1], "\t\tfoo(\txyz, 0abc);");
|
||||||
assert.strictEqual(lines[2], "\t\t \t ^");
|
assert.strictEqual(lines[2], "\t\t \t ^");
|
||||||
assert.strictEqual(lines[3], "SyntaxError: Invalid syntax: 0abc");
|
assert.strictEqual(lines[3], "ERROR: Invalid syntax: 0abc");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -234,7 +238,7 @@ describe("bin/uglifyjs", function () {
|
||||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/eof.js:2,0");
|
assert.strictEqual(lines[0], "Parse error at test/input/invalid/eof.js:2,0");
|
||||||
assert.strictEqual(lines[1], "foo, bar(");
|
assert.strictEqual(lines[1], "foo, bar(");
|
||||||
assert.strictEqual(lines[2], " ^");
|
assert.strictEqual(lines[2], " ^");
|
||||||
assert.strictEqual(lines[3], "SyntaxError: Unexpected token: eof (undefined)");
|
assert.strictEqual(lines[3], "ERROR: Unexpected token: eof (undefined)");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -247,20 +251,10 @@ describe("bin/uglifyjs", function () {
|
||||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/loop-no-body.js:2,0");
|
assert.strictEqual(lines[0], "Parse error at test/input/invalid/loop-no-body.js:2,0");
|
||||||
assert.strictEqual(lines[1], "for (var i = 0; i < 1; i++) ");
|
assert.strictEqual(lines[1], "for (var i = 0; i < 1; i++) ");
|
||||||
assert.strictEqual(lines[2], " ^");
|
assert.strictEqual(lines[2], " ^");
|
||||||
assert.strictEqual(lines[3], "SyntaxError: Unexpected token: eof (undefined)");
|
assert.strictEqual(lines[3], "ERROR: Unexpected token: eof (undefined)");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should support hyphen as shorthand", function(done) {
|
|
||||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js -m keep-fnames=true';
|
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
|
||||||
if (err) throw err;
|
|
||||||
|
|
||||||
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("Should throw syntax error (5--)", function(done) {
|
it("Should throw syntax error (5--)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/assign_1.js';
|
var command = uglifyjscmd + ' test/input/invalid/assign_1.js';
|
||||||
|
|
||||||
|
|
@ -271,7 +265,7 @@ describe("bin/uglifyjs", function () {
|
||||||
"Parse error at test/input/invalid/assign_1.js:1,18",
|
"Parse error at test/input/invalid/assign_1.js:1,18",
|
||||||
"console.log(1 || 5--);",
|
"console.log(1 || 5--);",
|
||||||
" ^",
|
" ^",
|
||||||
"SyntaxError: Invalid use of -- operator"
|
"ERROR: Invalid use of -- operator"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
@ -286,7 +280,7 @@ describe("bin/uglifyjs", function () {
|
||||||
"Parse error at test/input/invalid/assign_2.js:1,32",
|
"Parse error at test/input/invalid/assign_2.js:1,32",
|
||||||
"console.log(2 || (Math.random() /= 2));",
|
"console.log(2 || (Math.random() /= 2));",
|
||||||
" ^",
|
" ^",
|
||||||
"SyntaxError: Invalid assignment"
|
"ERROR: Invalid assignment"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
@ -301,7 +295,7 @@ describe("bin/uglifyjs", function () {
|
||||||
"Parse error at test/input/invalid/assign_3.js:1,18",
|
"Parse error at test/input/invalid/assign_3.js:1,18",
|
||||||
"console.log(3 || ++this);",
|
"console.log(3 || ++this);",
|
||||||
" ^",
|
" ^",
|
||||||
"SyntaxError: Invalid use of ++ operator"
|
"ERROR: Invalid use of ++ operator"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,6 @@ describe("comment filters", function() {
|
||||||
|
|
||||||
it("Should handle shebang and preamble correctly", function() {
|
it("Should handle shebang and preamble correctly", function() {
|
||||||
var code = UglifyJS.minify("#!/usr/bin/node\nvar x = 10;", {
|
var code = UglifyJS.minify("#!/usr/bin/node\nvar x = 10;", {
|
||||||
fromString: true,
|
|
||||||
output: { preamble: "/* Build */" }
|
output: { preamble: "/* Build */" }
|
||||||
}).code;
|
}).code;
|
||||||
assert.strictEqual(code, "#!/usr/bin/node\n/* Build */\nvar x=10;");
|
assert.strictEqual(code, "#!/usr/bin/node\n/* Build */\nvar x=10;");
|
||||||
|
|
@ -83,7 +82,6 @@ describe("comment filters", function() {
|
||||||
|
|
||||||
it("Should handle preamble without shebang correctly", function() {
|
it("Should handle preamble without shebang correctly", function() {
|
||||||
var code = UglifyJS.minify("var x = 10;", {
|
var code = UglifyJS.minify("var x = 10;", {
|
||||||
fromString: true,
|
|
||||||
output: { preamble: "/* Build */" }
|
output: { preamble: "/* Build */" }
|
||||||
}).code;
|
}).code;
|
||||||
assert.strictEqual(code, "/* Build */\nvar x=10;");
|
assert.strictEqual(code, "/* Build */\nvar x=10;");
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ describe("Comment", function() {
|
||||||
|
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.throws(function() {
|
assert.throws(function() {
|
||||||
uglify.parse(tests[i], {fromString: true})
|
uglify.parse(tests[i]);
|
||||||
}, fail, tests[i]);
|
}, fail, tests[i]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -43,7 +43,7 @@ describe("Comment", function() {
|
||||||
|
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.throws(function() {
|
assert.throws(function() {
|
||||||
uglify.parse(tests[i], {fromString: true})
|
uglify.parse(tests[i]);
|
||||||
}, fail, tests[i]);
|
}, fail, tests[i]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,7 @@ describe("comment before constant", function() {
|
||||||
|
|
||||||
it("Should test comment before constant is retained and output after mangle.", function() {
|
it("Should test comment before constant is retained and output after mangle.", function() {
|
||||||
var result = Uglify.minify(js, {
|
var result = Uglify.minify(js, {
|
||||||
fromString: true,
|
|
||||||
compress: { collapse_vars: false, reduce_vars: false },
|
compress: { collapse_vars: false, reduce_vars: false },
|
||||||
mangle: {},
|
|
||||||
output: { comments: true },
|
output: { comments: true },
|
||||||
});
|
});
|
||||||
assert.strictEqual(result.code, 'function f(){/*c1*/var/*c2*/n=/*c3*/!1;return n}');
|
assert.strictEqual(result.code, 'function f(){/*c1*/var/*c2*/n=/*c3*/!1;return n}');
|
||||||
|
|
@ -16,12 +14,9 @@ describe("comment before constant", function() {
|
||||||
|
|
||||||
it("Should test code works when comments disabled.", function() {
|
it("Should test code works when comments disabled.", function() {
|
||||||
var result = Uglify.minify(js, {
|
var result = Uglify.minify(js, {
|
||||||
fromString: true,
|
|
||||||
compress: { collapse_vars: false, reduce_vars: false },
|
compress: { collapse_vars: false, reduce_vars: false },
|
||||||
mangle: {},
|
|
||||||
output: { comments: false },
|
output: { comments: false },
|
||||||
});
|
});
|
||||||
assert.strictEqual(result.code, 'function f(){var n=!1;return n}');
|
assert.strictEqual(result.code, 'function f(){var n=!1;return n}');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,7 @@ describe("Directives", function() {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
uglify.minify(
|
uglify.minify(
|
||||||
'"use strict";\'use strict\';"use strict";"use strict";;\'use strict\';console.log(\'use strict\');',
|
'"use strict";\'use strict\';"use strict";"use strict";;\'use strict\';console.log(\'use strict\');',
|
||||||
{fromString: true, output: {beautify: true, quote_style: 3}, compress: false}
|
{output: {beautify: true, quote_style: 3}, compress: false}
|
||||||
).code,
|
).code,
|
||||||
'"use strict";\n\n\'use strict\';\n\n"use strict";\n\n"use strict";\n\n;\'use strict\';\n\nconsole.log(\'use strict\');'
|
'"use strict";\n\n\'use strict\';\n\n"use strict";\n\n"use strict";\n\n;\'use strict\';\n\nconsole.log(\'use strict\');'
|
||||||
);
|
);
|
||||||
|
|
@ -225,7 +225,7 @@ describe("Directives", function() {
|
||||||
|
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
uglify.minify(tests[i][0], {fromString: true, quote_style: 3, compress: false, mangle: false}).code,
|
uglify.minify(tests[i][0], {compress: false, mangle: false}).code,
|
||||||
tests[i][1],
|
tests[i][1],
|
||||||
tests[i][0]
|
tests[i][0]
|
||||||
);
|
);
|
||||||
|
|
@ -234,7 +234,7 @@ describe("Directives", function() {
|
||||||
|
|
||||||
it("Should add double semicolon when relying on automatic semicolon insertion", function() {
|
it("Should add double semicolon when relying on automatic semicolon insertion", function() {
|
||||||
var code = uglify.minify('"use strict";"use\\x20strict";',
|
var code = uglify.minify('"use strict";"use\\x20strict";',
|
||||||
{fromString: true, output: {semicolons: false}, compress: false}
|
{output: {semicolons: false}, compress: false}
|
||||||
).code;
|
).code;
|
||||||
assert.strictEqual(code, '"use strict";;"use strict"\n');
|
assert.strictEqual(code, '"use strict";;"use strict"\n');
|
||||||
});
|
});
|
||||||
|
|
@ -340,7 +340,7 @@ describe("Directives", function() {
|
||||||
];
|
];
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
uglify.minify(tests[i][0], {fromString: true, output:{quote_style: tests[i][1]}, compress: false}).code,
|
uglify.minify(tests[i][0], {output:{quote_style: tests[i][1]}, compress: false}).code,
|
||||||
tests[i][2],
|
tests[i][2],
|
||||||
tests[i][0] + " using mode " + tests[i][1]
|
tests[i][0] + " using mode " + tests[i][1]
|
||||||
);
|
);
|
||||||
|
|
@ -362,7 +362,7 @@ describe("Directives", function() {
|
||||||
|
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
uglify.minify(tests[i][0], {fromString: true, compress: {collapse_vars: true, side_effects: true}}).code,
|
uglify.minify(tests[i][0], {compress: {collapse_vars: true, side_effects: true}}).code,
|
||||||
tests[i][1],
|
tests[i][1],
|
||||||
tests[i][0]
|
tests[i][0]
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,58 +1,80 @@
|
||||||
var Uglify = require('../../');
|
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
var exec = require("child_process").exec;
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
|
var readFileSync = require("fs").readFileSync;
|
||||||
|
|
||||||
describe("minify() with input file globs", function() {
|
describe("bin/uglifyjs with input file globs", function() {
|
||||||
it("minify() with one input file glob string.", function() {
|
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||||
var result = Uglify.minify("test/input/issue-1242/foo.*");
|
it("bin/uglifyjs with one input file extension glob.", function(done) {
|
||||||
assert.strictEqual(result.code, 'function foo(o){print("Foo:",2*o)}var print=console.log.bind(console);');
|
var command = uglifyjscmd + ' "test/input/issue-1242/foo.*" -cm';
|
||||||
});
|
|
||||||
it("minify() with an array of one input file glob.", function() {
|
exec(command, function(err, stdout) {
|
||||||
var result = Uglify.minify([
|
if (err) throw err;
|
||||||
"test/input/issue-1242/b*.es5",
|
|
||||||
]);
|
assert.strictEqual(stdout, 'function foo(o){print("Foo:",2*o)}var print=console.log.bind(console);\n');
|
||||||
assert.strictEqual(result.code, 'function bar(n){return 3*n}function baz(n){return n/2}');
|
done();
|
||||||
});
|
|
||||||
it("minify() with an array of multiple input file globs.", function() {
|
|
||||||
var result = Uglify.minify([
|
|
||||||
"test/input/issue-1242/???.es5",
|
|
||||||
"test/input/issue-1242/*.js",
|
|
||||||
], {
|
|
||||||
compress: { toplevel: true }
|
|
||||||
});
|
});
|
||||||
assert.strictEqual(result.code, 'var print=console.log.bind(console),a=function(n){return 3*n}(3),b=function(n){return n/2}(12);print("qux",a,b),function(n){print("Foo:",2*n)}(11);');
|
|
||||||
});
|
});
|
||||||
it("should throw with non-matching glob string", function() {
|
it("bin/uglifyjs with one input file name glob.", function(done) {
|
||||||
var glob = "test/input/issue-1242/blah.*";
|
var command = uglifyjscmd + ' "test/input/issue-1242/b*.es5" -cm';
|
||||||
assert.strictEqual(Uglify.simple_glob(glob).length, 1);
|
|
||||||
assert.strictEqual(Uglify.simple_glob(glob)[0], glob);
|
exec(command, function(err, stdout) {
|
||||||
assert.throws(function() {
|
if (err) throw err;
|
||||||
Uglify.minify(glob);
|
|
||||||
}, "should throw file not found");
|
assert.strictEqual(stdout, 'function bar(n){return 3*n}function baz(n){return n/2}\n');
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
it('"?" in glob string should not match "/"', function() {
|
it("bin/uglifyjs with multiple input file globs.", function(done) {
|
||||||
var glob = "test/input?issue-1242/foo.*";
|
var command = uglifyjscmd + ' "test/input/issue-1242/???.es5" "test/input/issue-1242/*.js" -mc toplevel';
|
||||||
assert.strictEqual(Uglify.simple_glob(glob).length, 1);
|
|
||||||
assert.strictEqual(Uglify.simple_glob(glob)[0], glob);
|
exec(command, function(err, stdout) {
|
||||||
assert.throws(function() {
|
if (err) throw err;
|
||||||
Uglify.minify(glob);
|
|
||||||
}, "should throw file not found");
|
assert.strictEqual(stdout, 'var print=console.log.bind(console),a=function(n){return 3*n}(3),b=function(n){return n/2}(12);print("qux",a,b),function(n){print("Foo:",2*n)}(11);\n');
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
it("should handle special characters in glob string", function() {
|
it("should throw with non-matching glob string", function(done) {
|
||||||
var result = Uglify.minify("test/input/issue-1632/^{*}[???](*)+$.??");
|
var command = uglifyjscmd + ' "test/input/issue-1242/blah.*"';
|
||||||
assert.strictEqual(result.code, "console.log(x);");
|
|
||||||
|
exec(command, function(err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.ok(/^ERROR: ENOENT/.test(stderr));
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
it("should handle array of glob strings - matching and otherwise", function() {
|
it('"?" in glob string should not match "/"', function(done) {
|
||||||
|
var command = uglifyjscmd + ' "test/input?issue-1242/foo.*"';
|
||||||
|
|
||||||
|
exec(command, function(err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.ok(/^ERROR: ENOENT/.test(stderr));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("should handle special characters in glob string", function(done) {
|
||||||
|
var command = uglifyjscmd + ' "test/input/issue-1632/^{*}[???](*)+$.??" -cm';
|
||||||
|
|
||||||
|
exec(command, function(err, stdout) {
|
||||||
|
if (err) throw err;
|
||||||
|
|
||||||
|
assert.strictEqual(stdout, "console.log(x);\n");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("should handle array of glob strings - matching and otherwise", function(done) {
|
||||||
var dir = "test/input/issue-1242";
|
var dir = "test/input/issue-1242";
|
||||||
var matches = Uglify.simple_glob([
|
var command = uglifyjscmd + ' "' + [
|
||||||
path.join(dir, "b*.es5"),
|
path.join(dir, "b*.es5"),
|
||||||
path.join(dir, "z*.es5"),
|
path.join(dir, "z*.es5"),
|
||||||
path.join(dir, "*.js"),
|
path.join(dir, "*.js")
|
||||||
]);
|
].join('" "') + '"';
|
||||||
assert.strictEqual(matches.length, 4);
|
|
||||||
assert.strictEqual(matches[0], path.join(dir, "bar.es5"));
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.strictEqual(matches[1], path.join(dir, "baz.es5"));
|
assert.ok(err);
|
||||||
assert.strictEqual(matches[2], path.join(dir, "z*.es5"));
|
assert.ok(/^ERROR: ENOENT.*?z\*\.es5/.test(stderr));
|
||||||
assert.strictEqual(matches[3], path.join(dir, "qux.js"));
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,7 @@ describe("Huge number of comments.", function() {
|
||||||
for (i = 1; i <= 5000; ++i) { js += "// " + i + "\n"; }
|
for (i = 1; i <= 5000; ++i) { js += "// " + i + "\n"; }
|
||||||
for (; i <= 10000; ++i) { js += "/* " + i + " */ /**/"; }
|
for (; i <= 10000; ++i) { js += "/* " + i + " */ /**/"; }
|
||||||
js += "x; }";
|
js += "x; }";
|
||||||
var result = Uglify.minify(js, {
|
var result = Uglify.minify(js, { mangle: false });
|
||||||
fromString: true,
|
|
||||||
mangle: false,
|
|
||||||
compress: {}
|
|
||||||
});
|
|
||||||
assert.strictEqual(result.code, "function lots_of_comments(x){return 7-x}");
|
assert.strictEqual(result.code, "function lots_of_comments(x){return 7-x}");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@ describe("input sourcemaps", function() {
|
||||||
transpilemap = sourceMap || getMap();
|
transpilemap = sourceMap || getMap();
|
||||||
|
|
||||||
var result = Uglify.minify(transpiled, {
|
var result = Uglify.minify(transpiled, {
|
||||||
fromString: true,
|
sourceMap: {
|
||||||
inSourceMap: transpilemap,
|
content: transpilemap
|
||||||
outSourceMap: true
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
map = new SourceMapConsumer(result.map);
|
map = new SourceMapConsumer(result.map);
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ describe("let", function() {
|
||||||
s += "var v" + i + "=0;";
|
s += "var v" + i + "=0;";
|
||||||
}
|
}
|
||||||
s += '}';
|
s += '}';
|
||||||
var result = Uglify.minify(s, {fromString: true, compress: false});
|
var result = Uglify.minify(s, {compress: false});
|
||||||
|
|
||||||
// Verify that select keywords and reserved keywords not produced
|
// Verify that select keywords and reserved keywords not produced
|
||||||
assert.strictEqual(result.code.indexOf("var let="), -1);
|
assert.strictEqual(result.code.indexOf("var let="), -1);
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,8 @@ var assert = require("assert");
|
||||||
|
|
||||||
describe("line-endings", function() {
|
describe("line-endings", function() {
|
||||||
var options = {
|
var options = {
|
||||||
fromString: true,
|
|
||||||
mangle: false,
|
|
||||||
compress: false,
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
output: {
|
output: {
|
||||||
beautify: false,
|
beautify: false,
|
||||||
comments: /^!/,
|
comments: /^!/,
|
||||||
|
|
|
||||||
|
|
@ -6,43 +6,41 @@ describe("Input file as map", function() {
|
||||||
var jsMap = {
|
var jsMap = {
|
||||||
'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'
|
'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'
|
||||||
};
|
};
|
||||||
var result = Uglify.minify(jsMap, {fromString: true, outSourceMap: true});
|
var result = Uglify.minify(jsMap, {sourceMap: true});
|
||||||
|
|
||||||
var map = JSON.parse(result.map);
|
var map = JSON.parse(result.map);
|
||||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3};');
|
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3};');
|
||||||
assert.deepEqual(map.sources, ['/scripts/foo.js']);
|
assert.deepEqual(map.sources, ['/scripts/foo.js']);
|
||||||
assert.strictEqual(map.file, undefined);
|
assert.strictEqual(map.file, undefined);
|
||||||
|
|
||||||
result = Uglify.minify(jsMap, {fromString: true, outFileName: 'out.js'});
|
result = Uglify.minify(jsMap);
|
||||||
assert.strictEqual(result.map, null);
|
assert.strictEqual(result.map, undefined);
|
||||||
|
|
||||||
result = Uglify.minify(jsMap, {fromString: true, outFileName: 'out.js', outSourceMap: true});
|
result = Uglify.minify(jsMap, {sourceMap: {filename: 'out.js'}});
|
||||||
map = JSON.parse(result.map);
|
map = JSON.parse(result.map);
|
||||||
assert.strictEqual(map.file, 'out.js');
|
assert.strictEqual(map.file, 'out.js');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should accept array of objects and strings", function() {
|
it("Should accept array of strings", function() {
|
||||||
var jsSeq = [
|
var jsSeq = [
|
||||||
{'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'},
|
'var foo = {"x": 1, y: 2, \'z\': 3};',
|
||||||
'var bar = 15;'
|
'var bar = 15;'
|
||||||
];
|
];
|
||||||
var result = Uglify.minify(jsSeq, {fromString: true, outSourceMap: true});
|
var result = Uglify.minify(jsSeq, {sourceMap: true});
|
||||||
|
|
||||||
var map = JSON.parse(result.map);
|
var map = JSON.parse(result.map);
|
||||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3},bar=15;');
|
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3},bar=15;');
|
||||||
assert.strictEqual(map.sources[0], '/scripts/foo.js');
|
assert.deepEqual(map.sources, ['0', '1']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should correctly include source", function() {
|
it("Should correctly include source", function() {
|
||||||
var jsSeq = [
|
var jsMap = {
|
||||||
{'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'},
|
'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'
|
||||||
'var bar = 15;'
|
};
|
||||||
];
|
var result = Uglify.minify(jsMap, {sourceMap: {includeSources: true}});
|
||||||
var result = Uglify.minify(jsSeq, {fromString: true, outSourceMap: true, sourceMapIncludeSources: true});
|
|
||||||
|
|
||||||
var map = JSON.parse(result.map);
|
var map = JSON.parse(result.map);
|
||||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3},bar=15;');
|
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3};');
|
||||||
assert.deepEqual(map.sourcesContent, ['var foo = {"x": 1, y: 2, \'z\': 3};', 'var bar = 15;']);
|
assert.deepEqual(map.sourcesContent, ['var foo = {"x": 1, y: 2, \'z\': 3};']);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,14 @@ var Uglify = require('../../');
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var readFileSync = require("fs").readFileSync;
|
var readFileSync = require("fs").readFileSync;
|
||||||
|
|
||||||
|
function read(path) {
|
||||||
|
return readFileSync(path, "utf8");
|
||||||
|
}
|
||||||
|
|
||||||
describe("minify", function() {
|
describe("minify", function() {
|
||||||
it("Should test basic sanity of minify with default options", function() {
|
it("Should test basic sanity of minify with default options", function() {
|
||||||
var js = 'function foo(bar) { if (bar) return 3; else return 7; var u = not_called(); }';
|
var js = 'function foo(bar) { if (bar) return 3; else return 7; var u = not_called(); }';
|
||||||
var result = Uglify.minify(js, {fromString: true});
|
var result = Uglify.minify(js);
|
||||||
assert.strictEqual(result.code, 'function foo(n){return n?3:7}');
|
assert.strictEqual(result.code, 'function foo(n){return n?3:7}');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -13,7 +17,7 @@ describe("minify", function() {
|
||||||
it("Should preserve quotes in object literals", function() {
|
it("Should preserve quotes in object literals", function() {
|
||||||
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
||||||
var result = Uglify.minify(js, {
|
var result = Uglify.minify(js, {
|
||||||
fromString: true, output: {
|
output: {
|
||||||
keep_quoted_props: true
|
keep_quoted_props: true
|
||||||
}});
|
}});
|
||||||
assert.strictEqual(result.code, 'var foo={"x":1,y:2,"z":3};');
|
assert.strictEqual(result.code, 'var foo={"x":1,y:2,"z":3};');
|
||||||
|
|
@ -22,7 +26,7 @@ describe("minify", function() {
|
||||||
it("Should preserve quote styles when quote_style is 3", function() {
|
it("Should preserve quote styles when quote_style is 3", function() {
|
||||||
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
||||||
var result = Uglify.minify(js, {
|
var result = Uglify.minify(js, {
|
||||||
fromString: true, output: {
|
output: {
|
||||||
keep_quoted_props: true,
|
keep_quoted_props: true,
|
||||||
quote_style: 3
|
quote_style: 3
|
||||||
}});
|
}});
|
||||||
|
|
@ -32,7 +36,7 @@ describe("minify", function() {
|
||||||
it("Should not preserve quotes in object literals when disabled", function() {
|
it("Should not preserve quotes in object literals when disabled", function() {
|
||||||
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
||||||
var result = Uglify.minify(js, {
|
var result = Uglify.minify(js, {
|
||||||
fromString: true, output: {
|
output: {
|
||||||
keep_quoted_props: false,
|
keep_quoted_props: false,
|
||||||
quote_style: 3
|
quote_style: 3
|
||||||
}});
|
}});
|
||||||
|
|
@ -44,12 +48,13 @@ describe("minify", function() {
|
||||||
it("Shouldn't mangle quoted properties", function() {
|
it("Shouldn't mangle quoted properties", function() {
|
||||||
var js = 'a["foo"] = "bar"; a.color = "red"; x = {"bar": 10};';
|
var js = 'a["foo"] = "bar"; a.color = "red"; x = {"bar": 10};';
|
||||||
var result = Uglify.minify(js, {
|
var result = Uglify.minify(js, {
|
||||||
fromString: true,
|
|
||||||
compress: {
|
compress: {
|
||||||
properties: false
|
properties: false
|
||||||
},
|
},
|
||||||
mangleProperties: {
|
mangle: {
|
||||||
ignore_quoted: true
|
properties: {
|
||||||
|
ignore_quoted: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
keep_quoted_props: true,
|
keep_quoted_props: true,
|
||||||
|
|
@ -63,10 +68,12 @@ describe("minify", function() {
|
||||||
|
|
||||||
describe("inSourceMap", function() {
|
describe("inSourceMap", function() {
|
||||||
it("Should read the given string filename correctly when sourceMapIncludeSources is enabled (#1236)", function() {
|
it("Should read the given string filename correctly when sourceMapIncludeSources is enabled (#1236)", function() {
|
||||||
var result = Uglify.minify('./test/input/issue-1236/simple.js', {
|
var result = Uglify.minify(read("./test/input/issue-1236/simple.js"), {
|
||||||
outSourceMap: "simple.min.js.map",
|
sourceMap: {
|
||||||
inSourceMap: "./test/input/issue-1236/simple.js.map",
|
content: read("./test/input/issue-1236/simple.js.map"),
|
||||||
sourceMapIncludeSources: true
|
filename: "simple.min.js",
|
||||||
|
includeSources: true
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var map = JSON.parse(result.map);
|
var map = JSON.parse(result.map);
|
||||||
|
|
@ -77,10 +84,12 @@ describe("minify", function() {
|
||||||
'let foo = x => "foo " + x;\nconsole.log(foo("bar"));');
|
'let foo = x => "foo " + x;\nconsole.log(foo("bar"));');
|
||||||
});
|
});
|
||||||
it("Should process inline source map", function() {
|
it("Should process inline source map", function() {
|
||||||
var code = Uglify.minify("./test/input/issue-520/input.js", {
|
var code = Uglify.minify(read("./test/input/issue-520/input.js"), {
|
||||||
compress: { toplevel: true },
|
compress: { toplevel: true },
|
||||||
inSourceMap: "inline",
|
sourceMap: {
|
||||||
sourceMapInline: true
|
content: "inline",
|
||||||
|
url: "inline"
|
||||||
|
}
|
||||||
}).code + "\n";
|
}).code + "\n";
|
||||||
assert.strictEqual(code, readFileSync("test/input/issue-520/output.js", "utf8"));
|
assert.strictEqual(code, readFileSync("test/input/issue-520/output.js", "utf8"));
|
||||||
});
|
});
|
||||||
|
|
@ -91,9 +100,11 @@ describe("minify", function() {
|
||||||
warnings.push(txt);
|
warnings.push(txt);
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
var result = Uglify.minify("./test/input/issue-1323/sample.js", {
|
var result = Uglify.minify(read("./test/input/issue-1323/sample.js"), {
|
||||||
inSourceMap: "inline",
|
|
||||||
mangle: false,
|
mangle: false,
|
||||||
|
sourceMap: {
|
||||||
|
content: "inline"
|
||||||
|
}
|
||||||
});
|
});
|
||||||
assert.strictEqual(result.code, "var bar=function(){function foo(bar){return bar}return foo}();");
|
assert.strictEqual(result.code, "var bar=function(){function foo(bar){return bar}return foo}();");
|
||||||
assert.strictEqual(warnings.length, 1);
|
assert.strictEqual(warnings.length, 1);
|
||||||
|
|
@ -105,20 +116,13 @@ describe("minify", function() {
|
||||||
it("Should fail with multiple input and inline source map", function() {
|
it("Should fail with multiple input and inline source map", function() {
|
||||||
assert.throws(function() {
|
assert.throws(function() {
|
||||||
Uglify.minify([
|
Uglify.minify([
|
||||||
"./test/input/issue-520/input.js",
|
read("./test/input/issue-520/input.js"),
|
||||||
"./test/input/issue-520/output.js"
|
read("./test/input/issue-520/output.js")
|
||||||
], {
|
], {
|
||||||
inSourceMap: "inline",
|
sourceMap: {
|
||||||
sourceMapInline: true
|
content: "inline",
|
||||||
});
|
url: "inline"
|
||||||
});
|
}
|
||||||
});
|
|
||||||
it("Should fail with SpiderMonkey and inline source map", function() {
|
|
||||||
assert.throws(function() {
|
|
||||||
Uglify.minify("./test/input/issue-520/input.js", {
|
|
||||||
inSourceMap: "inline",
|
|
||||||
sourceMapInline: true,
|
|
||||||
spidermonkey: true
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -127,17 +131,16 @@ describe("minify", function() {
|
||||||
describe("sourceMapInline", function() {
|
describe("sourceMapInline", function() {
|
||||||
it("should append source map to output js when sourceMapInline is enabled", function() {
|
it("should append source map to output js when sourceMapInline is enabled", function() {
|
||||||
var result = Uglify.minify('var a = function(foo) { return foo; };', {
|
var result = Uglify.minify('var a = function(foo) { return foo; };', {
|
||||||
fromString: true,
|
sourceMap: {
|
||||||
sourceMapInline: true
|
url: "inline"
|
||||||
|
}
|
||||||
});
|
});
|
||||||
var code = result.code;
|
var code = result.code;
|
||||||
assert.strictEqual(code, "var a=function(n){return n};\n" +
|
assert.strictEqual(code, "var a=function(n){return n};\n" +
|
||||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIj8iXSwibmFtZXMiOlsiYSIsImZvbyJdLCJtYXBwaW5ncyI6IkFBQUEsR0FBSUEsR0FBSSxTQUFTQyxHQUFPLE1BQU9BIn0=");
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsiYSIsImZvbyJdLCJtYXBwaW5ncyI6IkFBQUEsR0FBSUEsR0FBSSxTQUFTQyxHQUFPLE1BQU9BIn0=");
|
||||||
});
|
});
|
||||||
it("should not append source map to output js when sourceMapInline is not enabled", function() {
|
it("should not append source map to output js when sourceMapInline is not enabled", function() {
|
||||||
var result = Uglify.minify('var a = function(foo) { return foo; };', {
|
var result = Uglify.minify('var a = function(foo) { return foo; };');
|
||||||
fromString: true
|
|
||||||
});
|
|
||||||
var code = result.code;
|
var code = result.code;
|
||||||
assert.strictEqual(code, "var a=function(n){return n};");
|
assert.strictEqual(code, "var a=function(n){return n};");
|
||||||
});
|
});
|
||||||
|
|
@ -146,7 +149,6 @@ describe("minify", function() {
|
||||||
describe("#__PURE__", function() {
|
describe("#__PURE__", function() {
|
||||||
it("should drop #__PURE__ hint after use", function() {
|
it("should drop #__PURE__ hint after use", function() {
|
||||||
var result = Uglify.minify('//@__PURE__ comment1 #__PURE__ comment2\n foo(), bar();', {
|
var result = Uglify.minify('//@__PURE__ comment1 #__PURE__ comment2\n foo(), bar();', {
|
||||||
fromString: true,
|
|
||||||
output: {
|
output: {
|
||||||
comments: "all",
|
comments: "all",
|
||||||
beautify: false,
|
beautify: false,
|
||||||
|
|
@ -157,7 +159,6 @@ describe("minify", function() {
|
||||||
});
|
});
|
||||||
it("should not drop #__PURE__ hint if function is retained", function() {
|
it("should not drop #__PURE__ hint if function is retained", function() {
|
||||||
var result = Uglify.minify("var a = /*#__PURE__*/(function(){ foo(); })();", {
|
var result = Uglify.minify("var a = /*#__PURE__*/(function(){ foo(); })();", {
|
||||||
fromString: true,
|
|
||||||
output: {
|
output: {
|
||||||
comments: "all",
|
comments: "all",
|
||||||
beautify: false,
|
beautify: false,
|
||||||
|
|
@ -171,11 +172,11 @@ describe("minify", function() {
|
||||||
describe("JS_Parse_Error", function() {
|
describe("JS_Parse_Error", function() {
|
||||||
it("should throw syntax error", function() {
|
it("should throw syntax error", function() {
|
||||||
assert.throws(function() {
|
assert.throws(function() {
|
||||||
Uglify.minify("function f(a{}", { fromString: true });
|
Uglify.minify("function f(a{}");
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
assert.ok(err instanceof Error);
|
assert.ok(err instanceof Error);
|
||||||
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token punc «{», expected punc «,»");
|
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token punc «{», expected punc «,»");
|
||||||
assert.strictEqual(err.filename, 0);
|
assert.strictEqual(err.filename, "0");
|
||||||
assert.strictEqual(err.line, 1);
|
assert.strictEqual(err.line, 1);
|
||||||
assert.strictEqual(err.col, 12);
|
assert.strictEqual(err.col, 12);
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -191,5 +192,4 @@ describe("minify", function() {
|
||||||
assert.strictEqual(ast.print_to_string(), "function f(a){for(var i=0;i<a;i++)console.log(i)}");
|
assert.strictEqual(ast.print_to_string(), "function f(a){for(var i=0;i<a;i++)console.log(i)}");
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ describe("New", function() {
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
uglify.minify(tests[i], {
|
uglify.minify(tests[i], {
|
||||||
fromString: true,
|
|
||||||
output: {beautify: true},
|
output: {beautify: true},
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false
|
mangle: false
|
||||||
|
|
@ -76,7 +75,6 @@ describe("New", function() {
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
uglify.minify(tests[i], {
|
uglify.minify(tests[i], {
|
||||||
fromString: true,
|
|
||||||
output: {beautify: false},
|
output: {beautify: false},
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false
|
mangle: false
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,7 @@ describe("screw-ie8", function () {
|
||||||
}\
|
}\
|
||||||
console.log('undefined is ' + undefined);\
|
console.log('undefined is ' + undefined);\
|
||||||
return b === undefined;\
|
return b === undefined;\
|
||||||
};", {
|
};"
|
||||||
fromString: true
|
|
||||||
}
|
|
||||||
).code,
|
).code,
|
||||||
'function a(o){try{throw"Stuff"}catch(o){console.log("caught: "+o)}return console.log("undefined is "+void 0),void 0===o}'
|
'function a(o){try{throw"Stuff"}catch(o){console.log("caught: "+o)}return console.log("undefined is "+void 0),void 0===o}'
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ describe("spidermonkey export/import sanity test", function() {
|
||||||
this.timeout(20000);
|
this.timeout(20000);
|
||||||
|
|
||||||
var uglifyjs = '"' + process.argv[0] + '" bin/uglifyjs';
|
var uglifyjs = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||||
var command = uglifyjs + " --self -cm --wrap SpiderUglify --dump-spidermonkey-ast | " +
|
var command = uglifyjs + " --self -cm --wrap SpiderUglify -o spidermonkey | " +
|
||||||
uglifyjs + " --spidermonkey -cm";
|
uglifyjs + " -p spidermonkey -cm";
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
|
||||||
|
|
@ -768,7 +768,6 @@ function createVarName(maybe, dontStore) {
|
||||||
function try_beautify(code, result) {
|
function try_beautify(code, result) {
|
||||||
try {
|
try {
|
||||||
var beautified = UglifyJS.minify(code, {
|
var beautified = UglifyJS.minify(code, {
|
||||||
fromString: true,
|
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
output: {
|
output: {
|
||||||
|
|
@ -802,8 +801,8 @@ var default_options = {
|
||||||
mangle: {
|
mangle: {
|
||||||
"cache": null,
|
"cache": null,
|
||||||
"eval": false,
|
"eval": false,
|
||||||
|
"ie8": false,
|
||||||
"keep_fnames": false,
|
"keep_fnames": false,
|
||||||
"screw_ie8": true,
|
|
||||||
"toplevel": false,
|
"toplevel": false,
|
||||||
},
|
},
|
||||||
output: infer_options(UglifyJS.OutputStream),
|
output: infer_options(UglifyJS.OutputStream),
|
||||||
|
|
@ -869,10 +868,7 @@ function log(options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var minify_options = require("./ufuzz.json").map(function(options) {
|
var minify_options = require("./ufuzz.json").map(JSON.stringify);
|
||||||
options.fromString = true;
|
|
||||||
return JSON.stringify(options);
|
|
||||||
});
|
|
||||||
var original_code, original_result;
|
var original_code, original_result;
|
||||||
var uglify_code, uglify_result, ok;
|
var uglify_code, uglify_result, ok;
|
||||||
for (var round = 1; round <= num_iterations; round++) {
|
for (var round = 1; round <= num_iterations; round++) {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ exports["base54"] = base54;
|
||||||
exports["defaults"] = defaults;
|
exports["defaults"] = defaults;
|
||||||
exports["mangle_properties"] = mangle_properties;
|
exports["mangle_properties"] = mangle_properties;
|
||||||
exports["merge"] = merge;
|
exports["merge"] = merge;
|
||||||
|
exports["minify"] = minify;
|
||||||
exports["parse"] = parse;
|
exports["parse"] = parse;
|
||||||
exports["push_uniq"] = push_uniq;
|
exports["push_uniq"] = push_uniq;
|
||||||
exports["string_template"] = string_template;
|
exports["string_template"] = string_template;
|
||||||
|
|
|
||||||
255
tools/node.js
255
tools/node.js
|
|
@ -4,7 +4,6 @@
|
||||||
stream._handle.setBlocking(true);
|
stream._handle.setBlocking(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
var path = require("path");
|
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
|
|
||||||
var UglifyJS = exports;
|
var UglifyJS = exports;
|
||||||
|
|
@ -19,6 +18,7 @@ var FILES = UglifyJS.FILES = [
|
||||||
"../lib/sourcemap.js",
|
"../lib/sourcemap.js",
|
||||||
"../lib/mozilla-ast.js",
|
"../lib/mozilla-ast.js",
|
||||||
"../lib/propmangle.js",
|
"../lib/propmangle.js",
|
||||||
|
"../lib/minify.js",
|
||||||
"./exports.js",
|
"./exports.js",
|
||||||
].map(function(file){
|
].map(function(file){
|
||||||
return require.resolve(file);
|
return require.resolve(file);
|
||||||
|
|
@ -31,168 +31,6 @@ new Function("MOZ_SourceMap", "exports", FILES.map(function(file){
|
||||||
UglifyJS
|
UglifyJS
|
||||||
);
|
);
|
||||||
|
|
||||||
UglifyJS.AST_Node.warn_function = function(txt) {
|
|
||||||
console.error("WARN: %s", txt);
|
|
||||||
};
|
|
||||||
|
|
||||||
function read_source_map(code) {
|
|
||||||
var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
|
|
||||||
if (!match) {
|
|
||||||
UglifyJS.AST_Node.warn("inline source map not found");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return JSON.parse(new Buffer(match[2], "base64"));
|
|
||||||
}
|
|
||||||
|
|
||||||
UglifyJS.minify = function(files, options) {
|
|
||||||
options = UglifyJS.defaults(options, {
|
|
||||||
compress : {},
|
|
||||||
fromString : false,
|
|
||||||
inSourceMap : null,
|
|
||||||
mangle : {},
|
|
||||||
mangleProperties : false,
|
|
||||||
nameCache : null,
|
|
||||||
outFileName : null,
|
|
||||||
output : null,
|
|
||||||
outSourceMap : null,
|
|
||||||
parse : {},
|
|
||||||
sourceMapInline : false,
|
|
||||||
sourceMapUrl : null,
|
|
||||||
sourceRoot : null,
|
|
||||||
spidermonkey : false,
|
|
||||||
warnings : false,
|
|
||||||
});
|
|
||||||
UglifyJS.base54.reset();
|
|
||||||
|
|
||||||
var inMap = options.inSourceMap;
|
|
||||||
if (typeof inMap == "string" && inMap != "inline") {
|
|
||||||
inMap = JSON.parse(fs.readFileSync(inMap, "utf8"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. parse
|
|
||||||
var toplevel = null,
|
|
||||||
sourcesContent = {};
|
|
||||||
|
|
||||||
if (options.spidermonkey) {
|
|
||||||
if (inMap == "inline") {
|
|
||||||
throw new Error("inline source map only works with built-in parser");
|
|
||||||
}
|
|
||||||
toplevel = UglifyJS.AST_Node.from_mozilla_ast(files);
|
|
||||||
} else {
|
|
||||||
function addFile(file, fileUrl) {
|
|
||||||
var code = options.fromString
|
|
||||||
? file
|
|
||||||
: fs.readFileSync(file, "utf8");
|
|
||||||
if (inMap == "inline") {
|
|
||||||
inMap = read_source_map(code);
|
|
||||||
}
|
|
||||||
sourcesContent[fileUrl] = code;
|
|
||||||
toplevel = UglifyJS.parse(code, {
|
|
||||||
filename: fileUrl,
|
|
||||||
toplevel: toplevel,
|
|
||||||
bare_returns: options.parse ? options.parse.bare_returns : undefined
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!options.fromString) {
|
|
||||||
files = UglifyJS.simple_glob(files);
|
|
||||||
if (inMap == "inline" && files.length > 1) {
|
|
||||||
throw new Error("inline source map only works with singular input");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[].concat(files).forEach(function (files, i) {
|
|
||||||
if (typeof files === 'string') {
|
|
||||||
addFile(files, options.fromString ? i : files);
|
|
||||||
} else {
|
|
||||||
for (var fileUrl in files) {
|
|
||||||
addFile(files[fileUrl], fileUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (options.wrap) {
|
|
||||||
toplevel = toplevel.wrap_commonjs(options.wrap, options.exportAll);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. compress
|
|
||||||
if (options.compress) {
|
|
||||||
var compress = { warnings: options.warnings };
|
|
||||||
UglifyJS.merge(compress, options.compress);
|
|
||||||
toplevel.figure_out_scope(options.mangle);
|
|
||||||
var sq = UglifyJS.Compressor(compress);
|
|
||||||
toplevel = sq.compress(toplevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. mangle properties
|
|
||||||
if (options.mangleProperties || options.nameCache) {
|
|
||||||
options.mangleProperties.cache = UglifyJS.readNameCache(options.nameCache, "props");
|
|
||||||
toplevel = UglifyJS.mangle_properties(toplevel, options.mangleProperties);
|
|
||||||
UglifyJS.writeNameCache(options.nameCache, "props", options.mangleProperties.cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. mangle
|
|
||||||
if (options.mangle) {
|
|
||||||
toplevel.figure_out_scope(options.mangle);
|
|
||||||
toplevel.compute_char_frequency(options.mangle);
|
|
||||||
toplevel.mangle_names(options.mangle);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. output
|
|
||||||
var output = { max_line_len: 32000 };
|
|
||||||
if (options.outSourceMap || options.sourceMapInline) {
|
|
||||||
output.source_map = UglifyJS.SourceMap({
|
|
||||||
// prefer outFileName, otherwise use outSourceMap without .map suffix
|
|
||||||
file: options.outFileName || (typeof options.outSourceMap === 'string' ? options.outSourceMap.replace(/\.map$/i, '') : null),
|
|
||||||
orig: inMap,
|
|
||||||
root: options.sourceRoot
|
|
||||||
});
|
|
||||||
if (options.sourceMapIncludeSources) {
|
|
||||||
for (var file in sourcesContent) {
|
|
||||||
if (sourcesContent.hasOwnProperty(file)) {
|
|
||||||
output.source_map.get().setSourceContent(file, sourcesContent[file]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (options.output) {
|
|
||||||
UglifyJS.merge(output, options.output);
|
|
||||||
}
|
|
||||||
var stream = UglifyJS.OutputStream(output);
|
|
||||||
toplevel.print(stream);
|
|
||||||
|
|
||||||
|
|
||||||
var source_map = output.source_map;
|
|
||||||
if (source_map) {
|
|
||||||
source_map = source_map + "";
|
|
||||||
}
|
|
||||||
|
|
||||||
var mappingUrlPrefix = "\n//# sourceMappingURL=";
|
|
||||||
if (options.sourceMapInline) {
|
|
||||||
stream += mappingUrlPrefix + "data:application/json;charset=utf-8;base64," + new Buffer(source_map).toString("base64");
|
|
||||||
} else if (options.outSourceMap && typeof options.outSourceMap === "string" && options.sourceMapUrl !== false) {
|
|
||||||
stream += mappingUrlPrefix + (typeof options.sourceMapUrl === "string" ? options.sourceMapUrl : options.outSourceMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
code : stream + "",
|
|
||||||
map : source_map
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// UglifyJS.describe_ast = function() {
|
|
||||||
// function doitem(ctor) {
|
|
||||||
// var sub = {};
|
|
||||||
// ctor.SUBCLASSES.forEach(function(ctor){
|
|
||||||
// sub[ctor.TYPE] = doitem(ctor);
|
|
||||||
// });
|
|
||||||
// var ret = {};
|
|
||||||
// if (ctor.SELF_PROPS.length > 0) ret.props = ctor.SELF_PROPS;
|
|
||||||
// if (ctor.SUBCLASSES.length > 0) ret.sub = sub;
|
|
||||||
// return ret;
|
|
||||||
// }
|
|
||||||
// return doitem(UglifyJS.AST_Node).sub;
|
|
||||||
// }
|
|
||||||
|
|
||||||
UglifyJS.describe_ast = function() {
|
UglifyJS.describe_ast = function() {
|
||||||
var out = UglifyJS.OutputStream({ beautify: true });
|
var out = UglifyJS.OutputStream({ beautify: true });
|
||||||
function doitem(ctor) {
|
function doitem(ctor) {
|
||||||
|
|
@ -227,94 +65,3 @@ UglifyJS.describe_ast = function() {
|
||||||
doitem(UglifyJS.AST_Node);
|
doitem(UglifyJS.AST_Node);
|
||||||
return out + "";
|
return out + "";
|
||||||
};
|
};
|
||||||
|
|
||||||
function readReservedFile(filename, reserved) {
|
|
||||||
if (!reserved) {
|
|
||||||
reserved = { vars: [], props: [] };
|
|
||||||
}
|
|
||||||
var data = fs.readFileSync(filename, "utf8");
|
|
||||||
data = JSON.parse(data);
|
|
||||||
if (data.vars) {
|
|
||||||
data.vars.forEach(function(name){
|
|
||||||
UglifyJS.push_uniq(reserved.vars, name);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (data.props) {
|
|
||||||
data.props.forEach(function(name){
|
|
||||||
UglifyJS.push_uniq(reserved.props, name);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return reserved;
|
|
||||||
}
|
|
||||||
|
|
||||||
UglifyJS.readReservedFile = readReservedFile;
|
|
||||||
|
|
||||||
UglifyJS.readDefaultReservedFile = function(reserved) {
|
|
||||||
return readReservedFile(require.resolve("./domprops.json"), reserved);
|
|
||||||
};
|
|
||||||
|
|
||||||
UglifyJS.readNameCache = function(filename, key) {
|
|
||||||
var cache = null;
|
|
||||||
if (filename) {
|
|
||||||
try {
|
|
||||||
var cache = fs.readFileSync(filename, "utf8");
|
|
||||||
cache = JSON.parse(cache)[key];
|
|
||||||
if (!cache) throw "init";
|
|
||||||
cache.props = UglifyJS.Dictionary.fromObject(cache.props);
|
|
||||||
} catch(ex) {
|
|
||||||
cache = {
|
|
||||||
cname: -1,
|
|
||||||
props: new UglifyJS.Dictionary()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cache;
|
|
||||||
};
|
|
||||||
|
|
||||||
UglifyJS.writeNameCache = function(filename, key, cache) {
|
|
||||||
if (filename) {
|
|
||||||
var data;
|
|
||||||
try {
|
|
||||||
data = fs.readFileSync(filename, "utf8");
|
|
||||||
data = JSON.parse(data);
|
|
||||||
} catch(ex) {
|
|
||||||
data = {};
|
|
||||||
}
|
|
||||||
data[key] = {
|
|
||||||
cname: cache.cname,
|
|
||||||
props: cache.props.toObject()
|
|
||||||
};
|
|
||||||
fs.writeFileSync(filename, JSON.stringify(data, null, 2), "utf8");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// A file glob function that only supports "*" and "?" wildcards in the basename.
|
|
||||||
// Example: "foo/bar/*baz??.*.js"
|
|
||||||
// Argument `glob` may be a string or an array of strings.
|
|
||||||
// Returns an array of strings. Garbage in, garbage out.
|
|
||||||
UglifyJS.simple_glob = function simple_glob(glob) {
|
|
||||||
if (Array.isArray(glob)) {
|
|
||||||
return [].concat.apply([], glob.map(simple_glob));
|
|
||||||
}
|
|
||||||
if (glob.match(/\*|\?/)) {
|
|
||||||
var dir = path.dirname(glob);
|
|
||||||
try {
|
|
||||||
var entries = fs.readdirSync(dir);
|
|
||||||
} catch (ex) {}
|
|
||||||
if (entries) {
|
|
||||||
var pattern = "^" + path.basename(glob)
|
|
||||||
.replace(/[.+^$[\]\\(){}]/g, "\\$&")
|
|
||||||
.replace(/\*/g, "[^/\\\\]*")
|
|
||||||
.replace(/\?/g, "[^/\\\\]") + "$";
|
|
||||||
var mod = process.platform === "win32" ? "i" : "";
|
|
||||||
var rx = new RegExp(pattern, mod);
|
|
||||||
var results = entries.filter(function(name) {
|
|
||||||
return rx.test(name);
|
|
||||||
}).map(function(name) {
|
|
||||||
return path.join(dir, name);
|
|
||||||
});
|
|
||||||
if (results.length) return results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [ glob ];
|
|
||||||
};
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user