From 51b587292f2ba85d68939d9c59cf7fa745a6173e Mon Sep 17 00:00:00 2001 From: Tanguy Krotoff Date: Wed, 6 Jan 2016 16:35:43 +0100 Subject: [PATCH] Add definitions for UglifyJS 2 (https://github.com/mishoo/UglifyJS2) --- uglify-js/uglify-js-tests.ts | 73 ++++++ uglify-js/uglify-js.d.ts | 430 +++++++++++++++++++++++++++++++++++ 2 files changed, 503 insertions(+) create mode 100644 uglify-js/uglify-js-tests.ts create mode 100644 uglify-js/uglify-js.d.ts diff --git a/uglify-js/uglify-js-tests.ts b/uglify-js/uglify-js-tests.ts new file mode 100644 index 000000000..23b935dec --- /dev/null +++ b/uglify-js/uglify-js-tests.ts @@ -0,0 +1,73 @@ +/// +/// + +import * as UglifyJS from 'uglify-js'; +import * as fs from 'fs'; + +var result = UglifyJS.minify("/path/to/file.js"); +console.log(result.code); // minified output +// if you need to pass code instead of file name +var result = UglifyJS.minify("var b = function () {};", {fromString: true}); + +var result = UglifyJS.minify([ "file1.js", "file2.js", "file3.js" ]); +console.log(result.code); + +var result = UglifyJS.minify([ "file1.js", "file2.js", "file3.js" ], { + outSourceMap: "out.js.map" +}); +console.log(result.code); // minified output +console.log(result.map); + +var result = UglifyJS.minify([ "file1.js", "file2.js", "file3.js" ], { + outSourceMap: "out.js.map", + sourceRoot: "http://example.com/src" +}); + +var result = UglifyJS.minify("compiled.js", { + inSourceMap: "compiled.js.map", + outSourceMap: "minified.js.map" +}); +// same as before, it returns `code` and `map` + +const my_source_map_string = 'sourceMap'; +var result = UglifyJS.minify("compiled.js", { + inSourceMap: JSON.parse(my_source_map_string), + outSourceMap: "minified.js.map" +}); + +var toplevel_ast = UglifyJS.parse(code, {}); + +var toplevel: UglifyJS.AST_Toplevel = null; +const files = ['file1', 'file2']; +files.forEach(function(file){ + var code = fs.readFileSync(file, "utf8"); + toplevel = UglifyJS.parse(code, { + filename: file, + toplevel: toplevel + }); +}); + +toplevel.figure_out_scope() + +var compressor = UglifyJS.Compressor({}); +var compressed_ast = toplevel.transform(compressor); + +compressed_ast.figure_out_scope(); +compressed_ast.compute_char_frequency(); +compressed_ast.mangle_names(); + +var stream = UglifyJS.OutputStream({}); +compressed_ast.print(stream); +var code = stream.toString(); // this is your minified code + +var code = compressed_ast.print_to_string({}); + +var source_map = UglifyJS.SourceMap({}); +var stream = UglifyJS.OutputStream({ + //... + source_map: source_map +}); +compressed_ast.print(stream); + +var code = stream.toString(); +var map = source_map.toString(); // json output for your source map diff --git a/uglify-js/uglify-js.d.ts b/uglify-js/uglify-js.d.ts new file mode 100644 index 000000000..b9c22bc6e --- /dev/null +++ b/uglify-js/uglify-js.d.ts @@ -0,0 +1,430 @@ +// Type definitions for UglifyJS 2 v2.6.1 +// Project: https://github.com/mishoo/UglifyJS2 +// Definitions by: Tanguy Krotoff +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// + +declare module 'uglify-js' { + import * as MOZ_SourceMap from 'source-map'; + + namespace UglifyJS { + interface Tokenizer { + /** + * The type of this token. + * Can be "num", "string", "regexp", "operator", "punc", "atom", "name", "keyword", "comment1" or "comment2". + * "comment1" and "comment2" are for single-line, respectively multi-line comments. + */ + type: string; + + /** + * The name of the file where this token originated from. Useful when compressing multiple files at once to generate the proper source map. + */ + file: string; + + /** + * The "value" of the token. + * That's additional information and depends on the token type: "num", "string" and "regexp" tokens you get their literal value. + * - For "operator" you get the operator. + * - For "punc" it's the punctuation sign (parens, comma, semicolon etc). + * - For "atom", "name" and "keyword" it's the name of the identifier + * - For comments it's the body of the comment (excluding the initial "//" and "/*". + */ + value: string; + + /** + * The line number of this token in the original code. + * 1-based index. + */ + line: number; + + /** + * The column number of this token in the original code. + * 0-based index. + */ + col: number; + + /** + * Short for "newline before", it's a boolean that tells us whether there was a newline before this node in the original source. It helps for automatic semicolon insertion. + * For multi-line comments in particular this will be set to true if there either was a newline before this comment, or * * if this comment contains a newline. + */ + nlb: boolean; + + /** + * This doesn't apply for comment tokens, but for all other token types it will be an array of comment tokens that were found before. + */ + comments_before: string[]; + } + + interface AST_Node { + // The first token of this node + start: AST_Node; + + // The last token of this node + end: AST_Node; + + transform(tt: TreeTransformer): AST_Toplevel; + } + + interface AST_Toplevel extends AST_Node { + // UglifyJS contains a scope analyzer which figures out variable/function definitions, references etc. + // You need to call it manually before compression or mangling. + // The figure_out_scope method is defined only on the AST_Toplevel node. + figure_out_scope(): void; + + // Get names that are optimized for GZip compression (names will be generated using the most frequent characters first) + compute_char_frequency(): void; + + mangle_names(): void; + + print(stream: OutputStream): void; + + print_to_string(options?: BeautifierOptions): string; + } + + interface MinifyOptions { + spidermonkey?: boolean; + outSourceMap?: string; + sourceRoot?: string; + inSourceMap?: string; + fromString?: boolean; + warnings?: boolean; + mangle?: Object; + output?: MinifyOutput, + compress?: Object; + } + + interface MinifyOutput { + code: string; + map: string; + } + + function minify(files: string | Array, options?: MinifyOptions): MinifyOutput; + + + interface ParseOptions { + // Default is false + strict?: boolean; + + // Input file name, default is null + filename?: string; + + // Default is null + toplevel?: AST_Toplevel; + } + + /** + * The parser creates a custom abstract syntax tree given a piece of JavaScript code. + * Perhaps you should read about the AST first. + */ + function parse(code: string, options?: ParseOptions): AST_Toplevel; + + + interface BeautifierOptions { + /** + * Start indentation on every line (only when `beautify`) + */ + indent_start?: number; + + /** + * Indentation level (only when `beautify`) + */ + indent_level?: number; + + /** + * Quote all keys in object literals? + */ + quote_keys?: boolean; + + /** + * Add a space after colon signs? + */ + space_colon?: boolean; + + /** + * Output ASCII-safe? (encodes Unicode characters as ASCII) + */ + ascii_only?: boolean; + + /** + * Escape " boolean; + + /** + * UglifyJS provides a TreeWalker object and every node has a walk method that given a walker will apply your visitor to each node in the tree. + * Your visitor can return a non-falsy value in order to prevent descending the current node. + */ + function TreeWalker(visitor: visitor): TreeWalker; + + + // TODO + interface TreeTransformer extends TreeWalker { + } + + /** + * The tree transformer is a special case of a tree walker. + * In fact it even inherits from TreeWalker and you can use the same methods, but initialization and visitor protocol are a bit different. + */ + function TreeTransformer(before: visitor, after: visitor): TreeTransformer; + } + + export = UglifyJS; +}