feat: add types for UglifyJS V3

This commit is contained in:
Alan Agius 2018-03-22 19:39:13 +01:00
parent e8bc07e649
commit c2fd8880d7
20 changed files with 890 additions and 579 deletions

View File

@ -14,10 +14,15 @@
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"paths": {
"uglify-js": [
"uglify-js/v2"
]
}
},
"files": [
"index.d.ts",
"express-minify-tests.ts"
]
}
}

View File

@ -14,10 +14,13 @@
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"paths": {
"uglify-js": ["uglify-js/v2"]
}
},
"files": [
"index.d.ts",
"gulp-filter-tests.ts"
]
}
}

View File

@ -2,6 +2,8 @@
// Project: https://www.npmjs.com/package/gulp-html-replace
// Definitions by: Peter Juras <https://github.com/peterjuras>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.2
/// <reference types="node" />

View File

@ -2,6 +2,7 @@
// Project: https://github.com/jonschlinkert/gulp-htmlmin
// Definitions by: Tanguy Krotoff <https://github.com/tkrotoff>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.2
/// <reference types="node" />

View File

@ -14,10 +14,15 @@
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"paths": {
"uglify-js": [
"uglify-js/v2"
]
}
},
"files": [
"index.d.ts",
"gulp-rev-replace-tests.ts"
]
}
}

View File

@ -14,11 +14,16 @@
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"paths": {
"uglify-js": [
"uglify-js/v2"
]
}
},
"files": [
"index.d.ts",
"composer.d.ts",
"gulp-uglify-tests.ts"
]
}
}

View File

@ -14,10 +14,13 @@
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"paths": {
"uglify-js": ["uglify-js/v2"]
}
},
"files": [
"index.d.ts",
"gulp-useref-tests.ts"
]
}
}

View File

@ -3,6 +3,7 @@
// Definitions by: Tanguy Krotoff <https://github.com/tkrotoff>
// Riku <https://github.com/rikuayanokozy>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.2
import * as UglifyJS from 'uglify-js';
import * as CleanCSS from 'clean-css';

View File

@ -16,6 +16,9 @@
"html-minifier": [
"html-minifier/v1"
],
"uglify-js": [
"uglify-js/v2"
],
"html-minifier/*": [
"html-minifier/v1/*"
]
@ -28,4 +31,4 @@
"index.d.ts",
"html-minifier-tests.ts"
]
}
}

View File

