Folks, today I'm not going to talk about vague stuff, just about a big pit I stepped into in the past two days and how I climbed out. Here's the thing: we have an old project online that was running fine, but recently users reported occasional white screens. The error rate wasn't high, but given the large user base, a pile of error logs flooded my inbox every day. At first, I thought it was a backend API issue, but after checking, there was nothing wrong. Then I looked at the frontend monitoring and was dumbfounded—all JS errors, concentrated in that minified bundle file.
You know, production JS is minified, with tens of thousands of characters per line, making error messages unreadable. I stared at that "Unexpected token" for a long time, feeling like it was mocking me. Eventually, I enabled sourcemaps to locate the issues and found that the errors were varied but had a common thread: they all involved code inside conditional checks or used ES6+ syntax.
That's when I realized the problem might be in the compression configuration. Our project used an older compression tool, and at the time, for convenience, we just used the default config without looking closely. Some optimization options in the default config, like "drop_debugger" and the tricks in "compress", were a disaster for old code.
Let me give you the most typical example: the compression tool by default deletes conditional branches it thinks are "always false." For instance, you write if (typeof window !== 'undefined') to be compatible with SSR or to prevent errors in certain special environments. But to the compressor, this check is redundant because it analyzes the context and assumes window definitely exists, so it removes the entire if block. As a result, on real devices, in some WebView environments, certain properties of window are inaccessible, and the code crashes directly.
Another even trickier issue: the compressor renames variables inside functions to extremely short names, like changing userName to a and orderList to b. This is fine most of the time, but if your code uses eval or new Function that reference external variable names, after compression the names won't match, leading to ReferenceError. We had a few old modules using this, which were fine normally but broke after compression.
So, after much thought, I spent an afternoon studying the compression config. After making changes, guess what? Online errors dropped by 80%! It's not superstition; it's just that the config wasn't set correctly.
Here are the specific changes I made—you might want to jot them down; they could save you one day:
First, disable conditionals and dead_code in the compress option. This prevents the tool from being too clever and deleting code branches. Although this slightly reduces compression ratio, maybe adding a few KB, it's worth it for stability. Especially for old projects full of compatibility checks, these two options are time bombs.
Second, set eval in mangle to true. This means if the code detects eval or new Function, it won't rewrite variable names inside them, or it will keep those variables unshortened. This reduces compression effectiveness, but it's better than crashing online.
Third, I also turned off unused in compress. This option removes parameters that are "defined but not used." But sometimes, we intentionally leave a parameter as a placeholder, like in callback functions where the third parameter is useful, and the first two are fixed signatures. The compressor doesn't know that; it sees the first two are unused and deletes them, causing callback parameters to shift, resulting in undefined when called, messing up the logic.
Fourth, and most easily overlooked, is the ascii_only setting in output. If your code contains Chinese characters or emoji strings, I recommend setting this to false; otherwise, it will convert them all to escape sequences like \uXXXX. Although functionally the same, the string length explodes, and some old browsers have issues parsing overly long strings, which can cause freezes or errors.
Anyway, my current config is basically "mind your own business" mode. The purpose of compression is to reduce size, but if you break functionality to reduce size, the saved bandwidth isn't worth the overtime pay. After changing the config, I calculated that the bundle size only increased by about 15%, but the online error rate dropped from hundreds per day to single digits. That size increase is nothing.
One last reminder: after changing the compression config, be sure to run a full regression test, especially for areas involving route lazy loading and dynamic imports. Don't ask me why I know; it's a long story. Anyway, now the online environment is stable, and I can sleep well. If you have similar issues, don't doubt your code logic; first check if your compression config is causing more harm than good.