From b6260641200adf8888d52ef51c1adde357ecfb78 Mon Sep 17 00:00:00 2001 From: Gusted Date: Sat, 19 Jun 2021 22:25:05 +0200 Subject: [PATCH 1/4] feat: mangle Infinity This change will shave some bytes when the code is using `Infinity`. The ECMA definition of divide can return (-)Infinity based of the second value in specif when it's zero. And based on the first value it will be positive or negative. See: https://tc39.es/ecma262/#sec-numeric-types-number-divide It should be a small change and not break any code. And any existing code should play along nice Simplified ```js Infinity**2 1/0**2 ``` Hereby ** has priority over the `/` and could break the code, but now it's nice about `1` and `0` they won't change at all, doesn't matter which expressions you try to use with which numbers. And `1` could be set to 0 with ```js 0 * 1/0 0 * Infinity ``` But in both cases printed NaN like it should behave. Regards, Gusted --- CHANGELOG.md | 6 ++++++ internal/js_printer/js_printer.go | 11 ++++++++--- internal/js_printer/js_printer_test.go | 11 +++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f732752fe9a..cc1818ff6bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +* Mangle Syntax `Infinity` to `1/0` + + MinifySyntax will now mangle the `Infinty` keywoard to `1/0` which is less in bytes. + ## 0.12.9 * Allow `this` with `--define` ([#1361](https://github.com/evanw/esbuild/issues/1361)) diff --git a/internal/js_printer/js_printer.go b/internal/js_printer/js_printer.go index d9cf7ca79e2..cd3356d156d 100644 --- a/internal/js_printer/js_printer.go +++ b/internal/js_printer/js_printer.go @@ -2129,18 +2129,23 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla value := e.Value absValue := math.Abs(value) + infinity := "Infinity" + if p.options.MangleSyntax { + infinity = "1/0" + } + if value != value { p.printSpaceBeforeIdentifier() p.print("NaN") } else if value == positiveInfinity { p.printSpaceBeforeIdentifier() - p.print("Infinity") + p.print(infinity) } else if value == negativeInfinity { if level >= js_ast.LPrefix { - p.print("(-Infinity)") + p.print("(-" + infinity + ")") } else { p.printSpaceBeforeOperator(js_ast.UnOpNeg) - p.print("-Infinity") + p.print("-" + infinity) } } else { if !math.Signbit(value) { diff --git a/internal/js_printer/js_printer_test.go b/internal/js_printer/js_printer_test.go index 48c3570ddd6..c808210ffca 100644 --- a/internal/js_printer/js_printer_test.go +++ b/internal/js_printer/js_printer_test.go @@ -931,3 +931,14 @@ func TestAvoidSlashScript(t *testing.T) { expectPrintedMinify(t, "x = 1 < / script/.exec(y).length", "x=1 Date: Sat, 19 Jun 2021 22:30:39 +0200 Subject: [PATCH 2/4] Add example code in Changelog.MD --- CHANGELOG.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc1818ff6bd..e152105b97b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,21 @@ ## Unreleased -* Mangle Syntax `Infinity` to `1/0` +* Minify Syntax `Infinity` to `1/0` - MinifySyntax will now mangle the `Infinty` keywoard to `1/0` which is less in bytes. + `--minify-syntax` will now minify the `Infinity` keyword to `1/0` which is less in bytes. + + ```js + // Orginial code + const a = Infinity; + + const b = 0 * Infinity; + + // Output with "--mangle-syntax" + const a = 1/0; + + const b = 0 * 1/0; + ``` ## 0.12.9 From 046fafd3c9546941a5ebbd066bf13f5190540be4 Mon Sep 17 00:00:00 2001 From: Gusted Date: Sat, 19 Jun 2021 23:34:40 +0200 Subject: [PATCH 3/4] Update CHANGELOG.md Co-authored-by: Darien Maillet Valentine --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e152105b97b..fdeefb4f840 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ `--minify-syntax` will now minify the `Infinity` keyword to `1/0` which is less in bytes. ```js - // Orginial code + // Original code const a = Infinity; const b = 0 * Infinity; From 7764a2a43812d471333883bdf193f4f34e8bdcdc Mon Sep 17 00:00:00 2001 From: Evan Wallace Date: Thu, 24 Jun 2021 12:11:20 -0700 Subject: [PATCH 4/4] fix correctness issues --- CHANGELOG.md | 14 +++--- internal/js_printer/js_printer.go | 33 ++++++++------ internal/js_printer/js_printer_test.go | 63 ++++++++++++++++++++++---- 3 files changed, 81 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eacaced3d81..51abf23aaec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,22 +6,20 @@ It's now possible to use `--target=es2021` to target the newly-released JavaScript version ES2021. The only difference between that and `--target=es2020` is that logical assignment operators such as `a ||= b` are not converted to regular assignment operators such as `a || (a = b)`. -* Minify Syntax `Infinity` to `1/0` +* Minify the syntax `Infinity` to `1 / 0` ([#1385](https://github.com/evanw/esbuild/pull/1385)) - `--minify-syntax` will now minify the `Infinity` keyword to `1/0` which is less in bytes. + The `--minify-syntax` flag (automatically enabled by `--minify`) will now minify the expression `Infinity` to `1 / 0`, which uses fewer bytes: ```js // Original code const a = Infinity; - const b = 0 * Infinity; - - // Output with "--mangle-syntax" - const a = 1/0; - - const b = 0 * 1/0; + // Output with "--minify-syntax" + const a = 1 / 0; ``` + This change was contributed by [@Gusted](https://github.com/Gusted). + ## 0.12.9 * Allow `this` with `--define` ([#1361](https://github.com/evanw/esbuild/issues/1361)) diff --git a/internal/js_printer/js_printer.go b/internal/js_printer/js_printer.go index cd3356d156d..6f2d060676b 100644 --- a/internal/js_printer/js_printer.go +++ b/internal/js_printer/js_printer.go @@ -2129,23 +2129,30 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla value := e.Value absValue := math.Abs(value) - infinity := "Infinity" - if p.options.MangleSyntax { - infinity = "1/0" - } - if value != value { p.printSpaceBeforeIdentifier() p.print("NaN") - } else if value == positiveInfinity { - p.printSpaceBeforeIdentifier() - p.print(infinity) - } else if value == negativeInfinity { - if level >= js_ast.LPrefix { - p.print("(-" + infinity + ")") - } else { + } else if value == positiveInfinity || value == negativeInfinity { + wrap := (p.options.MangleSyntax && level >= js_ast.LMultiply) || + (value == negativeInfinity && level >= js_ast.LPrefix) + if wrap { + p.print("(") + } + if value == negativeInfinity { p.printSpaceBeforeOperator(js_ast.UnOpNeg) - p.print("-" + infinity) + p.print("-") + } else { + p.printSpaceBeforeIdentifier() + } + if !p.options.MangleSyntax { + p.print("Infinity") + } else if p.options.RemoveWhitespace { + p.print("1/0") + } else { + p.print("1 / 0") + } + if wrap { + p.print(")") } } else { if !math.Signbit(value) { diff --git a/internal/js_printer/js_printer_test.go b/internal/js_printer/js_printer_test.go index c808210ffca..b711983d2a2 100644 --- a/internal/js_printer/js_printer_test.go +++ b/internal/js_printer/js_printer_test.go @@ -932,13 +932,60 @@ func TestAvoidSlashScript(t *testing.T) { expectPrintedMinify(t, "x = 1 << / script/.exec(y).length", "x=1<