@ -1,429 +1,212 @@
// Type definitions for UglifyJS 2 v2.6.1
// Type definitions for UglifyJS 3.0
// Project: https://github.com/mishoo/UglifyJS2
// Definitions by: Tanguy Krotoff <https://github.com/tkrotoff>
// Definitions by: Alan Agius <https://github.com/alan-agius4>, Tanguy Krotoff <https://github.com/tkrotoff>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/// <reference types="source-map" />
import * as MOZ_SourceMap from 'source-map';
declare 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<string>, 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 "</script"?
*/
inline_script?: boolean;
/**
* Informative maximum line width (for beautified output)
*/
width?: number;
/**
* Maximum line length (for non-beautified output)
*/
max_line_len?: number;
/**
* Output IE-safe code?
*/
ie_proof?: boolean;
/**
* Beautify output?
*/
beautify?: boolean;
/**
* Output a source map
*/
source_map?: SourceMap;
/**
* Use brackets every time?
*/
bracketize?: boolean;
/**
* Output comments?
*/
comments?: boolean;
/**
* Use semicolons to separate statements? (otherwise, newlines)
*/
semicolons?: boolean;
}
interface OutputStream {
// Return the output so far as a string
get(): string;
toString(): string;
// Insert one indentation string (usually 4 characters).
// Optionally pass true to indent half the width (I'm using that for case and default lines in switch blocks.
// If beautify is off, this function does nothing.
indent(half?: boolean): void;
// Return the current indentation width (not level; for example if we're in level 2 and indent_level is 4, this method would return 8.
indentation(): number;
// return the width of the current line text minus indentation.
current_width(): number
// Return true if current_width() is bigger than options.width (assuming options.width is non-null, non-zero).
should_break(): boolean;
// If beautification is on, this inserts a newline. Otherwise it does nothing.
newline(): void;
// Include the given string into the output, adjusting current_line, current_col and current_pos accordingly.
print(str: string): void;
// If beautification is on this always includes a space character.
// Otherwise it saves a hint somewhere that a space might be needed at current point.
// The space will go in at the next output but only when absolutely required, for example it will insert the space in return 10 but not in return"stuff".
space(): void;
// Inserts a comma, and calls space() — that is, if beautification is on you'll get a space after the comma.
comma(): void;
// Inserts a colon, and calls space() if options.space_colon is set.
colon(): void;
// Returns the last printed chunk.
last(): string;
// If beautification is on it always inserts a semicolon.
// Otherwise it saves a hint that a semicolon might be needed at current point.
// The semicolon is inserted when the next output comes in, only if required to not break the JS syntax.
semicolon(): void;
// Always inserts a semicolon and clears the hint that a semicolon might be needed.
force_semicolon(): void;
// Encodes any non-ASCII characters in string with JavaScript's conventions (using \uCODE).
to_ascii(str: string): void;
// Prints an identifier. If options.ascii_only is set, non-ASCII chars will be encoded with JavaScript conventions.
print_name(name: string): void;
// Prints a string. It adds quotes automatically.
// It prefers double-quotes, but will actually count any quotes in the string and will use single-quotes if the output proves to be shorter (depending on how many backslashes it has to insert).
// It encodes to ASCII if options.ascii_only is set.
print_string(str: string): void;
// Returns the width of the next indentation level. For example if current level is 2 and options.indent_level is 4, it'll return 12.
next_indent(): number;
// Sets the current indentation to col (column), calls the function and thereafter restores the previous indentation level.
// If beautification is off it simply calls func.
with_indent(col: number, func: Function): void;
// This is used to output blocks in curly brackets.
// It'll print an open bracket at current point, then call newline() and with the next indentation level it calls your func.
// Lastly, it'll print an indented closing bracket. As usual, if beautification is off you'll just get {x} where x is whatever func outputs.
with_block(func: Function): void;
// Adds parens around the output that your function prints.
with_parens(func: Function): void;
// Adds square brackets around the output that your function prints.
with_square(func: Function): void;
// If options.source_map is set, this will generate a source mapping between the given token (which should be an AST_Token-like object) and the current line/col.
// The name is optional; in most cases it will be inferred from the token.
add_mapping(token: AST_Node, name?: string): void;
// Returns the option with the given name.
option(name: string): any;
// Returns the current line in the output (1-based).
line(): number;
// Returns the current column in the output (zero-based).
col(): number;
// Push the given node into an internal stack. This is used to keep track of current node's parent(s).
push_node(node: AST_Node): void;
// Pops the top of the stack and returns it.
pop_node(): AST_Node;
// Returns that internal stack.
stack(): any;
// Returns the n-th parent node (where zero means the direct parent).
parent(n: number): AST_Node;
}
/**
* The code generator is a recursive process of getting back source code from an AST returned by the parser.
* Every AST node has a print method that takes an OutputStream and dumps the code from that node into it.
* The stream object supports a lot of options that control the output.
* You can specify whether you'd like to get human-readable (indented) output, the indentation level, whether you'd like to quote all properties in object literals etc.
*/
function OutputStream(options?: BeautifierOptions): OutputStream;
interface SourceMapOptions {
/**
* The compressed file name
*/
file?: string;
/**
* The root URL to the original sources
*/
root?: string;
/**
* The input source map.
* Useful when you compress code that was generated from some other source (possibly other programming language).
* If you have an input source map, pass it in this argument and UglifyJS will generate a mapping that maps back
* to the original source (as opposed to the compiled code that you are compressing).
*/
orig?: Object | JSON;
}
interface SourceMap {
add(source: string, gen_line: number, gen_col: number, orig_line: number, orig_col: number, name?: string): void;
get(): MOZ_SourceMap.SourceMapGenerator;
toString(): string;
}
/**
* The output stream keeps track of the current line/column in the output and can trivially generate a source mapping to the original code via Mozilla's source-map library.
* To use this functionality, you must load this library (it's automatically require-d by UglifyJS in the NodeJS version, but in a browser you must load it yourself)
* and make it available via the global MOZ_SourceMap variable.
*/
function SourceMap(options?: SourceMapOptions): SourceMap;
interface CompressorOptions {
// Join consecutive statemets with the “comma operator”
sequences?: boolean;
// Optimize property access: a["foo"] → a.foo
properties?: boolean;
// Discard unreachable code
dead_code?: boolean;
// Discard “debugger” statements
drop_debugger?: boolean;
// Some unsafe optimizations (see below)
unsafe?: boolean;
// Optimize if-s and conditional expressions
conditionals?: boolean;
// Optimize comparisons
comparisons?: boolean;
// Evaluate constant expressions
evaluate?: boolean;
// Optimize boolean expressions
booleans?: boolean;
// Optimize loops
loops?: boolean;
// Drop unused variables/functions
unused?: boolean;
// Hoist function declarations
hoist_funs?: boolean;
// Hoist variable declarations
hoist_vars?: boolean;
// Optimize if-s followed by return/continue
if_return?: boolean;
// Join var declarations
join_vars?: boolean;
// Try to cascade `right` into `left` in sequences
cascade?: boolean;
// Drop side-effect-free statements
side_effects?: boolean;
// Warn about potentially dangerous optimizations/code
warnings?: boolean;
// Global definitions
global_defs?: Object;
}
/**
* The compressor is a tree transformer which reduces the code size by applying various optimizations on the AST
*/
function Compressor(options?: CompressorOptions): AST_Toplevel;
// TODO
interface TreeWalker {
}
type visitor = (node: AST_Node, descend: Function) => 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;
// TypeScript Version: 2.2
import { RawSourceMap } from 'source-map';
export interface ParseOptions {
/** Support top level `return` statements */
bare_returns?: boolean;
html5_comments?: boolean;
/** Support `#!command` as the first line */
shebang: boolean;
}
export = UglifyJS;
export interface CompressOptions {
/** Replace `arguments[index]` with function parameter name whenever possible. */
arguments?: boolean;
/** Various optimizations for boolean context, for example `!!a ? b : c → a ? b : c` */
booleans?: boolean;
/** Collapse single-use non-constant variables, side effects permitting. */
collapse_vars?: boolean;
/** Apply certain optimizations to binary nodes, e.g. `!(a <= b) → a > b,` attempts to negate binary nodes, e.g. `a = !b && !c && !d && !e → a=!(b||c||d||e)` etc */
comparisons?: boolean;
/** Apply optimizations for `if-s` and conditional expressions. */
conditionals?: boolean;
/** Remove unreachable code */
dead_code?: boolean;
/**
* Pass `true` to discard calls to console.* functions.
* If you wish to drop a specific function call such as `console.info` and/or retain side effects from function
* arguments after dropping the function call then use `pure_funcs` instead.
*/
drop_console?: boolean;
/** Remove `debugger;` statements */
drop_debugger?: boolean;
/** Attempt to evaluate constant expressions */
evaluate?: boolean;
/** Pass `true` to preserve completion values from terminal statements without `return`, e.g. in bookmarklets. */
expression?: boolean;
global_defs?: object;
/** hoist function declarations */
hoist_funs?: boolean;
/**
* Hoist properties from constant object and array literals into regular variables subject to a set of constraints.
* For example: `var o={p:1, q:2}; f(o.p, o.q);` is converted to `f(1, 2);`. Note: `hoist_props` works best with mangle enabled,
* the compress option passes set to 2 or higher, and the compress option toplevel enabled.
*/
hoist_props?: boolean;
/** Hoist var declarations (this is `false` by default because it seems to increase the size of the output in general) */
hoist_vars?: boolean;
/** Optimizations for if/return and if/continue */
if_return?: boolean;
/**
* Inline calls to function with simple/return statement
* - false -- same as `Disabled`
* - `Disabled` -- disabled inlining
* - `SimpleFunctions` -- inline simple functions
* - `WithArguments` -- inline functions with arguments
* - `WithArgumentsAndVariables` -- inline functions with arguments and variables
* - true -- same as `WithArgumentsAndVariables`
*/
inline?: boolean | InlineFunctions;
/** join consecutive `var` statements */
join_vars?: boolean;
/** Prevents the compressor from discarding unused function arguments. You need this for code which relies on `Function.length` */
keep_fargs?: boolean;
/** Pass true to prevent the compressor from discarding function names. Useful for code relying on `Function.prototype.name`. */
keep_fnames?: boolean;
/** Pass true to prevent Infinity from being compressed into `1/0`, which may cause performance issues on `Chrome` */
keep_infinity?: boolean;
/** Optimizations for `do`, `while` and `for` loops when we can statically determine the condition. */
loops?: boolean;
/** negate `Immediately-Called Function Expressions` where the return value is discarded, to avoid the parens that the code generator would insert. */
negate_iife?: boolean;
/** The maximum number of times to run compress. In some cases more than one pass leads to further compressed code. Keep in mind more passes will take more time. */
passes?: number;
/** Rewrite property access using the dot notation, for example `foo["bar"]` to `foo.bar` */
properties?: boolean;
/**
* An array of names and UglifyJS will assume that those functions do not produce side effects.
* DANGER: will not check if the name is redefined in scope.
* An example case here, for instance `var q = Math.floor(a/b)`.
* If variable q is not used elsewhere, UglifyJS will drop it, but will still keep the `Math.floor(a/b)`,
* not knowing what it does. You can pass `pure_funcs: [ 'Math.floor' ]` to let it know that this function
* won't produce any side effect, in which case the whole statement would get discarded. The current
* implementation adds some overhead (compression will be slower).
*/
pure_funcs?: string[];
pure_getters?: boolean | 'strict';
/**
* Allows single-use functions to be inlined as function expressions when permissible allowing further optimization.
* Enabled by default. Option depends on reduce_vars being enabled. Some code runs faster in the Chrome V8 engine if
* this option is disabled. Does not negatively impact other major browsers.
*/
reduce_funcs?: boolean;
/** Improve optimization on variables assigned with and used as constant values. */
reduce_vars?: boolean;
sequences?: boolean;
/** Pass false to disable potentially dropping functions marked as "pure". */
side_effects?: boolean;
/** De-duplicate and remove unreachable `switch` branches. */
switches?: boolean;
/** Drop unreferenced functions ("funcs") and/or variables ("vars") in the top level scope (false by default, true to drop both unreferenced functions and variables) */
toplevel?: boolean;
/** Prevent specific toplevel functions and variables from unused removal (can be array, comma-separated, RegExp or function. Implies toplevel) */
top_retain?: boolean;
typeofs?: boolean;
unsafe?: boolean;
/** Compress expressions like a `<= b` assuming none of the operands can be (coerced to) `NaN`. */
unsafe_comps?: boolean;
/** Compress and mangle `Function(args, code)` when both args and code are string literals. */
unsafe_Function?: boolean;
/** Optimize numerical expressions like `2 * x * 3` into `6 * x`, which may give imprecise floating point results. */
unsafe_math?: boolean;
/** Optimize expressions like `Array.prototype.slice.call(a)` into `[].slice.call(a)` */
unsafe_proto?: boolean;
/** Enable substitutions of variables with `RegExp` values the same way as if they are constants. */
unsafe_regexp?: boolean;
unsafe_undefined?: boolean;
unused?: boolean;
/** display warnings when dropping unreachable code or unused declarations etc. */
warnings?: boolean;
}
export enum InlineFunctions {
Disabled = 0,
SimpleFunctions = 1,
WithArguments = 2,
WithArgumentsAndVariables = 3
}
export interface MangleOptions {
/** Pass true to mangle names visible in scopes where `eval` or with are used. */
eval?: boolean;
/** Pass true to not mangle function names. Useful for code relying on `Function.prototype.name`. */
keep_fnames?: boolean;
/** Pass an array of identifiers that should be excluded from mangling. Example: `["foo", "bar"]`. */
reserved?: string[];
/** Pass true to mangle names declared in the top level scope. */
toplevel?: boolean;
properties?: boolean | ManglePropertiesOptions;
}
export interface ManglePropertiesOptions {
/** Use true to allow the mangling of builtin DOM properties. Not recommended to override this setting. */
builtins?: boolean;
/** Mangle names with the original name still present. Pass an empty string "" to enable, or a non-empty string to set the debug suffix. */
debug?: boolean;
/** Only mangle unquoted property names */
keep_quoted?: boolean;
/** Pass a RegExp literal to only mangle property names matching the regular expression. */
regex?: RegExp;
/** Do not mangle property names listed in the reserved array */
reserved?: string[];
}
export interface OutputOptions {
ascii_only?: boolean;
beautify?: boolean;
braces?: boolean;
comments?: boolean | 'all' | 'some' | RegExp;
indent_level?: number;
indent_start?: boolean;
inline_script?: boolean;
keep_quoted_props?: boolean;
max_line_len?: boolean;
preamble?: string;
preserve_line?: boolean;
quote_keys?: boolean;
quote_style?: OutputQuoteStyle;
semicolons?: boolean;
shebang?: boolean;
webkit?: boolean;
width?: number;
wrap_iife?: boolean;
}
export enum OutputQuoteStyle {
PreferDouble = 0,
AlwaysSingle = 1,
AlwaysDouble = 2,
AlwaysOriginal = 3
}
export interface MinifyOptions {
/** Pass true to return compressor warnings in result.warnings. Use the value `verbose` for more detailed warnings. */
warnings?: boolean | 'verbose';
parse?: ParseOptions;
compress?: boolean | CompressOptions;
mangle?: boolean | MangleOptions;
output?: OutputOptions;
sourceMap?: boolean | SourceMapOptions;
toplevel?: boolean;
nameCache?: object;
ie8?: boolean;
keep_fnames?: boolean;
}
export interface MinifyOutput {
error?: Error;
code: string;
map: string;
}
export interface SourceMapOptions {
filename?: string;
url?: string | 'inline';
root?: string;
content?: RawSourceMap;
}
export function minify(files: string | string[] | { [file: string]: string }, options?: MinifyOptions): MinifyOutput;

