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";
|
||||
|
||||
var UglifyJS = require("../tools/node");
|
||||
var sys = require("util");
|
||||
var yargs = require("yargs");
|
||||
var fs = require("fs");
|
||||
var info = require("../package.json");
|
||||
var path = require("path");
|
||||
var acorn;
|
||||
var screw_ie8 = true;
|
||||
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.")
|
||||
var program = require("commander");
|
||||
var UglifyJS = require("../tools/node");
|
||||
|
||||
.describe("comments", "Preserve copyright comments in the output. \
|
||||
By default this works like Google Closure, keeping JSDoc-style comments that contain \"@license\" or \"@preserve\". \
|
||||
You can optionally pass one of the following arguments to this flag:\n\
|
||||
- \"all\" to keep all comments\n\
|
||||
- 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,
|
||||
var files = {};
|
||||
var options = {
|
||||
compress: false,
|
||||
mangle: false
|
||||
};
|
||||
|
||||
if (ARGS.mangle_props == 2) {
|
||||
OUTPUT_OPTIONS.keep_quoted_props = true;
|
||||
if (COMPRESS && !("properties" in COMPRESS))
|
||||
COMPRESS.properties = false;
|
||||
program._name = info.name;
|
||||
program.version(info.version);
|
||||
program.parseArgv = program.parse;
|
||||
program.parse = undefined;
|
||||
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 (ARGS.support_ie8 === true && ARGS.screw_ie8 !== true) {
|
||||
screw_ie8 = false;
|
||||
if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
||||
fatal("ERROR: cannot write source map to STDOUT");
|
||||
}
|
||||
|
||||
if (COMPRESS) COMPRESS.screw_ie8 = screw_ie8;
|
||||
if (MANGLE) MANGLE.screw_ie8 = screw_ie8;
|
||||
OUTPUT_OPTIONS.screw_ie8 = screw_ie8;
|
||||
|
||||
if (ARGS.keep_fnames) {
|
||||
if (COMPRESS) COMPRESS.keep_fnames = true;
|
||||
if (MANGLE) MANGLE.keep_fnames = true;
|
||||
[
|
||||
"compress",
|
||||
"ie8",
|
||||
"mangle",
|
||||
"sourceMap",
|
||||
"toplevel",
|
||||
"wrap"
|
||||
].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 (ARGS.wrap_iife) {
|
||||
if (COMPRESS) COMPRESS.negate_iife = false;
|
||||
OUTPUT_OPTIONS.wrap_iife = true;
|
||||
if (program.comments) {
|
||||
if (typeof options.output != "object") options.output = {};
|
||||
options.output.comments = typeof program.comments == "string" ? program.comments : "some";
|
||||
}
|
||||
|
||||
if (BEAUTIFY)
|
||||
UglifyJS.merge(OUTPUT_OPTIONS, BEAUTIFY);
|
||||
|
||||
if (ARGS.comments === "") {
|
||||
OUTPUT_OPTIONS.comments = "some";
|
||||
if (program.define) {
|
||||
if (typeof options.compress != "object") options.compress = {};
|
||||
if (typeof options.compress.global_defs != "object") options.compress.global_defs = {};
|
||||
for (var expr in program.define) {
|
||||
options.compress.global_defs[expr] = program.define[expr];
|
||||
}
|
||||
}
|
||||
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 {
|
||||
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();
|
||||
|
||||
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";
|
||||
function convert_ast(fn) {
|
||||
return UglifyJS.AST_Node.from_mozilla_ast(Object.keys(files).reduce(fn, null));
|
||||
}
|
||||
|
||||
var ORIG_MAP = ARGS.in_source_map;
|
||||
|
||||
if (ORIG_MAP && ORIG_MAP != "inline") {
|
||||
ORIG_MAP = JSON.parse(fs.readFileSync(ORIG_MAP));
|
||||
if (files.length == 0) {
|
||||
print_error("INFO: Using file from the input source map: " + ORIG_MAP.file);
|
||||
files = [ ORIG_MAP.file ];
|
||||
}
|
||||
}
|
||||
|
||||
if (files.length == 0) {
|
||||
files = [ "-" ];
|
||||
}
|
||||
|
||||
if (ORIG_MAP == "inline") {
|
||||
if (files.length > 1) {
|
||||
print_error("ERROR: Inline source map only works with singular input");
|
||||
process.exit(1);
|
||||
}
|
||||
if (ARGS.acorn || ARGS.spidermonkey) {
|
||||
print_error("ERROR: Inline source map only works with built-in parser");
|
||||
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
|
||||
function run() {
|
||||
UglifyJS.AST_Node.warn_function = function(msg) {
|
||||
console.error("WARN:", msg);
|
||||
};
|
||||
if (program.stats) program.stats = Date.now();
|
||||
try {
|
||||
if (program.parse) {
|
||||
if (program.parse.acorn) {
|
||||
files = convert_ast(function(toplevel, name) {
|
||||
return require("acorn").parse(files[name], {
|
||||
locations: true,
|
||||
program: toplevel,
|
||||
sourceFile: name
|
||||
});
|
||||
});
|
||||
} else if (program.parse.spidermonkey) {
|
||||
files = convert_ast(function(toplevel, name) {
|
||||
var obj = JSON.parse(files[name]);
|
||||
if (!toplevel) return obj;
|
||||
toplevel.body = toplevel.body.concat(obj.body);
|
||||
return toplevel;
|
||||
});
|
||||
}
|
||||
else {
|
||||
try {
|
||||
TOPLEVEL = UglifyJS.parse(code, {
|
||||
filename : file,
|
||||
toplevel : TOPLEVEL,
|
||||
expression : ARGS.expr,
|
||||
bare_returns : ARGS.bare_returns,
|
||||
});
|
||||
} catch(ex) {
|
||||
if (ex instanceof UglifyJS.JS_Parse_Error) {
|
||||
print_error("Parse error at " + file + ":" + ex.line + "," + ex.col);
|
||||
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;
|
||||
}
|
||||
var result = UglifyJS.minify(files, options);
|
||||
} catch (ex) {
|
||||
if (ex instanceof UglifyJS.JS_Parse_Error) {
|
||||
console.error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
||||
var col = ex.col;
|
||||
var line = files[ex.filename].split(/\r?\n/)[ex.line - (col ? 1 : 2)];
|
||||
if (line) {
|
||||
if (col > 40) {
|
||||
line = line.slice(col - 40);
|
||||
col = 40;
|
||||
}
|
||||
};
|
||||
});
|
||||
cb();
|
||||
});
|
||||
}();
|
||||
if (col) {
|
||||
console.error(line.slice(0, 80));
|
||||
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() {
|
||||
var OUTPUT_FILE = ARGS.o;
|
||||
function fatal(message) {
|
||||
console.error(message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var SOURCE_MAP = (ARGS.source_map || ARGS.source_map_inline) ? UglifyJS.SourceMap({
|
||||
file: P_RELATIVE ? path.relative(path.dirname(ARGS.source_map), OUTPUT_FILE) : OUTPUT_FILE,
|
||||
root: ARGS.source_map_root || ORIG_MAP && ORIG_MAP.sourceRoot,
|
||||
orig: ORIG_MAP,
|
||||
}) : null;
|
||||
|
||||
OUTPUT_OPTIONS.source_map = SOURCE_MAP;
|
||||
// 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.
|
||||
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 ];
|
||||
}
|
||||
|
||||
function readFile(path) {
|
||||
try {
|
||||
var output = UglifyJS.OutputStream(OUTPUT_OPTIONS);
|
||||
var compressor = COMPRESS && UglifyJS.Compressor(COMPRESS);
|
||||
} catch(ex) {
|
||||
if (ex instanceof UglifyJS.DefaultsError) {
|
||||
print_error(ex.message);
|
||||
print_error("Supported options:");
|
||||
print_error(sys.inspect(ex.defs));
|
||||
process.exit(1);
|
||||
}
|
||||
return fs.readFileSync(path, "utf8");
|
||||
} catch (ex) {
|
||||
fatal("ERROR: " + ex.message);
|
||||
}
|
||||
}
|
||||
|
||||
if (ARGS.acorn || ARGS.spidermonkey) time_it("convert_ast", function(){
|
||||
TOPLEVEL = UglifyJS.AST_Node.from_mozilla_ast(TOPLEVEL);
|
||||
});
|
||||
|
||||
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;
|
||||
|
||||
function parseJS(flag, constants) {
|
||||
return function(value, options) {
|
||||
options = options || {};
|
||||
try {
|
||||
regex = ARGS.mangle_regex ? extractRegex(ARGS.mangle_regex) : null;
|
||||
} catch (e) {
|
||||
print_error("ERROR: Invalid --mangle-regex: " + e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
TOPLEVEL = UglifyJS.mangle_properties(TOPLEVEL, {
|
||||
reserved : reserved,
|
||||
cache : cache,
|
||||
only_cache : !ARGS.mangle_props,
|
||||
regex : regex,
|
||||
ignore_quoted : ARGS.mangle_props == 2,
|
||||
debug : typeof ARGS.mangle_props_debug === "undefined" ? false : ARGS.mangle_props_debug
|
||||
});
|
||||
writeNameCache("props", cache);
|
||||
})();
|
||||
|
||||
var SCOPE_IS_NEEDED = COMPRESS || MANGLE || ARGS.lint
|
||||
var TL_CACHE = readNameCache("vars");
|
||||
if (MANGLE) MANGLE.cache = TL_CACHE;
|
||||
|
||||
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)
|
||||
UglifyJS.parse(value, {
|
||||
expression: true
|
||||
}).walk(new UglifyJS.TreeWalker(function(node) {
|
||||
if (node instanceof UglifyJS.AST_Assign) {
|
||||
var name = node.left.print_to_string();
|
||||
var value = node.right;
|
||||
if (!constants) {
|
||||
options[name] = value;
|
||||
} else if (value instanceof UglifyJS.AST_Constant) {
|
||||
options[name] = value.getValue();
|
||||
} else {
|
||||
options[name] = value.print_to_string();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (node instanceof UglifyJS.AST_Symbol || node instanceof UglifyJS.AST_PropAccess) {
|
||||
var name = node.print_to_string();
|
||||
options[name] = true;
|
||||
return true;
|
||||
}
|
||||
if (!(node instanceof UglifyJS.AST_Sequence)) throw node;
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -----[ 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) {
|
||||
if (ex instanceof UglifyJS.JS_Parse_Error) {
|
||||
print_error("Error parsing arguments for flag `" + flag + "': " + x);
|
||||
process.exit(1);
|
||||
}
|
||||
fatal("Error parsing arguments for '" + flag + "': " + value);
|
||||
}
|
||||
ast.walk(new UglifyJS.TreeWalker(function(node){
|
||||
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);
|
||||
return options;
|
||||
}
|
||||
}
|
||||
|
||||
function read_source_map(code) {
|
||||
var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
|
||||
if (!match) {
|
||||
print_error("WARN: inline source map not found");
|
||||
return null;
|
||||
function parseSourceMap() {
|
||||
var parse = parseJS("sourceMap", true);
|
||||
return function(value, options) {
|
||||
var hasContent = options && options.sourceMap && "content" in options.sourceMap;
|
||||
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: {
|
||||
globals: "[Object/S] a map of name -> SymbolDef for all undeclared names",
|
||||
},
|
||||
wrap_enclose: function(arg_parameter_pairs) {
|
||||
var self = this;
|
||||
var args = [];
|
||||
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(",") + ")";
|
||||
wrap_commonjs: function(name) {
|
||||
var body = this.body;
|
||||
var wrapped_tl = "(function(exports){'$ORIG';})(typeof " + name + "=='undefined'?(" + name + "={}):" + name + ");";
|
||||
wrapped_tl = parse(wrapped_tl);
|
||||
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
|
||||
if (node instanceof AST_Directive && node.value == "$ORIG") {
|
||||
return MAP.splice(self.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 MAP.splice(body);
|
||||
}
|
||||
}));
|
||||
return wrapped_tl;
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ function Compressor(options, false_by_default) {
|
|||
global_defs : {},
|
||||
hoist_funs : !false_by_default,
|
||||
hoist_vars : false,
|
||||
ie8 : false,
|
||||
if_return : !false_by_default,
|
||||
join_vars : !false_by_default,
|
||||
keep_fargs : true,
|
||||
|
|
@ -74,7 +75,6 @@ function Compressor(options, false_by_default) {
|
|||
pure_getters : !false_by_default && "strict",
|
||||
pure_funcs : null,
|
||||
reduce_vars : !false_by_default,
|
||||
screw_ie8 : true,
|
||||
sequences : !false_by_default,
|
||||
side_effects : !false_by_default,
|
||||
switches : !false_by_default,
|
||||
|
|
@ -2845,10 +2845,11 @@ merge(Compressor.prototype, {
|
|||
return arg.value;
|
||||
}).join(",") + "){" + self.args[self.args.length - 1].value + "})()";
|
||||
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);
|
||||
ast = ast.transform(comp);
|
||||
ast.figure_out_scope({ screw_ie8: compressor.option("screw_ie8") });
|
||||
ast.figure_out_scope(mangle);
|
||||
ast.mangle_names();
|
||||
var fun;
|
||||
try {
|
||||
|
|
@ -3294,7 +3295,7 @@ merge(Compressor.prototype, {
|
|||
&& self.right.operator == "typeof") {
|
||||
var expr = self.right.expression;
|
||||
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.left = make_node(AST_Undefined, self.left).optimize(compressor);
|
||||
if (self.operator.length == 2) self.operator += "=";
|
||||
|
|
@ -3618,7 +3619,7 @@ merge(Compressor.prototype, {
|
|||
return def.optimize(compressor);
|
||||
}
|
||||
// testing against !self.scope.uses_with first is an optimization
|
||||
if (compressor.option("screw_ie8")
|
||||
if (!compressor.option("ie8")
|
||||
&& self.undeclared()
|
||||
&& (!self.scope.uses_with || !compressor.find_parent(AST_With))) {
|
||||
switch (self.name) {
|
||||
|
|
@ -3938,7 +3939,7 @@ merge(Compressor.prototype, {
|
|||
var prop = self.property;
|
||||
if (prop instanceof AST_String && compressor.option("properties")) {
|
||||
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, {
|
||||
expression : self.expression,
|
||||
property : prop
|
||||
|
|
@ -3965,7 +3966,7 @@ merge(Compressor.prototype, {
|
|||
return def.optimize(compressor);
|
||||
}
|
||||
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, {
|
||||
expression : self.expression,
|
||||
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,
|
||||
bracketize : false,
|
||||
comments : false,
|
||||
ie8 : false,
|
||||
indent_level : 4,
|
||||
indent_start : 0,
|
||||
inline_script : true,
|
||||
|
|
@ -66,7 +67,6 @@ function OutputStream(options) {
|
|||
preserve_line : false,
|
||||
quote_keys : false,
|
||||
quote_style : 0,
|
||||
screw_ie8 : true,
|
||||
semicolons : true,
|
||||
shebang : true,
|
||||
source_map : null,
|
||||
|
|
@ -136,7 +136,7 @@ function OutputStream(options) {
|
|||
case "\t": return "\\t";
|
||||
case "\b": return "\\b";
|
||||
case "\f": return "\\f";
|
||||
case "\x0B": return options.screw_ie8 ? "\\v" : "\\x0B";
|
||||
case "\x0B": return options.ie8 ? "\\x0B" : "\\v";
|
||||
case "\u2028": return "\\u2028";
|
||||
case "\u2029": return "\\u2029";
|
||||
case "\ufeff": return "\\ufeff";
|
||||
|
|
@ -906,7 +906,7 @@ function OutputStream(options) {
|
|||
function make_then(self, output) {
|
||||
var b = self.body;
|
||||
if (output.option("bracketize")
|
||||
|| !output.option("screw_ie8") && b instanceof AST_Do)
|
||||
|| output.option("ie8") && b instanceof AST_Do)
|
||||
return make_block(b, output);
|
||||
// The squeezer replaces "block"-s that contain only a single
|
||||
// statement with the statement itself; technically, the AST
|
||||
|
|
@ -1222,7 +1222,7 @@ function OutputStream(options) {
|
|||
&& +key + "" == key)
|
||||
&& parseFloat(key) >= 0) {
|
||||
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")) {
|
||||
output.print_string(key, quote);
|
||||
} else {
|
||||
|
|
|
|||
11
lib/scope.js
11
lib/scope.js
|
|
@ -76,7 +76,7 @@ SymbolDef.prototype = {
|
|||
else if (!this.mangled_name && !this.unmangleable(options)) {
|
||||
var s = this.scope;
|
||||
var sym = this.orig[0];
|
||||
if (!options.screw_ie8 && sym instanceof AST_SymbolLambda)
|
||||
if (options.ie8 && sym instanceof AST_SymbolLambda)
|
||||
s = s.parent_scope;
|
||||
var def;
|
||||
if (this.defun && (def = this.defun.variables.get(this.name))) {
|
||||
|
|
@ -93,7 +93,7 @@ SymbolDef.prototype = {
|
|||
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
options = defaults(options, {
|
||||
cache: null,
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
});
|
||||
|
||||
// pass 1: setup scope chaining and handle definitions
|
||||
|
|
@ -220,7 +220,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||
self.walk(tw);
|
||||
|
||||
// pass 3: fix up any scoping issue with IE8
|
||||
if (!options.screw_ie8) {
|
||||
if (options.ie8) {
|
||||
self.walk(new TreeWalker(function(node, descend) {
|
||||
if (node instanceof AST_SymbolCatch) {
|
||||
var name = node.name;
|
||||
|
|
@ -400,9 +400,8 @@ AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
|||
return defaults(options, {
|
||||
eval : false,
|
||||
except : [],
|
||||
ie8 : false,
|
||||
keep_fnames : false,
|
||||
screw_ie8 : true,
|
||||
sort : false, // Ignored. Flag retained for backwards compatibility.
|
||||
toplevel : false,
|
||||
});
|
||||
});
|
||||
|
|
@ -452,7 +451,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||
node.mangled_name = name;
|
||||
return true;
|
||||
}
|
||||
if (options.screw_ie8 && node instanceof AST_SymbolCatch) {
|
||||
if (!options.ie8 && node instanceof AST_SymbolCatch) {
|
||||
to_mangle.push(node.definition());
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@
|
|||
"LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"source-map": "~0.5.1",
|
||||
"yargs": "~3.10.0"
|
||||
"commander": "~2.9.0",
|
||||
"source-map": "~0.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"acorn": "~0.6.0",
|
||||
|
|
|
|||
|
|
@ -29,11 +29,11 @@ function done() {
|
|||
var info = results[url];
|
||||
console.log();
|
||||
console.log(url);
|
||||
console.log(info.log);
|
||||
var elapsed = 0;
|
||||
info.log.replace(/: ([0-9]+\.[0-9]{3})s/g, function(match, time) {
|
||||
elapsed += parseFloat(time);
|
||||
});
|
||||
console.log(info.log.replace(/Elapsed: ([0-9]+)\s*/g, function(match, time) {
|
||||
elapsed += 1e-3 * parseInt(time);
|
||||
return "";
|
||||
}));
|
||||
console.log("Run-time:", elapsed.toFixed(3), "s");
|
||||
console.log("Original:", info.input, "bytes");
|
||||
console.log("Uglified:", info.output, "bytes");
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ ascii_only_true: {
|
|||
options = {}
|
||||
beautify = {
|
||||
ascii_only : true,
|
||||
screw_ie8 : true,
|
||||
ie8 : false,
|
||||
beautify : false,
|
||||
}
|
||||
input: {
|
||||
|
|
@ -20,7 +20,7 @@ ascii_only_false: {
|
|||
options = {}
|
||||
beautify = {
|
||||
ascii_only : false,
|
||||
screw_ie8 : true,
|
||||
ie8 : false,
|
||||
beautify : false,
|
||||
}
|
||||
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\'}'
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ typeof_eq_undefined: {
|
|||
typeof_eq_undefined_ie8: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
screw_ie8: false
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
var a = typeof b != "undefined";
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
screw_ie8: {
|
||||
options = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
try { throw "foo"; } catch (x) { console.log(x); }
|
||||
|
|
@ -16,10 +16,10 @@ screw_ie8: {
|
|||
|
||||
support_ie8: {
|
||||
options = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
try { throw "foo"; } catch (x) { console.log(x); }
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
mangle_catch: {
|
||||
options = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
|
|
@ -22,11 +22,11 @@ mangle_catch: {
|
|||
|
||||
mangle_catch_ie8: {
|
||||
options = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
|
|
@ -44,11 +44,11 @@ mangle_catch_ie8: {
|
|||
|
||||
mangle_catch_var: {
|
||||
options = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
|
|
@ -66,11 +66,11 @@ mangle_catch_var: {
|
|||
|
||||
mangle_catch_var_ie8: {
|
||||
options = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
|
|
@ -88,11 +88,11 @@ mangle_catch_var_ie8: {
|
|||
|
||||
mangle_catch_toplevel: {
|
||||
options = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
|
|
@ -110,11 +110,11 @@ mangle_catch_toplevel: {
|
|||
|
||||
mangle_catch_ie8_toplevel: {
|
||||
options = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
|
|
@ -132,11 +132,11 @@ mangle_catch_ie8_toplevel: {
|
|||
|
||||
mangle_catch_var_toplevel: {
|
||||
options = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
|
|
@ -154,11 +154,11 @@ mangle_catch_var_toplevel: {
|
|||
|
||||
mangle_catch_var_ie8_toplevel: {
|
||||
options = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
|
|
@ -176,11 +176,11 @@ mangle_catch_var_ie8_toplevel: {
|
|||
|
||||
mangle_catch_redef_1: {
|
||||
options = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
|
|
@ -198,11 +198,11 @@ mangle_catch_redef_1: {
|
|||
|
||||
mangle_catch_redef_1_ie8: {
|
||||
options = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
|
|
@ -220,11 +220,11 @@ mangle_catch_redef_1_ie8: {
|
|||
|
||||
mangle_catch_redef_1_toplevel: {
|
||||
options = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
|
|
@ -242,11 +242,11 @@ mangle_catch_redef_1_toplevel: {
|
|||
|
||||
mangle_catch_redef_1_ie8_toplevel: {
|
||||
options = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
|
|
@ -264,11 +264,11 @@ mangle_catch_redef_1_ie8_toplevel: {
|
|||
|
||||
mangle_catch_redef_2: {
|
||||
options = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
|
|
@ -285,11 +285,11 @@ mangle_catch_redef_2: {
|
|||
|
||||
mangle_catch_redef_2_ie8: {
|
||||
options = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
|
|
@ -306,11 +306,11 @@ mangle_catch_redef_2_ie8: {
|
|||
|
||||
mangle_catch_redef_2_toplevel: {
|
||||
options = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
|
|
@ -327,11 +327,11 @@ mangle_catch_redef_2_toplevel: {
|
|||
|
||||
mangle_catch_redef_2_ie8_toplevel: {
|
||||
options = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
function_iife_catch: {
|
||||
mangle = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
function f(n) {
|
||||
|
|
@ -21,7 +21,7 @@ function_iife_catch: {
|
|||
|
||||
function_iife_catch_ie8: {
|
||||
mangle = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
function f(n) {
|
||||
|
|
@ -42,7 +42,7 @@ function_iife_catch_ie8: {
|
|||
|
||||
function_catch_catch: {
|
||||
mangle = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
var o = 0;
|
||||
|
|
@ -70,7 +70,7 @@ function_catch_catch: {
|
|||
|
||||
function_catch_catch_ie8: {
|
||||
mangle = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
var o = 0;
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ issue_1532: {
|
|||
issue_186: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
|
|
@ -264,7 +264,7 @@ issue_186: {
|
|||
issue_186_ie8: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
|
|
@ -283,7 +283,7 @@ issue_186_ie8: {
|
|||
issue_186_beautify: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
|
|
@ -310,7 +310,7 @@ issue_186_beautify: {
|
|||
issue_186_beautify_ie8: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
|
|
@ -340,7 +340,7 @@ issue_186_bracketize: {
|
|||
beautify = {
|
||||
beautify: false,
|
||||
bracketize: true,
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
|
|
@ -360,7 +360,7 @@ issue_186_bracketize_ie8: {
|
|||
beautify = {
|
||||
beautify: false,
|
||||
bracketize: true,
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
|
|
@ -380,7 +380,7 @@ issue_186_beautify_bracketize: {
|
|||
beautify = {
|
||||
beautify: true,
|
||||
bracketize: true,
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
|
|
@ -412,7 +412,7 @@ issue_186_beautify_bracketize_ie8: {
|
|||
beautify = {
|
||||
beautify: true,
|
||||
bracketize: true,
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
var x = 3;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ keep_properties: {
|
|||
dot_properties: {
|
||||
options = {
|
||||
properties: true,
|
||||
screw_ie8: false
|
||||
ie8: true,
|
||||
};
|
||||
input: {
|
||||
a["foo"] = "bar";
|
||||
|
|
@ -36,7 +36,7 @@ dot_properties: {
|
|||
dot_properties_es5: {
|
||||
options = {
|
||||
properties: true,
|
||||
screw_ie8: true
|
||||
ie8: false,
|
||||
};
|
||||
input: {
|
||||
a["foo"] = "bar";
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
do_screw: {
|
||||
options = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
}
|
||||
beautify = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
ascii_only: true,
|
||||
}
|
||||
input: {
|
||||
|
|
@ -14,10 +14,10 @@ do_screw: {
|
|||
|
||||
dont_screw: {
|
||||
options = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
}
|
||||
beautify = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
ascii_only: true,
|
||||
}
|
||||
input: {
|
||||
|
|
@ -28,7 +28,7 @@ dont_screw: {
|
|||
|
||||
do_screw_constants: {
|
||||
options = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
f(undefined, Infinity);
|
||||
|
|
@ -38,7 +38,7 @@ do_screw_constants: {
|
|||
|
||||
dont_screw_constants: {
|
||||
options = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
f(undefined, Infinity);
|
||||
|
|
@ -47,9 +47,15 @@ dont_screw_constants: {
|
|||
}
|
||||
|
||||
do_screw_try_catch: {
|
||||
options = { screw_ie8: true };
|
||||
mangle = { screw_ie8: true };
|
||||
beautify = { screw_ie8: true };
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
beautify = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
good = function(e){
|
||||
return function(error){
|
||||
|
|
@ -75,9 +81,15 @@ do_screw_try_catch: {
|
|||
}
|
||||
|
||||
dont_screw_try_catch: {
|
||||
options = { screw_ie8: false };
|
||||
mangle = { screw_ie8: false };
|
||||
beautify = { screw_ie8: false };
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
beautify = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
bad = function(e){
|
||||
return function(error){
|
||||
|
|
@ -103,9 +115,15 @@ dont_screw_try_catch: {
|
|||
}
|
||||
|
||||
do_screw_try_catch_undefined: {
|
||||
options = { screw_ie8: true };
|
||||
mangle = { screw_ie8: true };
|
||||
beautify = { screw_ie8: true };
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
beautify = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
function a(b){
|
||||
try {
|
||||
|
|
@ -132,9 +150,15 @@ do_screw_try_catch_undefined: {
|
|||
}
|
||||
|
||||
dont_screw_try_catch_undefined: {
|
||||
options = { screw_ie8: false };
|
||||
mangle = { screw_ie8: false };
|
||||
beautify = { screw_ie8: false };
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
beautify = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
function a(b){
|
||||
try {
|
||||
|
|
@ -164,11 +188,11 @@ reduce_vars: {
|
|||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
|
|
@ -196,10 +220,10 @@ reduce_vars: {
|
|||
|
||||
issue_1586_1: {
|
||||
options = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: false,
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
|
|
@ -215,10 +239,10 @@ issue_1586_1: {
|
|||
|
||||
issue_1586_2: {
|
||||
options = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
screw_ie8: true,
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ describe("bin/uglifyjs", function () {
|
|||
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';
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
|
|
@ -50,8 +50,8 @@ describe("bin/uglifyjs", function () {
|
|||
done();
|
||||
});
|
||||
});
|
||||
it("Should append source map to output when using --source-map-inline", function (done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-1323/sample.js --source-map-inline';
|
||||
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 url=inline";
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
|
@ -61,7 +61,7 @@ describe("bin/uglifyjs", function () {
|
|||
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';
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
|
|
@ -152,7 +152,7 @@ describe("bin/uglifyjs", function () {
|
|||
});
|
||||
});
|
||||
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) {
|
||||
if (err) throw err;
|
||||
|
|
@ -162,40 +162,44 @@ describe("bin/uglifyjs", function () {
|
|||
});
|
||||
});
|
||||
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) {
|
||||
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");
|
||||
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) {
|
||||
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();
|
||||
});
|
||||
});
|
||||
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) {
|
||||
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();
|
||||
});
|
||||
});
|
||||
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) {
|
||||
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();
|
||||
});
|
||||
});
|
||||
|
|
@ -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[1], "function f(a{}");
|
||||
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();
|
||||
});
|
||||
});
|
||||
|
|
@ -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[1], "\t\tfoo(\txyz, 0abc);");
|
||||
assert.strictEqual(lines[2], "\t\t \t ^");
|
||||
assert.strictEqual(lines[3], "SyntaxError: Invalid syntax: 0abc");
|
||||
assert.strictEqual(lines[3], "ERROR: Invalid syntax: 0abc");
|
||||
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[1], "foo, bar(");
|
||||
assert.strictEqual(lines[2], " ^");
|
||||
assert.strictEqual(lines[3], "SyntaxError: Unexpected token: eof (undefined)");
|
||||
assert.strictEqual(lines[3], "ERROR: Unexpected token: eof (undefined)");
|
||||
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[1], "for (var i = 0; i < 1; i++) ");
|
||||
assert.strictEqual(lines[2], " ^");
|
||||
assert.strictEqual(lines[3], "SyntaxError: Unexpected token: eof (undefined)");
|
||||
assert.strictEqual(lines[3], "ERROR: Unexpected token: eof (undefined)");
|
||||
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) {
|
||||
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",
|
||||
"console.log(1 || 5--);",
|
||||
" ^",
|
||||
"SyntaxError: Invalid use of -- operator"
|
||||
"ERROR: Invalid use of -- operator"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
|
|
@ -286,7 +280,7 @@ describe("bin/uglifyjs", function () {
|
|||
"Parse error at test/input/invalid/assign_2.js:1,32",
|
||||
"console.log(2 || (Math.random() /= 2));",
|
||||
" ^",
|
||||
"SyntaxError: Invalid assignment"
|
||||
"ERROR: Invalid assignment"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
|
|
@ -301,7 +295,7 @@ describe("bin/uglifyjs", function () {
|
|||
"Parse error at test/input/invalid/assign_3.js:1,18",
|
||||
"console.log(3 || ++this);",
|
||||
" ^",
|
||||
"SyntaxError: Invalid use of ++ operator"
|
||||
"ERROR: Invalid use of ++ operator"
|
||||
].join("\n"));
|
||||
done();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -75,7 +75,6 @@ describe("comment filters", function() {
|
|||
|
||||
it("Should handle shebang and preamble correctly", function() {
|
||||
var code = UglifyJS.minify("#!/usr/bin/node\nvar x = 10;", {
|
||||
fromString: true,
|
||||
output: { preamble: "/* Build */" }
|
||||
}).code;
|
||||
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() {
|
||||
var code = UglifyJS.minify("var x = 10;", {
|
||||
fromString: true,
|
||||
output: { preamble: "/* Build */" }
|
||||
}).code;
|
||||
assert.strictEqual(code, "/* Build */\nvar x=10;");
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ describe("Comment", function() {
|
|||
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
assert.throws(function() {
|
||||
uglify.parse(tests[i], {fromString: true})
|
||||
uglify.parse(tests[i]);
|
||||
}, fail, tests[i]);
|
||||
}
|
||||
});
|
||||
|
|
@ -43,7 +43,7 @@ describe("Comment", function() {
|
|||
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
assert.throws(function() {
|
||||
uglify.parse(tests[i], {fromString: true})
|
||||
uglify.parse(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() {
|
||||
var result = Uglify.minify(js, {
|
||||
fromString: true,
|
||||
compress: { collapse_vars: false, reduce_vars: false },
|
||||
mangle: {},
|
||||
output: { comments: true },
|
||||
});
|
||||
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() {
|
||||
var result = Uglify.minify(js, {
|
||||
fromString: true,
|
||||
compress: { collapse_vars: false, reduce_vars: false },
|
||||
mangle: {},
|
||||
output: { comments: false },
|
||||
});
|
||||
assert.strictEqual(result.code, 'function f(){var n=!1;return n}');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ describe("Directives", function() {
|
|||
assert.strictEqual(
|
||||
uglify.minify(
|
||||
'"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,
|
||||
'"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++) {
|
||||
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][0]
|
||||
);
|
||||
|
|
@ -234,7 +234,7 @@ describe("Directives", function() {
|
|||
|
||||
it("Should add double semicolon when relying on automatic semicolon insertion", function() {
|
||||
var code = uglify.minify('"use strict";"use\\x20strict";',
|
||||
{fromString: true, output: {semicolons: false}, compress: false}
|
||||
{output: {semicolons: false}, compress: false}
|
||||
).code;
|
||||
assert.strictEqual(code, '"use strict";;"use strict"\n');
|
||||
});
|
||||
|
|
@ -340,7 +340,7 @@ describe("Directives", function() {
|
|||
];
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
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][0] + " using mode " + tests[i][1]
|
||||
);
|
||||
|
|
@ -362,7 +362,7 @@ describe("Directives", function() {
|
|||
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
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][0]
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,58 +1,80 @@
|
|||
var Uglify = require('../../');
|
||||
var assert = require("assert");
|
||||
var exec = require("child_process").exec;
|
||||
var path = require("path");
|
||||
var readFileSync = require("fs").readFileSync;
|
||||
|
||||
describe("minify() with input file globs", function() {
|
||||
it("minify() with one input file glob string.", function() {
|
||||
var result = Uglify.minify("test/input/issue-1242/foo.*");
|
||||
assert.strictEqual(result.code, 'function foo(o){print("Foo:",2*o)}var print=console.log.bind(console);');
|
||||
});
|
||||
it("minify() with an array of one input file glob.", function() {
|
||||
var result = Uglify.minify([
|
||||
"test/input/issue-1242/b*.es5",
|
||||
]);
|
||||
assert.strictEqual(result.code, 'function bar(n){return 3*n}function baz(n){return n/2}');
|
||||
});
|
||||
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 }
|
||||
describe("bin/uglifyjs with input file globs", function() {
|
||||
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||
it("bin/uglifyjs with one input file extension glob.", function(done) {
|
||||
var command = uglifyjscmd + ' "test/input/issue-1242/foo.*" -cm';
|
||||
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, 'function foo(o){print("Foo:",2*o)}var print=console.log.bind(console);\n');
|
||||
done();
|
||||
});
|
||||
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() {
|
||||
var glob = "test/input/issue-1242/blah.*";
|
||||
assert.strictEqual(Uglify.simple_glob(glob).length, 1);
|
||||
assert.strictEqual(Uglify.simple_glob(glob)[0], glob);
|
||||
assert.throws(function() {
|
||||
Uglify.minify(glob);
|
||||
}, "should throw file not found");
|
||||
it("bin/uglifyjs with one input file name glob.", function(done) {
|
||||
var command = uglifyjscmd + ' "test/input/issue-1242/b*.es5" -cm';
|
||||
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
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() {
|
||||
var glob = "test/input?issue-1242/foo.*";
|
||||
assert.strictEqual(Uglify.simple_glob(glob).length, 1);
|
||||
assert.strictEqual(Uglify.simple_glob(glob)[0], glob);
|
||||
assert.throws(function() {
|
||||
Uglify.minify(glob);
|
||||
}, "should throw file not found");
|
||||
it("bin/uglifyjs with multiple input file globs.", function(done) {
|
||||
var command = uglifyjscmd + ' "test/input/issue-1242/???.es5" "test/input/issue-1242/*.js" -mc toplevel';
|
||||
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
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() {
|
||||
var result = Uglify.minify("test/input/issue-1632/^{*}[???](*)+$.??");
|
||||
assert.strictEqual(result.code, "console.log(x);");
|
||||
it("should throw with non-matching glob string", function(done) {
|
||||
var command = uglifyjscmd + ' "test/input/issue-1242/blah.*"';
|
||||
|
||||
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 matches = Uglify.simple_glob([
|
||||
var command = uglifyjscmd + ' "' + [
|
||||
path.join(dir, "b*.es5"),
|
||||
path.join(dir, "z*.es5"),
|
||||
path.join(dir, "*.js"),
|
||||
]);
|
||||
assert.strictEqual(matches.length, 4);
|
||||
assert.strictEqual(matches[0], path.join(dir, "bar.es5"));
|
||||
assert.strictEqual(matches[1], path.join(dir, "baz.es5"));
|
||||
assert.strictEqual(matches[2], path.join(dir, "z*.es5"));
|
||||
assert.strictEqual(matches[3], path.join(dir, "qux.js"));
|
||||
path.join(dir, "*.js")
|
||||
].join('" "') + '"';
|
||||
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.ok(/^ERROR: ENOENT.*?z\*\.es5/.test(stderr));
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,12 +8,7 @@ describe("Huge number of comments.", function() {
|
|||
for (i = 1; i <= 5000; ++i) { js += "// " + i + "\n"; }
|
||||
for (; i <= 10000; ++i) { js += "/* " + i + " */ /**/"; }
|
||||
js += "x; }";
|
||||
var result = Uglify.minify(js, {
|
||||
fromString: true,
|
||||
mangle: false,
|
||||
compress: {}
|
||||
});
|
||||
var result = Uglify.minify(js, { mangle: false });
|
||||
assert.strictEqual(result.code, "function lots_of_comments(x){return 7-x}");
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@ describe("input sourcemaps", function() {
|
|||
transpilemap = sourceMap || getMap();
|
||||
|
||||
var result = Uglify.minify(transpiled, {
|
||||
fromString: true,
|
||||
inSourceMap: transpilemap,
|
||||
outSourceMap: true
|
||||
sourceMap: {
|
||||
content: transpilemap
|
||||
}
|
||||
});
|
||||
|
||||
map = new SourceMapConsumer(result.map);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ describe("let", function() {
|
|||
s += "var v" + i + "=0;";
|
||||
}
|
||||
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
|
||||
assert.strictEqual(result.code.indexOf("var let="), -1);
|
||||
|
|
|
|||
|
|
@ -3,9 +3,8 @@ var assert = require("assert");
|
|||
|
||||
describe("line-endings", function() {
|
||||
var options = {
|
||||
fromString: true,
|
||||
mangle: false,
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
beautify: false,
|
||||
comments: /^!/,
|
||||
|
|
|
|||
|
|
@ -6,43 +6,41 @@ describe("Input file as map", function() {
|
|||
var jsMap = {
|
||||
'/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);
|
||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3};');
|
||||
assert.deepEqual(map.sources, ['/scripts/foo.js']);
|
||||
assert.strictEqual(map.file, undefined);
|
||||
|
||||
result = Uglify.minify(jsMap, {fromString: true, outFileName: 'out.js'});
|
||||
assert.strictEqual(result.map, null);
|
||||
result = Uglify.minify(jsMap);
|
||||
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);
|
||||
assert.strictEqual(map.file, 'out.js');
|
||||
});
|
||||
|
||||
it("Should accept array of objects and strings", function() {
|
||||
it("Should accept array of strings", function() {
|
||||
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 result = Uglify.minify(jsSeq, {fromString: true, outSourceMap: true});
|
||||
var result = Uglify.minify(jsSeq, {sourceMap: true});
|
||||
|
||||
var map = JSON.parse(result.map);
|
||||
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() {
|
||||
var jsSeq = [
|
||||
{'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'},
|
||||
'var bar = 15;'
|
||||
];
|
||||
var result = Uglify.minify(jsSeq, {fromString: true, outSourceMap: true, sourceMapIncludeSources: true});
|
||||
var jsMap = {
|
||||
'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'
|
||||
};
|
||||
var result = Uglify.minify(jsMap, {sourceMap: {includeSources: true}});
|
||||
|
||||
var map = JSON.parse(result.map);
|
||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3},bar=15;');
|
||||
assert.deepEqual(map.sourcesContent, ['var foo = {"x": 1, y: 2, \'z\': 3};', 'var 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};']);
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,10 +2,14 @@ var Uglify = require('../../');
|
|||
var assert = require("assert");
|
||||
var readFileSync = require("fs").readFileSync;
|
||||
|
||||
function read(path) {
|
||||
return readFileSync(path, "utf8");
|
||||
}
|
||||
|
||||
describe("minify", 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 result = Uglify.minify(js, {fromString: true});
|
||||
var result = Uglify.minify(js);
|
||||
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() {
|
||||
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
||||
var result = Uglify.minify(js, {
|
||||
fromString: true, output: {
|
||||
output: {
|
||||
keep_quoted_props: true
|
||||
}});
|
||||
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() {
|
||||
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
||||
var result = Uglify.minify(js, {
|
||||
fromString: true, output: {
|
||||
output: {
|
||||
keep_quoted_props: true,
|
||||
quote_style: 3
|
||||
}});
|
||||
|
|
@ -32,7 +36,7 @@ describe("minify", function() {
|
|||
it("Should not preserve quotes in object literals when disabled", function() {
|
||||
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
||||
var result = Uglify.minify(js, {
|
||||
fromString: true, output: {
|
||||
output: {
|
||||
keep_quoted_props: false,
|
||||
quote_style: 3
|
||||
}});
|
||||
|
|
@ -44,12 +48,13 @@ describe("minify", function() {
|
|||
it("Shouldn't mangle quoted properties", function() {
|
||||
var js = 'a["foo"] = "bar"; a.color = "red"; x = {"bar": 10};';
|
||||
var result = Uglify.minify(js, {
|
||||
fromString: true,
|
||||
compress: {
|
||||
properties: false
|
||||
},
|
||||
mangleProperties: {
|
||||
ignore_quoted: true
|
||||
mangle: {
|
||||
properties: {
|
||||
ignore_quoted: true
|
||||
}
|
||||
},
|
||||
output: {
|
||||
keep_quoted_props: true,
|
||||
|
|
@ -63,10 +68,12 @@ describe("minify", function() {
|
|||
|
||||
describe("inSourceMap", 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', {
|
||||
outSourceMap: "simple.min.js.map",
|
||||
inSourceMap: "./test/input/issue-1236/simple.js.map",
|
||||
sourceMapIncludeSources: true
|
||||
var result = Uglify.minify(read("./test/input/issue-1236/simple.js"), {
|
||||
sourceMap: {
|
||||
content: read("./test/input/issue-1236/simple.js.map"),
|
||||
filename: "simple.min.js",
|
||||
includeSources: true
|
||||
}
|
||||
});
|
||||
|
||||
var map = JSON.parse(result.map);
|
||||
|
|
@ -77,10 +84,12 @@ describe("minify", function() {
|
|||
'let foo = x => "foo " + x;\nconsole.log(foo("bar"));');
|
||||
});
|
||||
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 },
|
||||
inSourceMap: "inline",
|
||||
sourceMapInline: true
|
||||
sourceMap: {
|
||||
content: "inline",
|
||||
url: "inline"
|
||||
}
|
||||
}).code + "\n";
|
||||
assert.strictEqual(code, readFileSync("test/input/issue-520/output.js", "utf8"));
|
||||
});
|
||||
|
|
@ -91,9 +100,11 @@ describe("minify", function() {
|
|||
warnings.push(txt);
|
||||
};
|
||||
try {
|
||||
var result = Uglify.minify("./test/input/issue-1323/sample.js", {
|
||||
inSourceMap: "inline",
|
||||
var result = Uglify.minify(read("./test/input/issue-1323/sample.js"), {
|
||||
mangle: false,
|
||||
sourceMap: {
|
||||
content: "inline"
|
||||
}
|
||||
});
|
||||
assert.strictEqual(result.code, "var bar=function(){function foo(bar){return bar}return foo}();");
|
||||
assert.strictEqual(warnings.length, 1);
|
||||
|
|
@ -105,20 +116,13 @@ describe("minify", function() {
|
|||
it("Should fail with multiple input and inline source map", function() {
|
||||
assert.throws(function() {
|
||||
Uglify.minify([
|
||||
"./test/input/issue-520/input.js",
|
||||
"./test/input/issue-520/output.js"
|
||||
read("./test/input/issue-520/input.js"),
|
||||
read("./test/input/issue-520/output.js")
|
||||
], {
|
||||
inSourceMap: "inline",
|
||||
sourceMapInline: true
|
||||
});
|
||||
});
|
||||
});
|
||||
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
|
||||
sourceMap: {
|
||||
content: "inline",
|
||||
url: "inline"
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -127,17 +131,16 @@ describe("minify", function() {
|
|||
describe("sourceMapInline", function() {
|
||||
it("should append source map to output js when sourceMapInline is enabled", function() {
|
||||
var result = Uglify.minify('var a = function(foo) { return foo; };', {
|
||||
fromString: true,
|
||||
sourceMapInline: true
|
||||
sourceMap: {
|
||||
url: "inline"
|
||||
}
|
||||
});
|
||||
var code = result.code;
|
||||
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() {
|
||||
var result = Uglify.minify('var a = function(foo) { return foo; };', {
|
||||
fromString: true
|
||||
});
|
||||
var result = Uglify.minify('var a = function(foo) { return foo; };');
|
||||
var code = result.code;
|
||||
assert.strictEqual(code, "var a=function(n){return n};");
|
||||
});
|
||||
|
|
@ -146,7 +149,6 @@ describe("minify", function() {
|
|||
describe("#__PURE__", function() {
|
||||
it("should drop #__PURE__ hint after use", function() {
|
||||
var result = Uglify.minify('//@__PURE__ comment1 #__PURE__ comment2\n foo(), bar();', {
|
||||
fromString: true,
|
||||
output: {
|
||||
comments: "all",
|
||||
beautify: false,
|
||||
|
|
@ -157,7 +159,6 @@ describe("minify", function() {
|
|||
});
|
||||
it("should not drop #__PURE__ hint if function is retained", function() {
|
||||
var result = Uglify.minify("var a = /*#__PURE__*/(function(){ foo(); })();", {
|
||||
fromString: true,
|
||||
output: {
|
||||
comments: "all",
|
||||
beautify: false,
|
||||
|
|
@ -171,11 +172,11 @@ describe("minify", function() {
|
|||
describe("JS_Parse_Error", function() {
|
||||
it("should throw syntax error", function() {
|
||||
assert.throws(function() {
|
||||
Uglify.minify("function f(a{}", { fromString: true });
|
||||
Uglify.minify("function f(a{}");
|
||||
}, function(err) {
|
||||
assert.ok(err instanceof Error);
|
||||
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.col, 12);
|
||||
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)}");
|
||||
});
|
||||
})
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ describe("New", function() {
|
|||
for (var i = 0; i < tests.length; i++) {
|
||||
assert.strictEqual(
|
||||
uglify.minify(tests[i], {
|
||||
fromString: true,
|
||||
output: {beautify: true},
|
||||
compress: false,
|
||||
mangle: false
|
||||
|
|
@ -76,7 +75,6 @@ describe("New", function() {
|
|||
for (var i = 0; i < tests.length; i++) {
|
||||
assert.strictEqual(
|
||||
uglify.minify(tests[i], {
|
||||
fromString: true,
|
||||
output: {beautify: false},
|
||||
compress: false,
|
||||
mangle: false
|
||||
|
|
|
|||
|
|
@ -13,9 +13,7 @@ describe("screw-ie8", function () {
|
|||
}\
|
||||
console.log('undefined is ' + undefined);\
|
||||
return b === undefined;\
|
||||
};", {
|
||||
fromString: true
|
||||
}
|
||||
};"
|
||||
).code,
|
||||
'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);
|
||||
|
||||
var uglifyjs = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||
var command = uglifyjs + " --self -cm --wrap SpiderUglify --dump-spidermonkey-ast | " +
|
||||
uglifyjs + " --spidermonkey -cm";
|
||||
var command = uglifyjs + " --self -cm --wrap SpiderUglify -o spidermonkey | " +
|
||||
uglifyjs + " -p spidermonkey -cm";
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
|
|
|||
|
|
@ -768,7 +768,6 @@ function createVarName(maybe, dontStore) {
|
|||
function try_beautify(code, result) {
|
||||
try {
|
||||
var beautified = UglifyJS.minify(code, {
|
||||
fromString: true,
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
|
|
@ -802,8 +801,8 @@ var default_options = {
|
|||
mangle: {
|
||||
"cache": null,
|
||||
"eval": false,
|
||||
"ie8": false,
|
||||
"keep_fnames": false,
|
||||
"screw_ie8": true,
|
||||
"toplevel": false,
|
||||
},
|
||||
output: infer_options(UglifyJS.OutputStream),
|
||||
|
|
@ -869,10 +868,7 @@ function log(options) {
|
|||
}
|
||||
}
|
||||
|
||||
var minify_options = require("./ufuzz.json").map(function(options) {
|
||||
options.fromString = true;
|
||||
return JSON.stringify(options);
|
||||
});
|
||||
var minify_options = require("./ufuzz.json").map(JSON.stringify);
|
||||
var original_code, original_result;
|
||||
var uglify_code, uglify_result, ok;
|
||||
for (var round = 1; round <= num_iterations; round++) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ exports["base54"] = base54;
|
|||
exports["defaults"] = defaults;
|
||||
exports["mangle_properties"] = mangle_properties;
|
||||
exports["merge"] = merge;
|
||||
exports["minify"] = minify;
|
||||
exports["parse"] = parse;
|
||||
exports["push_uniq"] = push_uniq;
|
||||
exports["string_template"] = string_template;
|
||||
|
|
|
|||
255
tools/node.js
255
tools/node.js
|
|
@ -4,7 +4,6 @@
|
|||
stream._handle.setBlocking(true);
|
||||
});
|
||||
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
|
||||
var UglifyJS = exports;
|
||||
|
|
@ -19,6 +18,7 @@ var FILES = UglifyJS.FILES = [
|
|||
"../lib/sourcemap.js",
|
||||
"../lib/mozilla-ast.js",
|
||||
"../lib/propmangle.js",
|
||||
"../lib/minify.js",
|
||||
"./exports.js",
|
||||
].map(function(file){
|
||||
return require.resolve(file);
|
||||
|
|
@ -31,168 +31,6 @@ new Function("MOZ_SourceMap", "exports", FILES.map(function(file){
|
|||
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() {
|
||||
var out = UglifyJS.OutputStream({ beautify: true });
|
||||
function doitem(ctor) {
|
||||
|
|
@ -227,94 +65,3 @@ UglifyJS.describe_ast = function() {
|
|||
doitem(UglifyJS.AST_Node);
|
||||
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