Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring JS breaks variable scope #357

Open
ianleeder opened this issue Apr 17, 2023 · 5 comments
Open

Refactoring JS breaks variable scope #357

ianleeder opened this issue Apr 17, 2023 · 5 comments
Labels

Comments

@ianleeder
Copy link

Tested using 1.20.6

Describe the bug
NUglify refactors JS code, and moves variables inside block scope, breaking functions that reference that variable.

To Reproduce
This example uses C#11 raw string literals

using NUglify;

string testJs =
$$"""
document.addEventListener("DOMContentLoaded", () => {
    const body = document.querySelector("body");
    if (!body) {
      return;
    }
    const foo = 'bar'
    doIt();
    function doIt() {
        console.log(foo);
    }
  });
""";

UglifyResult uglified = Uglify.Js(testJs);
Console.WriteLine(uglified.Code);

Minified output or stack trace
The minified code:

document.addEventListener("DOMContentLoaded",()=>{function i(){console.log(t)}const n=document.querySelector("body");if(n){const t="bar";i()}})

You can clearly see (once formatted), that the variable t is no longer accessible by the function i:

document.addEventListener("DOMContentLoaded", ()=>{
    function i() {
        console.log(t)
    }
    const n = document.querySelector("body");
    if (n) {
        const t = "bar";
        i()
    }
}
)

Uncaught ReferenceError: t is not defined
at i

Excepted output code
Variable declaration should not be moved inside the if block.

@trullock
Copy link
Owner

If you change Const to Var does it still happen? What about Let?

@ianleeder
Copy link
Author

Changing the variable to var/let/const doesn't make a difference.

Running the same test without all this code inside an event handler works correctly, eg:

const body = document.querySelector("body");
if (!body) {
  return;
}
var foo = 'bar'
doIt();
function doIt() {
  console.log(foo);
}

Generates

function doIt(){console.log(foo)}const body=document.querySelector("body");if(!body)return;var foo="bar";doIt()

The guard-clause hasn't been inverted: if(!body)return;.

Also it no longer renames variables/functions.

@trullock trullock added the bug label Apr 19, 2023
@trullock
Copy link
Owner

The non-renaming is expected as they are in global scope (and be theoretically be used elsewhere)

Otherwise it does seem like a bug then

@caviyacht
Copy link

@trullock , any update on this? This is causing some odd issues that our team needs to constantly work around

@trullock
Copy link
Owner

Sorry, I don't get any time on this. PRs welcome and I'll merge them

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants