Continuing my plan to write about anything and everything that I lose more than an hour on, let's turn our attention to JavaScript minification and code patterns that may function perfectly well when executed on their own, but will break when minified. There are a variety of JavaScript minifiers out there, so I'm not going to try and say anything specific about what particular minifiers do. However, as recently came to my attention, you cannot count on minifiers preserving the uniqueness of the output of the .name
attribute on a JavaScript class, let alone the value of the name itself.
This, of course, is no huge surprise, especially given that JavaScript classes are pretty much just syntactic sugar themselves. Nevertheless, it's the kind of thing that always bears repeating, even when you think you know it. The even more general lesson worth drawing from this bug is that the hackier the solution, the less likely it is to stand up to changes in the environment or to optimizations performed by a particular compiler, and that you should always test the version you're going to distribute, be that version compiled, minified, or even just deployed to a different server than the one you're using for testing. Just because it worked once doesn't mean it will work again, even in two theoretically identical environments.
In the case of my specific bug, I was using the .name
attributes of JavaScript classes as indexes into a cache, in which instances of the classes were stored. In the minified version, unfortunately, all of the classes ended up with the same value assigned to .name
(presumably undefined
, although I never checked those particular values in the debugger). After spending hours and hours trying to and failing to see a bug in my non-minified code, I eventually discovered the real issue upon noticing that the wrong value was being retrieved from the cache, having been overwritten by a different object that should have been assigned a distinct index.
At any rate, the entire exercize was a good lesson in the fact that code transformation is often imperfect (and doubly so if the source language is as convoluted as JavaScript).