UglifyJS TypeError for constant reassignment

A few weeks ago, I was working on an enhancement to a component we have that would allow a developer to start using sets for applying filter logic to item properties that drive a table. This logic runs when choosing an option from a drop-down and then filters through all of the table rows and did support arrays but not sets.

Rather than adding another check to the inline series of tests, I extracted a new function that supported both Array#includes as well as Set#has. This change was quickly unit tested and verified on the page that was using the component in my development environment. A PR was opened, approved, and destined for the staging environment.

When I tested it in staging, it didn't work, not only that, but there was some other strange behavior on the page after my testing. Opening the Chrome console showed a very confusing message TypeError: Assignment to a constant variable. I was confused and went to the code that caused it, and there were no constants created in my new function. I continued to look on both my dev box as well as in Chrome at the staging code for about 10 minutes and could not piece things together. That is when I realized I was looking at my source maps in Chrome and not the actual uglified code. So I went to the bundle and had Chrome format it for me. It took a second to try and find the function in question, and I actually couldn't find it. So I went to the calling code, and it turned out that uglify inlined the function for me. The final code was a bit different than I wrote, but in the end, what did it matter?

UglifyJS Function Inlining

Well, it didn't only inline the function it added a "helpful" i=i, in the series of checks. In this scope, i happens to be a constant defined a little higher up.

UglifyJS constant reassignment

Now we have an issue where the production code is doing illegal things due to the output of the toolchain we use to build. After searching for some time, I found some settings that could be changed to stop the inlining, but it would be across the entire finalized output not just this one spot.

After some searching, I ended up on an open UglifyJS issue where multiple people mentioned renaming variables in the source could impact the final output. I renamed the variable, and in fact, it did solve my problem.

The question I'm hoping you're asking is, what was the rename? I changed value (which is not a very descriptive variable name) to chosenFilterValue. This resulted in different Uglified code, which I am assuming is due to the way Uglify chose to name things based on their frequency of use in the final output. A generic variable like value is used almost 300 times over our entire frontend codebase, and the new name is used only in that one instance.

Resources: