Open AshleyScirra opened 5 years ago
With a bit more investigation, it looks like adding an extra statement to the scope prevents the bug happening. We came across this with real-world code like this:
{
const NAMESPACE = self.foo = class Foo {
constructor() { /* something using NAMESPACE */ }
}
}
This uses a scope with a single const
declaration inside (triggering the bug), but also declares a global variable with a class declaration. The scope gets removed though, so when this pattern is used more than once, the NAMESPACE
declaration is duplicated in the outer scope.
Describe the bug
babel-minify sometimes eliminates a scope (i.e. pairs of braces, e.g.
{ ... }
) when it is unsafe to do so, resulting in broken code.To Reproduce
Actual Output
Note the enclosing scope was removed. This defeats the purpose of using the scope to prevent namespace pollution in the outer scope.
Expected Output
Note the enclosing scope is preserved. This avoids the
const
declaration using its name in the outer scope.Another way to demonstrate how this is an incorrect optimisation is the following code:
This fails to minify, because babel-minify renames both
const
declarations toa
, removes both enclosing scopes, and then crashes withDuplicate declaration "a"
.Configuration
Demo URL:
https://babeljs.io/en/repl#?babili=true&browsers=&build=&builtIns=false&spec=false&loose=false&code_lz=N4KABBYMYPYHYGcAuYBmMZgLxgIwG4QBfEEUSaeZMAIwEMAnbMAJkKKA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=false&presets=babili&prettier=false&targets=&version=6.26.0&envVersion=
Possible solution
It looks like the only safe option is to entirely avoid variable declarations in scopes. This is very difficult if you are using classic mode scripts and use a file-level scope to avoid polluting the global namespace.