javascriptangulartypescript

Enabling optimization breaks Angular site for no apparent reason


I'm currently using Angular to build a front-end website to search for and display information obtained via API queries. When I use ng build to compile the project into a file bundle for static deployment, the resulting bundle only works properly if I use the --optimization false option when building. If I enable optimization, trying to access the site produces a variety of runtime errors.

The runtime errors do not appear to be consistent – seemingly arbitrary changes in my code lead to entirely different errors showing up when I try to access the site. It's also not possible to easily figure out what's causing the errors, both because of the minified object/function names and the fact that every single error gets traced back to the following line in main.js and no further:

platformBrowserDynamic().bootstrapModule(AppModule).catch(err => console.error(err));

Here are some of the errors that have appeared – but as mentioned earlier, the specific errors produced seem to change whenever I make changes to my code:

Disabling optimization when building the file bundle completely resolves all of these issues, and the resulting site runs fine with no errors. However, I'd rather not leave my site permanently unoptimized, since the file size of the unoptimized bundle is significantly larger, and the optimization presumably comes with various other improvements as well.

Any ideas on why optimization might be breaking the site, and how to prevent that from happening in the future, would be greatly appreciated.


Solution

  • I had a similar problem with my angular app production build with optimization. It was quite a peculiar problem regarding how I would use the built files but it seems like you have similar problems.

    I had similar error messages which would sometimes change and not make a lot of sense. I found out that it was linked with mangled names used for the minification process done by esbuild, because during debugging I found out that my main.js would have a top-level function with the same name as a var declared in polyfills.js, then the latter (var se=...) would be overwritten by the former (function se() {...}). That's why while debugging the error in polyfills.js I would find a function from main instead of the initial object, leading to obvious unexpected errors.

    And looking at some of your error messages, you may have similar mangled names conflict problems as almost all your errors imply that the problematic variables don't have the expected types ("x is not a function", "reading '3'"), so they may also have been overwritten by some other file.

    In my case the actual problem was because of the way the built scripts would be used in the index.html, as in fact I was not using the built index.html, because I wanted to generate FreeMarker templates ftl files. And my mistake was that in my handwritten index.ftl I was importing the main and polyfills scripts like this :

    <script src="${script}" type="text/javascript"></script>
    

    Instead of this :

    <script src="${script}" type="module"></script>
    

    After this change, everything would work fine because, as described in the js module doc :

    Module-defined variables are scoped to the module unless explicitly attached to the global object.

    Hence the global scope variables mix-up while using type="text/javascript". When using true modules in index.html, then their scopes cannot "collide" and overwrite one another.

    I don't know if you have such a specific production build as I do, but you might want to find out what js files are interfering with each other by debugging the errors, or trying to find the variable name in error in different files. Then, you can try to understand why their scopes are getting mixed-up in the end.