Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Socket
Sign inDemoInstall

terser

Package Overview
Dependencies
Maintainers
1
Versions
182
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

terser - npm Package Compare versions

Comparing version 5.19.2 to 5.24.0

lib/compress/global-defs.js

30

CHANGELOG.md
# Changelog
## v5.24.0
- Improve formatting performance in V8 by keeping a small work string and a large output string
## v5.23.0
- When top_retain will keep a variable assignment around, inline the assignee when it's shorter than the name (#1434)
- Remove empty class `static {}` blocks.
## v5.22.0
- Do not `unsafe`ly shorten expressions like a?.toString() when they're conditional.
- Avoid running drop_unused in nodes that aren't scopes. Fixes a rare crash.
- When 'module' is enabled, assume strict mode when figuring out scopes.
## v5.21.0
- Do not inline functions that would be retained in the toplevel (as this would cause code duplication).
- Fix precedence of arrow function and ternary operator when formatting output.
## v5.20.0
- Passing `minify()` zero files will now throw a clean exception (#1450)
- `drop_console` supports passing in an array of `console.*` method names (#1445)
- New DOM properties from the WebGPU API have been added for use in the property mangler (#1436)
- Internal code simplification (#1437)
## v5.19.4
- Prevent creating very deeply nested ternaries from a long list of `if..return`
- Prevent inlining classes into other functions, to avoid constructors being compared.
## v5.19.3
- Fix side effect detection of `optional?.chains`.
- Add roundRect to domprops.js (#1426)
## v5.19.2

@@ -4,0 +34,0 @@ - fix performance hit from avoiding HTML comments in the output

2

lib/compress/common.js

@@ -347,3 +347,3 @@ /***********************************************************************

&& fn.name
&& compressor.top_retain(fn.name);
&& compressor.top_retain(fn.name.definition());
}

@@ -324,3 +324,5 @@ /***********************************************************************

}
if (this.expression.may_throw_on_access(compressor)) return this;
if (!this.optional && this.expression.may_throw_on_access(compressor)) {
return this;
}

@@ -334,11 +336,13 @@ return this.expression.drop_side_effect_free(compressor, first_in_statement);

}
if (this.expression.may_throw_on_access(compressor)) return this;
if (!this.optional && this.expression.may_throw_on_access(compressor)) {
return this;
}
var property = this.property.drop_side_effect_free(compressor);
if (property && this.optional) return this;
var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
if (!expression)
return this.property.drop_side_effect_free(compressor, first_in_statement);
var property = this.property.drop_side_effect_free(compressor);
if (!property)
return expression;
return make_sequence(this, [expression, property]);
if (expression && property) return make_sequence(this, [expression, property]);
return expression || property;
});

@@ -345,0 +349,0 @@

@@ -80,6 +80,2 @@ /***********************************************************************

walk,
_INLINE,
_NOINLINE,
_PURE
} from "../ast.js";

@@ -117,2 +113,4 @@ import {

if (compressor.has_directive("use asm")) return;
if (!this.variables) return; // not really a scope (eg: AST_Class)
var self = this;

@@ -137,3 +135,3 @@ if (self.pinned()) return;

self.variables.forEach(function(def) {
if (compressor.top_retain(def) && !in_use_ids.has(def.id)) {
if (compressor.top_retain(def)) {
in_use_ids.set(def.id, def);

@@ -153,5 +151,3 @@ }

var def = argname.definition();
if (!in_use_ids.has(def.id)) {
in_use_ids.set(def.id, def);
}
in_use_ids.set(def.id, def);
});

@@ -169,3 +165,3 @@ }

if (in_export || !drop_funcs && scope === self) {
if (node_def.global && !in_use_ids.has(node_def.id)) {
if (node_def.global) {
in_use_ids.set(node_def.id, node_def);

@@ -178,6 +174,8 @@ }

}
if (node instanceof AST_SymbolFunarg && scope === self) {
// In the root scope, we drop things. In inner scopes, we just check for uses.
const in_root_scope = scope === self;
if (node instanceof AST_SymbolFunarg && in_root_scope) {
map_add(var_defs_by_id, node.definition().id, node);
}
if (node instanceof AST_Definitions && scope === self) {
if (node instanceof AST_Definitions && in_root_scope) {
const in_export = tw.parent() instanceof AST_Export;

@@ -192,3 +190,3 @@ node.definitions.forEach(function(def) {

const def = node.definition();
if (def.global && !in_use_ids.has(def.id)) {
if (def.global) {
in_use_ids.set(def.id, def);

@@ -195,0 +193,0 @@ }

@@ -101,3 +101,2 @@ /***********************************************************************

AST_This,
AST_Toplevel,
AST_True,

@@ -111,3 +110,2 @@ AST_Try,

TreeTransformer,
walk,

@@ -126,7 +124,5 @@ walk_abort,

member,
noop,
has_annotation,
HOP
} from "../utils/index.js";
import { make_node_from_constant, make_sequence, best_of_expression, read_property } from "./common.js";
import { make_sequence, best_of_expression, read_property } from "./common.js";

@@ -383,12 +379,23 @@ import { INLINED, UNDEFINED, has_flag } from "./compressor-flags.js";

def_has_side_effects(AST_Dot, function(compressor) {
if (is_nullish(this, compressor)) return false;
return !this.optional && this.expression.may_throw_on_access(compressor)
|| this.expression.has_side_effects(compressor);
if (is_nullish(this, compressor)) {
return this.expression.has_side_effects(compressor);
}
if (!this.optional && this.expression.may_throw_on_access(compressor)) {
return true;
}
return this.expression.has_side_effects(compressor);
});
def_has_side_effects(AST_Sub, function(compressor) {
if (is_nullish(this, compressor)) return false;
if (is_nullish(this, compressor)) {
return this.expression.has_side_effects(compressor);
}
if (!this.optional && this.expression.may_throw_on_access(compressor)) {
return true;
}
return !this.optional && this.expression.may_throw_on_access(compressor)
|| this.expression.has_side_effects(compressor)
|| this.property.has_side_effects(compressor);
var property = this.property.has_side_effects(compressor);
if (property && this.optional) return true; // "?." is a condition
return property || this.expression.has_side_effects(compressor);
});

@@ -724,76 +731,2 @@ def_has_side_effects(AST_Chain, function (compressor) {

(function(def_find_defs) {
function to_node(value, orig) {
if (value instanceof AST_Node) {
if (!(value instanceof AST_Constant)) {
// Value may be a function, an array including functions and even a complex assign / block expression,
// so it should never be shared in different places.
// Otherwise wrong information may be used in the compression phase
value = value.clone(true);
}
return make_node(value.CTOR, orig, value);
}
if (Array.isArray(value)) return make_node(AST_Array, orig, {
elements: value.map(function(value) {
return to_node(value, orig);
})
});
if (value && typeof value == "object") {
var props = [];
for (var key in value) if (HOP(value, key)) {
props.push(make_node(AST_ObjectKeyVal, orig, {
key: key,
value: to_node(value[key], orig)
}));
}
return make_node(AST_Object, orig, {
properties: props
});
}
return make_node_from_constant(value, orig);
}
AST_Toplevel.DEFMETHOD("resolve_defines", function(compressor) {
if (!compressor.option("global_defs")) return this;
this.figure_out_scope({ ie8: compressor.option("ie8") });
return this.transform(new TreeTransformer(function(node) {
var def = node._find_defs(compressor, "");
if (!def) return;
var level = 0, child = node, parent;
while (parent = this.parent(level++)) {
if (!(parent instanceof AST_PropAccess)) break;
if (parent.expression !== child) break;
child = parent;
}
if (is_lhs(child, parent)) {
return;
}
return def;
}));
});
def_find_defs(AST_Node, noop);
def_find_defs(AST_Chain, function(compressor, suffix) {
return this.expression._find_defs(compressor, suffix);
});
def_find_defs(AST_Dot, function(compressor, suffix) {
return this.expression._find_defs(compressor, "." + this.property + suffix);
});
def_find_defs(AST_SymbolDeclaration, function() {
if (!this.global()) return;
});
def_find_defs(AST_SymbolRef, function(compressor, suffix) {
if (!this.global()) return;
var defines = compressor.option("global_defs");
var name = this.name + suffix;
if (HOP(defines, name)) return to_node(defines[name], this);
});
def_find_defs(AST_ImportMeta, function(compressor, suffix) {
var defines = compressor.option("global_defs");
var name = "import.meta" + suffix;
if (HOP(defines, name)) return to_node(defines[name], this);
});
})(function(node, func) {
node.DEFMETHOD("_find_defs", func);
});
// method to negate an expression

@@ -800,0 +733,0 @@ (function(def_negate) {

@@ -87,3 +87,3 @@ /***********************************************************************

_NOINLINE,
_PURE
_PURE,
} from "../ast.js";

@@ -152,8 +152,34 @@ import { make_node, has_annotation } from "../utils/index.js";

/**
* An extra check function for `top_retain` option, compare the length of const identifier
* and init value length and return true if init value is longer than identifier. for example:
* ```
* // top_retain: ["example"]
* const example = 100
* ```
* it will return false because length of "100" is short than identifier "example".
*/
function is_const_symbol_short_than_init_value(def, fixed_value) {
if (def.orig.length === 1 && fixed_value) {
const init_value_length = fixed_value.size();
const identifer_length = def.name.length;
return init_value_length > identifer_length;
}
return true;
}
export function inline_into_symbolref(self, compressor) {
const parent = compressor.parent();
const def = self.definition();
const nearest_scope = compressor.find_scope();
if (compressor.top_retain && def.global && compressor.top_retain(def)) {
let fixed = self.fixed_value();
if (
compressor.top_retain &&
def.global &&
compressor.top_retain(def) &&
// when identifier is in top_retain option dose not mean we can always inline it.
// if identifier name is longer then init value, we can replace it.
is_const_symbol_short_than_init_value(def, fixed)
) {
// keep it
def.fixed = false;

@@ -164,3 +190,2 @@ def.single_use = false;

let fixed = self.fixed_value();
let single_use = def.single_use

@@ -180,2 +205,6 @@ && !(parent instanceof AST_Call

if (fixed instanceof AST_Class && def.scope !== self.scope) {
return self;
}
if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {

@@ -293,4 +322,5 @@ if (retain_top_func(fixed, compressor)) {

export function inline_into_call(self, fn, compressor) {
export function inline_into_call(self, compressor) {
var exp = self.expression;
var fn = exp;
var simple_args = self.args.every((arg) => !(arg instanceof AST_Expansion));

@@ -303,5 +333,11 @@

const fixed = fn.fixed_value();
if (!retain_top_func(fixed, compressor)) {
fn = fixed;
if (
retain_top_func(fixed, compressor)
|| !compressor.toplevel.funcs && exp.definition().global
) {
return self;
}
fn = fixed;
}

@@ -308,0 +344,0 @@

@@ -99,6 +99,2 @@ /***********************************************************************

TreeWalker,
_INLINE,
_NOINLINE,
_PURE
} from "../ast.js";

@@ -105,0 +101,0 @@ import { HOP, make_node, noop } from "../utils/index.js";

@@ -984,3 +984,7 @@ /***********************************************************************

var in_lambda = self instanceof AST_Lambda;
for (var i = statements.length; --i >= 0;) {
// Prevent extremely deep nesting
// https://github.com/terser/terser/issues/1432
// https://github.com/webpack/webpack/issues/17548
const iteration_start = Math.min(statements.length, 500);
for (var i = iteration_start; --i >= 0;) {
var stat = statements[i];

@@ -987,0 +991,0 @@ var j = next_index(i);

@@ -233,2 +233,5 @@ "use strict";

}
if (options.parse.toplevel === null) {
throw new Error("no source file given");
}

@@ -235,0 +238,0 @@ toplevel = options.parse.toplevel;

@@ -169,6 +169,4 @@ /***********************************************************************

var normalize_directives = function(body) {
var in_directive = true;
for (var i = 0; i < body.length; i++) {
if (in_directive && body[i] instanceof AST_Statement && body[i].body instanceof AST_String) {
if (body[i] instanceof AST_Statement && body[i].body instanceof AST_String) {
body[i] = new AST_Directive({

@@ -179,4 +177,4 @@ start: body[i].start,

});
} else if (in_directive && !(body[i] instanceof AST_Statement && body[i].body instanceof AST_String)) {
in_directive = false;
} else {
return body;
}

@@ -183,0 +181,0 @@ }

@@ -208,2 +208,3 @@ /***********************************************************************

safari10: false,
module: false,
});

@@ -376,2 +377,7 @@

});
if (options.module) {
tw.directives["use strict"] = true;
}
this.walk(tw);

@@ -378,0 +384,0 @@

@@ -92,3 +92,3 @@ import {

AST_Node.prototype.size = function (compressor, stack) {
mangle_options = compressor && compressor.mangle_options;
mangle_options = compressor && compressor._mangle_options;

@@ -95,0 +95,0 @@ let size = 0;

@@ -7,3 +7,3 @@ {

"license": "BSD-2-Clause",
"version": "5.19.2",
"version": "5.24.0",
"engines": {

@@ -10,0 +10,0 @@ "node": ">=10"

@@ -157,3 +157,4 @@ <h1><img src="https://terser.org/img/terser-banner-logo.png" alt="Terser" width="400"></h1>

--module Input is an ES6 module. If `compress` or `mangle` is
enabled then the `toplevel` option will be enabled.
enabled then the `toplevel` option, as well as strict mode,
will be enabled.
--name-cache <file> File to hold mangled name mappings.

@@ -421,3 +422,3 @@ --safari10 Support non-standard Safari 10/11.

Browser loading is also supported:
Browser loading is also supported. It exposes a global variable `Terser` containing a `.minify` property:
```html

@@ -734,5 +735,4 @@ <script src="https://cdn.jsdelivr.net/npm/source-map@0.7.3/dist/source-map.js"></script>

- `drop_console` (default: `false`) -- 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.
`console.*` functions. If you only want to discard a portion of console,
you can pass an array like this `['log', 'info']`, which will only discard `console.log`、 `console.info`.

@@ -919,3 +919,3 @@ - `drop_debugger` (default: `true`) -- remove `debugger;` statements

- `module` (default `false`) -- Pass `true` an ES6 modules, where the toplevel
scope is not the global scope. Implies `toplevel`.
scope is not the global scope. Implies `toplevel` and assumes input code is strict mode JS.

@@ -922,0 +922,0 @@ - `nth_identifier` (default: an internal mangler that weights based on character

@@ -7,2 +7,5 @@ /// <reference lib="es2015" />

export type ConsoleProperty = keyof typeof console;
type DropConsoleOption = boolean | ConsoleProperty[];
export interface ParseOptions {

@@ -28,3 +31,3 @@ bare_returns?: boolean;

directives?: boolean;
drop_console?: boolean;
drop_console?: DropConsoleOption;
drop_debugger?: boolean;

@@ -31,0 +34,0 @@ ecma?: ECMA;

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc