我目前正在使用 Angular 构建一个前端网站,用于搜索和显示通过 API 查询获得的信息。当我使用
ng build
将项目编译成文件包以进行静态部署时,只有在构建时使用 --optimization false
选项,生成的包才能正常工作。如果我启用优化,尝试访问该站点会产生各种运行时错误。
运行时错误似乎不一致——我的代码中看似任意的更改导致当我尝试访问该网站时出现完全不同的错误。也不可能轻松找出导致错误的原因,因为对象/函数名称被缩小,而且每个错误都会追溯到
main.js
中的以下行,仅此而已:
platformBrowserDynamic().bootstrapModule(AppModule).catch(err => console.error(err));
以下是出现的一些错误 - 但正如前面提到的,每当我更改代码时,产生的具体错误似乎都会发生变化:
TypeError: rt is not a function
Cannot read properties of undefined (reading '3')
Uncaught TypeError: Class constructor xe cannot be invoked without 'new'
Uncaught (in promise) TypeError: He is not a function
在构建文件包时禁用优化可以完全解决所有这些问题,并且生成的网站运行良好,没有错误。但是,我不想让我的网站永久处于未优化状态,因为未优化捆绑包的文件大小明显更大,并且优化可能还伴随着各种其他改进。
任何关于为什么优化可能会破坏网站以及如何防止将来发生这种情况的想法,我们将不胜感激。
我的 Angular 应用程序生产构建和优化也遇到了类似的问题。 关于我如何使用构建的文件,这是一个非常奇怪的问题,但似乎你也有类似的问题。
我有类似的错误消息,有时会改变并且没有多大意义。我发现它与 ebuild 完成的缩小过程中使用的损坏名称相关联,因为在调试过程中我发现我的 main.js 将有一个顶级函数,其名称与 polyfills.js 中声明的 var 相同,那么后者 (var se=...) 将被前者 (function se() {...}) 覆盖。 这就是为什么在调试 polyfills.js 中的错误时,我会从 main 而不是初始对象中找到一个函数,从而导致明显的意外错误。
查看一些错误消息,您可能会遇到类似的错误名称冲突问题,因为几乎所有错误都暗示有问题的变量不具有预期的类型(“x 不是函数”、“读取 '3'” ),因此它们也可能已被其他文件覆盖。
在我的例子中,实际的问题是因为在index.html中使用构建的脚本的方式,事实上我没有使用构建的index.html,因为我想生成FreeMarker模板ftl文件。 我的错误是,在我手写的 index.ftl 中,我导入了 main 和 polyfills 脚本,如下所示:
<script src="${script}" type="text/javascript"></script>
而不是这个:
<script src="${script}" type="module"></script>
进行此更改后,一切都会正常工作,因为如js模块文档中所述:
模块定义的变量的范围仅限于模块,除非显式附加到全局对象。
因此,在使用 type="text/javascript" 时,全局范围变量会混淆。 当在index.html中使用真正的模块时,它们的范围不能“冲突”并相互覆盖。
我不知道你是否有像我一样的特定生产版本,但你可能想通过调试错误来找出哪些js文件相互干扰,或者尝试在不同文件中查找错误的变量名。然后,你可以尝试理解为什么他们的范围最终会变得混乱。