View File

@ -20,4 +20,4 @@
"index.d.ts",
"uglify-js-tests.ts"
]
}
}

View File

@ -1,79 +1,3 @@
{
"extends": "dtslint/dt.json",
"rules": {
"adjacent-overload-signatures": false,
"array-type": false,
"arrow-return-shorthand": false,
"ban-types": false,
"callable-types": false,
"comment-format": false,
"dt-header": false,
"eofline": false,
"export-just-namespace": false,
"import-spacing": false,
"interface-name": false,
"interface-over-type-literal": false,
"jsdoc-format": false,
"max-line-length": false,
"member-access": false,
"new-parens": false,
"no-any-union": false,
"no-boolean-literal-compare": false,
"no-conditional-assignment": false,
"no-consecutive-blank-lines": false,
"no-construct": false,
"no-declare-current-package": false,
"no-duplicate-imports": false,
"no-duplicate-variable": false,
"no-empty-interface": false,
"no-for-in-array": false,
"no-inferrable-types": false,
"no-internal-module": false,
"no-irregular-whitespace": false,
"no-mergeable-namespace": false,
"no-misused-new": false,
"no-namespace": false,
"no-object-literal-type-assertion": false,
"no-padding": false,
"no-redundant-jsdoc": false,
"no-redundant-jsdoc-2": false,
"no-redundant-undefined": false,
"no-reference-import": false,
"no-relative-import-in-test": false,
"no-self-import": false,
"no-single-declare-module": false,
"no-string-throw": false,
"no-unnecessary-callback-wrapper": false,
"no-unnecessary-class": false,
"no-unnecessary-generics": false,
"no-unnecessary-qualifier": false,
"no-unnecessary-type-assertion": false,
"no-useless-files": false,
"no-var-keyword": false,
"no-var-requires": false,
"no-void-expression": false,
"no-trailing-whitespace": false,
"object-literal-key-quotes": false,
"object-literal-shorthand": false,
"one-line": false,
"one-variable-per-declaration": false,
"only-arrow-functions": false,
"prefer-conditional-expression": false,
"prefer-const": false,
"prefer-declare-function": false,
"prefer-for-of": false,
"prefer-method-signature": false,
"prefer-template": false,
"radix": false,
"semicolon": false,
"space-before-function-paren": false,
"space-within-parens": false,
"strict-export-declare-modifiers": false,
"trim-file": false,
"triple-equals": false,
"typedef-whitespace": false,
"unified-signatures": false,
"void-return": false,
"whitespace": false
}
"extends": "dtslint/dt.json"
}

