【问题标题】:angular-cli build prod "Runtime compiler is not loaded”angular-cli build prod“未加载运行时编译器”
【发布时间】:2017-03-09 21:50:14
【问题描述】:

我做了 ng build -prod 并遇到了一个奇怪的错误,即 _zone_symbol__错误 :

Error: Uncaught (in promise): Error: Runtime compiler is not loaded Error: Runtime compiler is not loaded at d (http://localhost:4200/polyfills.cd321326a3dfc08ceb46.bund

我没有在我的应用程序中手动使用编译器。最奇怪的是错误似乎来自 polyfill。 我该如何解决这个问题?

【问题讨论】:

    标签: angular angular-cli


    【解决方案1】:

    在我的情况下,它可以禁用构建的提前编译

    ng build -prod --aot=false
    

    这样源代码仍然被打包和丑化,并且包括即时编译器。

    main.bundle js 文件比使用 aot 编译时要小,但 vendor.bundle js 增加了大约 1.5 MB。

    编辑 2018-07-11

    好像有两种情况:

    1) 如果您的项目有意创建真正的动态组件,目前包含 JIT 编译器的唯一方法似乎是禁用生产构建的 AOT。请参阅https://github.com/angular/angular/issues/11780 进行讨论

    2) 如果您的项目不需要需要动态创建组件并且您不知道为什么会发生错误,则禁用 AOT 可能是一种解决方法,但请注意缺点。如果没有 AOT,您的文件会更大,并且用户开始使用您的应用程序需要更长的时间。在这种情况下,调查生产构建中引用 JIT 编译器的原因可能更合适。

    有一些 SO 讨论(AngularCli & AOT: ERROR Error: Runtime compiler is not loadedTrouble shoot "Runtime compiler is not loaded")表明延迟加载使用“COMPILER_PROVIDERS”的第三方模块可能是错误的原因。但在撰写本文时,他们还没有公认的答案。

    有关使用延迟加载模块时的另一个陷阱的描述,请参阅此线程中 Alexei 的答案

    【讨论】:

    • 如果你禁用 AOT,它会开始使用 JIT 编译来添加编译器,但是如果你关心包大小,这不是正确的方法。
    • 是的。但如果您需要浏览器中的 JIT 编译器,禁用 AOT 是我知道的唯一方法。你知道另一种解决方案吗?
    • +1。我之所以使用它,是因为我在 Angular 5 中收到错误并且不清楚原因(我没有使用编译器类)。 vendor.bundle.js 确实大很多,但是如果不经常更改,浏览器会缓存它(Chrome 开发工具经常告诉它从磁盘缓存中读取文件)。
    • 感谢 Alexei 和 Andurit。您的 cmets 向我明确表示,至少有两种情况可能导致错误。我相应地编辑了我的答案。
    • 谢谢@c_froehlich 它对我有用。我正在使用 Angular 7 的 Node 10.15.3。我使用的是延迟加载,但如果我们构建“ng build --prod”,则默认情况下启用 aot 和 buildOptimizer 并且它有问题。通过在 angular.json 生产属性中将 aot 和 buildOptimizer 设为 false,我解决了我的问题。谢谢你的回答。
    【解决方案2】:

    Necromancing...我收到了同样的错误,但没有明确使用编译器,所以花了一段时间才明白发生了什么。

    在延迟加载某些模块时,AOT 似乎无法确定需要哪些模块as indicated in this thread。结果是最终构建将不包含这些模块,并且当需要它们时,应用程序将尝试即时编译它们并由于编译器不可用而失败。

    here 提供了解决方案,对我来说它是这样工作的:

    export function getSomeModule() { return SomeModule; }
    
    export const routes: Routes = [
      // some routes here
      { path: "some", loadChildren: "./some/some.module#SomeModule" }
    ]; 
    

    因此,模块的路径被指出,AOT 也将通过getSomeModule 函数知道SomeModule(代码中没有使用,但帮助 AOT 包含模块)。

    【讨论】:

    • 保留 SomeModule 导入会导致 this post 中提到的问题,这会导致 ng serve 失败。我也尝试过使用 AOT,但没有导入 SomeModule 也没有导出函数,到目前为止它似乎工作正常。可能值得更多讨论
    【解决方案3】:

    在您的代码中使用compiler class 进行生产构建(ng build -prod)时,@angular/cli@1.0.0-rc.2 会发生这种情况。

    要替换compiler,您需要使用“动态组件创建”。看到这个:

    .


    另外,检查您是否正在导入 polyfills.ts

    我可以通过将我的 @angular/cli@1.0.0-rc2 项目与新搭建的 CLI 项目进行比较来解决这个问题,并注意到 polyfills.ts 除了在 .angular-cli.json 之外的任何地方都没有导入

    例如,我在main.ts中导入polyfills.ts

    import 'polyfills.ts'; // Remove this line
    import { enableProdMode } from '@angular/core';
    import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
    
    import { AppModule } from './app/app.module';
    import { environment } from './environments/environment';
    
    if (environment.production) {
      enableProdMode();
    }
    
    platformBrowserDynamic().bootstrapModule(AppModule);
    

    Polyfill.ts 只需要在 .angular-cli.json 这里:

    ...
      "index": "index.html",
      "main": "main.ts",
      "polyfills": "polyfills.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.app.json",
    ...
    

    复制:

    【讨论】:

      【解决方案4】:

      我在尝试动态生成 ViewChild 时遇到了同样的错误。这与延迟加载略有不同,但它与本期的标题相匹配,因此我将在此处添加我的 2 美分,以防它对任何人有所帮助。

      由于我在代码中明确使用了编译器,因此我需要将其包含在输出包中。我这样做很简单:

      ng build --aot=false --buildOptimizer=false
      

      我知道没有人喜欢关闭优化器,但在这种情况下,优化器是导致问题的原因,通过“优化”编译器。

      请注意,输出仍然是最小化/丑化的,因为如果您想获得可读的输出,则有一个单独的标志:

      ng build --aot=false --buildOptimizer=false --optimization=false
      

      【讨论】:

        【解决方案5】:

        适用于 Angular 9+

        因为这是搜索此错误时首先弹出的内容,所以我只想补充一下,您在执行时也会出现此内容:

        const routes = [{
            path: '',
            component: ProfileComponent,
            children: [
                {
                    path: '',
                    loadChildren: () => import('./profile-about/profile-about.module') // .then(m => m.ProfileAboutModule) is missing here
                }
            ]
        }];
        

        而不是

        const routes = [{
            path: '',
            component: ProfileComponent,
            children: [
                {
                    path: '',
                    loadChildren: () => import('./profile-about/profile-about.module').then(m => m.ProfileAboutModule)
                }
            ]
        }];
        

        注意:.then(m => m.ProfileAboutModule)

        .then(m => m.ProfileAboutModule) 缺失时,Angular 编译器也会抛出Runtime compiler is not loaded 错误,所以也要注意这一点。

        【讨论】:

        • 我有这个问题...我不明白 .then(m => m.ProfileAboutModule) 怎么可能丢失?
        • @Doflamingo19 好吧,那是因为你没有在那里添加它。您需要添加该部分。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-02-03
        • 1970-01-01
        • 1970-01-01
        • 2020-12-03
        • 1970-01-01
        • 2019-07-08
        • 1970-01-01
        相关资源
        最近更新 更多