123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- var path = require("path");
- var fs = require("fs");
- var vm = require("vm");
- var UglifyJS = vm.createContext({
- console : console,
- process : process,
- Buffer : Buffer,
- MOZ_SourceMap : require("source-map")
- });
- function load_global(file) {
- file = path.resolve(path.dirname(module.filename), file);
- try {
- var code = fs.readFileSync(file, "utf8");
- return vm.runInContext(code, UglifyJS, file);
- } catch(ex) {
- // XXX: in case of a syntax error, the message is kinda
- // useless. (no location information).
- console.log("ERROR in file: " + file + " / " + ex);
- process.exit(1);
- }
- };
- var FILES = exports.FILES = [
- "../lib/utils.js",
- "../lib/ast.js",
- "../lib/parse.js",
- "../lib/transform.js",
- "../lib/scope.js",
- "../lib/output.js",
- "../lib/compress.js",
- "../lib/sourcemap.js",
- "../lib/mozilla-ast.js",
- "../lib/propmangle.js"
- ].map(function(file){
- return fs.realpathSync(path.join(path.dirname(__filename), file));
- });
- FILES.forEach(load_global);
- UglifyJS.AST_Node.warn_function = function(txt) {
- console.error("WARN: %s", txt);
- };
- // XXX: perhaps we shouldn't export everything but heck, I'm lazy.
- for (var i in UglifyJS) {
- if (UglifyJS.hasOwnProperty(i)) {
- exports[i] = UglifyJS[i];
- }
- }
- exports.minify = function(files, options) {
- options = UglifyJS.defaults(options, {
- spidermonkey : false,
- outSourceMap : null,
- sourceRoot : null,
- inSourceMap : null,
- fromString : false,
- warnings : false,
- mangle : {},
- output : null,
- compress : {}
- });
- UglifyJS.base54.reset();
- // 1. parse
- var toplevel = null,
- sourcesContent = {};
- if (options.spidermonkey) {
- toplevel = UglifyJS.AST_Node.from_mozilla_ast(files);
- } else {
- if (typeof files == "string")
- files = [ files ];
- files.forEach(function(file){
- var code = options.fromString
- ? file
- : fs.readFileSync(file, "utf8");
- sourcesContent[file] = code;
- toplevel = UglifyJS.parse(code, {
- filename: options.fromString ? "?" : file,
- toplevel: toplevel
- });
- });
- }
- // 2. compress
- if (options.compress) {
- var compress = { warnings: options.warnings };
- UglifyJS.merge(compress, options.compress);
- toplevel.figure_out_scope();
- var sq = UglifyJS.Compressor(compress);
- toplevel = toplevel.transform(sq);
- }
- // 3. mangle
- if (options.mangle) {
- toplevel.figure_out_scope(options.mangle);
- toplevel.compute_char_frequency(options.mangle);
- toplevel.mangle_names(options.mangle);
- }
- // 4. output
- var inMap = options.inSourceMap;
- var output = {};
- if (typeof options.inSourceMap == "string") {
- inMap = fs.readFileSync(options.inSourceMap, "utf8");
- }
- if (options.outSourceMap) {
- output.source_map = UglifyJS.SourceMap({
- file: options.outSourceMap,
- 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);
- if(options.outSourceMap){
- stream += "\n//# sourceMappingURL=" + options.outSourceMap;
- }
- var source_map = output.source_map;
- if (source_map) {
- source_map = source_map + "";
- }
- return {
- code : stream + "",
- map : source_map
- };
- };
- // exports.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;
- // }
- exports.describe_ast = function() {
- var out = UglifyJS.OutputStream({ beautify: true });
- function doitem(ctor) {
- out.print("AST_" + ctor.TYPE);
- var props = ctor.SELF_PROPS.filter(function(prop){
- return !/^\$/.test(prop);
- });
- if (props.length > 0) {
- out.space();
- out.with_parens(function(){
- props.forEach(function(prop, i){
- if (i) out.space();
- out.print(prop);
- });
- });
- }
- if (ctor.documentation) {
- out.space();
- out.print_string(ctor.documentation);
- }
- if (ctor.SUBCLASSES.length > 0) {
- out.space();
- out.with_block(function(){
- ctor.SUBCLASSES.forEach(function(ctor, i){
- out.indent();
- doitem(ctor);
- out.newline();
- });
- });
- }
- };
- 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;
- }
- exports.readReservedFile = readReservedFile;
- exports.readDefaultReservedFile = function(reserved) {
- return readReservedFile(path.join(__dirname, "domprops.json"), reserved);
- };
- exports.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;
- };
- exports.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");
- }
- };
|