View File

@ -1,72 +1,36 @@
/// <reference types="node" />
import * as UglifyJS from 'uglify-js';
import * as fs from 'fs';
import { OutputQuoteStyle, minify } from 'uglify-js';
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});
let code: any;
var result = UglifyJS.minify([ "file1.js", "file2.js", "file3.js" ]);
console.log(result.code);
code = {
"file1.js": "function add(first, second) { return first + second; }",
"file2.js": "console.log(add(1 + 2, 3 + 4));"
};
var result = UglifyJS.minify([ "file1.js", "file2.js", "file3.js" ], {
outSourceMap: "out.js.map"
});
console.log(result.code); // minified output
console.log(result.map);
minify(code);
var result = UglifyJS.minify([ "file1.js", "file2.js", "file3.js" ], {
outSourceMap: "out.js.map",
sourceRoot: "http://example.com/src"
code = "function add(first, second) { return first + second; }";
minify(code);
minify(code, {
output: {
quote_style: OutputQuoteStyle.AlwaysDouble
}
});
var result = UglifyJS.minify("compiled.js", {
inSourceMap: "compiled.js.map",
outSourceMap: "minified.js.map"
minify(code, {
warnings: 'verbose',
mangle: {
properties: {
regex: /reg/
}
},
sourceMap: {
filename: 'foo.map'
},
compress: {
arguments: true
}
});
// 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

429
types/uglify-js/v2/index.d.ts vendored Normal file
View File

@ -0,0 +1,429 @@
// Type definitions for UglifyJS 2 v2.6.1
// Project: https://github.com/mishoo/UglifyJS2
// Definitions by: Tanguy Krotoff <https://github.com/tkrotoff>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/// <reference types="source-map" />
import * as MOZ_SourceMap from 'source-map';
declare 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<string>, 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 "</script"?
*/
inline_script?: boolean;
/**
* Informative maximum line width (for beautified output)
*/
width?: number;
/**
* Maximum line length (for non-beautified output)
*/
max_line_len?: number;
/**
* Output IE-safe code?
*/
ie_proof?: boolean;
/**
* Beautify output?
*/
beautify?: boolean;
/**
* Output a source map
*/
source_map?: SourceMap;
/**
* Use brackets every time?
*/
bracketize?: boolean;
/**
* Output comments?
*/
comments?: boolean;
/**
* Use semicolons to separate statements? (otherwise, newlines)
*/
semicolons?: boolean;
}
interface OutputStream {
// Return the output so far as a string
get(): string;
toString(): string;
// Insert one indentation string (usually 4 characters).
// Optionally pass true to indent half the width (I'm using that for case and default lines in switch blocks.
// If beautify is off, this function does nothing.
indent(half?: boolean): void;
// Return the current indentation width (not level; for example if we're in level 2 and indent_level is 4, this method would return 8.
indentation(): number;
// return the width of the current line text minus indentation.
current_width(): number
// Return true if current_width() is bigger than options.width (assuming options.width is non-null, non-zero).
should_break(): boolean;
// If beautification is on, this inserts a newline. Otherwise it does nothing.
newline(): void;
// Include the given string into the output, adjusting current_line, current_col and current_pos accordingly.
print(str: string): void;
// If beautification is on this always includes a space character.
// Otherwise it saves a hint somewhere that a space might be needed at current point.
// The space will go in at the next output but only when absolutely required, for example it will insert the space in return 10 but not in return"stuff".
space(): void;
// Inserts a comma, and calls space() — that is, if beautification is on you'll get a space after the comma.
comma(): void;
// Inserts a colon, and calls space() if options.space_colon is set.
colon(): void;
// Returns the last printed chunk.
last(): string;
// If beautification is on it always inserts a semicolon.
// Otherwise it saves a hint that a semicolon might be needed at current point.
// The semicolon is inserted when the next output comes in, only if required to not break the JS syntax.
semicolon(): void;
// Always inserts a semicolon and clears the hint that a semicolon might be needed.
force_semicolon(): void;
// Encodes any non-ASCII characters in string with JavaScript's conventions (using \uCODE).
to_ascii(str: string): void;
// Prints an identifier. If options.ascii_only is set, non-ASCII chars will be encoded with JavaScript conventions.
print_name(name: string): void;
// Prints a string. It adds quotes automatically.
// It prefers double-quotes, but will actually count any quotes in the string and will use single-quotes if the output proves to be shorter (depending on how many backslashes it has to insert).
// It encodes to ASCII if options.ascii_only is set.
print_string(str: string): void;
// Returns the width of the next indentation level. For example if current level is 2 and options.indent_level is 4, it'll return 12.
next_indent(): number;
// Sets the current indentation to col (column), calls the function and thereafter restores the previous indentation level.
// If beautification is off it simply calls func.
with_indent(col: number, func: Function): void;
// This is used to output blocks in curly brackets.
// It'll print an open bracket at current point, then call newline() and with the next indentation level it calls your func.
// Lastly, it'll print an indented closing bracket. As usual, if beautification is off you'll just get {x} where x is whatever func outputs.
with_block(func: Function): void;
// Adds parens around the output that your function prints.
with_parens(func: Function): void;
// Adds square brackets around the output that your function prints.
with_square(func: Function): void;
// If options.source_map is set, this will generate a source mapping between the given token (which should be an AST_Token-like object) and the current line/col.
// The name is optional; in most cases it will be inferred from the token.
add_mapping(token: AST_Node, name?: string): void;
// Returns the option with the given name.
option(name: string): any;
// Returns the current line in the output (1-based).
line(): number;
// Returns the current column in the output (zero-based).
col(): number;
// Push the given node into an internal stack. This is used to keep track of current node's parent(s).
push_node(node: AST_Node): void;
// Pops the top of the stack and returns it.
pop_node(): AST_Node;
// Returns that internal stack.
stack(): any;
// Returns the n-th parent node (where zero means the direct parent).
parent(n: number): AST_Node;
}
/**
* The code generator is a recursive process of getting back source code from an AST returned by the parser.
* Every AST node has a print method that takes an OutputStream and dumps the code from that node into it.
* The stream object supports a lot of options that control the output.
* You can specify whether you'd like to get human-readable (indented) output, the indentation level, whether you'd like to quote all properties in object literals etc.
*/
function OutputStream(options?: BeautifierOptions): OutputStream;
interface SourceMapOptions {
/**
* The compressed file name
*/
file?: string;
/**
* The root URL to the original sources
*/
root?: string;
/**
* The input source map.
* Useful when you compress code that was generated from some other source (possibly other programming language).
* If you have an input source map, pass it in this argument and UglifyJS will generate a mapping that maps back
* to the original source (as opposed to the compiled code that you are compressing).
*/
orig?: Object | JSON;
}
interface SourceMap {
add(source: string, gen_line: number, gen_col: number, orig_line: number, orig_col: number, name?: string): void;
get(): MOZ_SourceMap.SourceMapGenerator;
toString(): string;
}
/**
* The output stream keeps track of the current line/column in the output and can trivially generate a source mapping to the original code via Mozilla's source-map library.
* To use this functionality, you must load this library (it's automatically require-d by UglifyJS in the NodeJS version, but in a browser you must load it yourself)
* and make it available via the global MOZ_SourceMap variable.
*/
function SourceMap(options?: SourceMapOptions): SourceMap;
interface CompressorOptions {
// Join consecutive statemets with the “comma operator”
sequences?: boolean;
// Optimize property access: a["foo"] → a.foo
properties?: boolean;
// Discard unreachable code
dead_code?: boolean;
// Discard “debugger” statements
drop_debugger?: boolean;
// Some unsafe optimizations (see below)
unsafe?: boolean;
// Optimize if-s and conditional expressions
conditionals?: boolean;
// Optimize comparisons
comparisons?: boolean;
// Evaluate constant expressions
evaluate?: boolean;
// Optimize boolean expressions
booleans?: boolean;
// Optimize loops
loops?: boolean;
// Drop unused variables/functions
unused?: boolean;
// Hoist function declarations
hoist_funs?: boolean;
// Hoist variable declarations
hoist_vars?: boolean;
// Optimize if-s followed by return/continue
if_return?: boolean;
// Join var declarations
join_vars?: boolean;
// Try to cascade `right` into `left` in sequences
cascade?: boolean;
// Drop side-effect-free statements
side_effects?: boolean;
// Warn about potentially dangerous optimizations/code
warnings?: boolean;
// Global definitions
global_defs?: Object;
}
/**
* The compressor is a tree transformer which reduces the code size by applying various optimizations on the AST
*/
function Compressor(options?: CompressorOptions): AST_Toplevel;
// TODO
interface TreeWalker {
}
type visitor = (node: AST_Node, descend: Function) => 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;

View File

@ -0,0 +1,6 @@
{
"private": true,
"dependencies": {
"source-map": "^0.6.1"
}
}

View File

@ -0,0 +1,26 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": false,
"strictFunctionTypes": true,
"baseUrl": "../../",
"typeRoots": [
"../../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true,
"paths": {
"uglify-js": ["uglify-js/v2"]
}
},
"files": [
"index.d.ts",
"uglify-js-tests.ts"
]
}

View File

@ -0,0 +1,79 @@
{
"extends": "dtslint/dt.json",
"rules": {
"adjacent-overload-signatures": false,
"array-type": false,
"arrow-return-shorthand": false,
"ban-types": false,
"callable-types": false,
"comment-format": false,
"dt-header": false,
"eofline": false,
"export-just-namespace": false,
"import-spacing": false,
"interface-name": false,
"interface-over-type-literal": false,
"jsdoc-format": false,
"max-line-length": false,
"member-access": false,
"new-parens": false,
"no-any-union": false,
"no-boolean-literal-compare": false,
"no-conditional-assignment": false,
"no-consecutive-blank-lines": false,
"no-construct": false,
"no-declare-current-package": false,
"no-duplicate-imports": false,
"no-duplicate-variable": false,
"no-empty-interface": false,
"no-for-in-array": false,
"no-inferrable-types": false,
"no-internal-module": false,
"no-irregular-whitespace": false,
"no-mergeable-namespace": false,
"no-misused-new": false,
"no-namespace": false,
"no-object-literal-type-assertion": false,
"no-padding": false,
"no-redundant-jsdoc": false,
"no-redundant-jsdoc-2": false,
"no-redundant-undefined": false,
"no-reference-import": false,
"no-relative-import-in-test": false,
"no-self-import": false,
"no-single-declare-module": false,
"no-string-throw": false,
"no-unnecessary-callback-wrapper": false,
"no-unnecessary-class": false,
"no-unnecessary-generics": false,
"no-unnecessary-qualifier": false,
"no-unnecessary-type-assertion": false,
"no-useless-files": false,
"no-var-keyword": false,
"no-var-requires": false,
"no-void-expression": false,
"no-trailing-whitespace": false,
"object-literal-key-quotes": false,
"object-literal-shorthand": false,
"one-line": false,
"one-variable-per-declaration": false,
"only-arrow-functions": false,
"prefer-conditional-expression": false,
"prefer-const": false,
"prefer-declare-function": false,
"prefer-for-of": false,
"prefer-method-signature": false,
"prefer-template": false,
"radix": false,
"semicolon": false,
"space-before-function-paren": false,
"space-within-parens": false,
"strict-export-declare-modifiers": false,
"trim-file": false,
"triple-equals": false,
"typedef-whitespace": false,
"unified-signatures": false,
"void-return": false,
"whitespace": false
}
}

View File

@ -0,0 +1,72 @@
/// <reference types="node" />
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

View File

@ -368,7 +368,7 @@ plugin = new webpack.optimize.UglifyJsPlugin({
});
plugin = new webpack.optimize.UglifyJsPlugin({
mangle: {
except: ['$super', '$', 'exports', 'require']
reserved: ['$super', '$', 'exports', 'require']
}
});
plugin = new webpack.optimize.UglifyJsPlugin({

View File

@ -262,7 +262,7 @@ plugin = new webpack.optimize.UglifyJsPlugin({
});
plugin = new webpack.optimize.UglifyJsPlugin({
mangle: {
except: ['$super', '$', 'exports', 'require']
reserved: ['$super', '$', 'exports', 'require']
}
});
plugin = new webpack.optimize.UglifyJsPlugin({