angular: Error: Runtime compiler is not loaded in angular6 --prod mode

I’m submitting a…


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
[ ] Other... Please describe:

Current behavior

I was dynamically creatingn a component in angular5 .After migrating my app to angular6 it doesnt work.

export class HtmlOutletDirective implements OnChanges {
  @Input() html: string;
  constructor(private vcRef: ViewContainerRef, private compiler: Compiler, private translate: TranslateService) {
  }

  ngOnChanges() {
    const html = this.html;
    if (!html) { return; }

    @Component({
      selector: 'ccw-dynamic-component',
      template: `
        <div [innerHtml]="innerHtmlTemplate">
        </div>
        `
    })

    class DynamicHtmlComponent {
      private innerHtmlTemplate: any = '';
      constructor(private httpClient: HttpClient, private sanitizer: DomSanitizer) {
        this.httpClient.get(html, { responseType: 'text' }).subscribe((htmlContent) => {
          this.innerHtmlTemplate = sanitizer.bypassSecurityTrustHtml(htmlContent.toString());
        });
      }
    }

    @NgModule({
      imports: [CommonModule],
      declarations: [DynamicHtmlComponent]
    })

    class DynamicHtmlModule { }

    this.compiler.compileModuleAndAllComponentsAsync(DynamicHtmlModule)
      .then(factory => {
        const compFactory = factory.componentFactories.find(x => x.componentType === DynamicHtmlComponent);
        const compRef = this.vcRef.createComponent(compFactory, 0);
      });


  }

This used to generate a component for me based on path specified.It used to work perfectly in dev/prod both.However after updating the app to angular6. It is not working in production. It gives me the below error: Generic error: Runtime compiler is not loaded logger.js:47 Error stack trace: Error: Runtime compiler is not loaded at Le (core.js:3286) at t.compileModuleAndAllComponentsAsync (core.js:3346) at l.ngOnChanges (html-outlet.directive.ts:52)

Expected behavior

the dynamic component should load

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


Angular version: 6.0.0


Browser:
- [x ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: 8.9.1
- Platform:  Windows

Others:

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 27
  • Comments: 23 (5 by maintainers)

Commits related to this issue

Most upvoted comments

Do not and i repeat do not import your feature modules in app module and also when addressing feature modules in your routes use this format, this can save you several hours buddy

{ path: 'auth', loadChildren: './modules/auth/auth.module#AuthModule' },
{ path: 'ingestion', loadChildren: './modules/ingestion-dashboard/ingestion-dashboard.module#IngestionDashboardModule'},

Do not use function signature

It sounds like you were running your application in the JIT mode in v5 but then switched over to the AOT mode in v6. The runtime compiler is not available and has never been available in the AOT mode unless you brought it yourself.

Can you please verify that you are bootstrapping your application with https://angular.io/api/core/PlatformRef#bootstrapModule (JIT mode) rather than https://angular.io/api/core/PlatformRef#bootstrapModuleFactory (AOT mode) or if you are using AngularCLI that you have AOT mode turned on in your angular.json, example: https://github.com/angular/angular/blob/23a98b9e5134df3b96dd932173ce86384d72ada0/aio/angular.json#L21

facing same issue

Do not and i repeat do not import your feature modules in app module and also when addressing feature modules in your routes use this format, this can save you several hours buddy

{ path: 'auth', loadChildren: './modules/auth/auth.module#AuthModule' },
{ path: 'ingestion', loadChildren: './modules/ingestion-dashboard/ingestion-dashboard.module#IngestionDashboardModule'},

Do not use function signature

The same was happening to me. @IgorMinar function signature breaks the aot build in prod mode. Should the issue be reopened?

@sandisototo Using loadChildren: () => HomeModule requires jit compiler. If you have a problem with loadChildren property that uses string then please create small reproduction

Do not and i repeat do not import your feature modules in app module and also when addressing feature modules in your routes use this format, this can save you several hours buddy

{ path: 'auth', loadChildren: './modules/auth/auth.module#AuthModule' },
{ path: 'ingestion', loadChildren: './modules/ingestion-dashboard/ingestion-dashboard.module#IngestionDashboardModule'},

Do not use function signature

Same thing happened to me. Nice catch @shanurrahman

Just sharing my rare experience, as it can help someone else.

I had two submodules with the same path ./app/apps.module#AppsModule in two different modules. Due to a known issue in angular https://github.com/angular/angular-cli/issues/10128, I couldn’t get this dynamically loaded using LoadChildren.

I tried to use LoadChildrenCallback as a work around. But as I use AOT in production, I couldn’t get it done as well.

The workaround i did was to load the SubModules by navigating to the parent folder. ie in my module storage I added the submodule apps as below

const routes: Routes = [
    { path: 'apps', loadChildren: "../storage/apps/apps.module#AppsModule" },
];

In order to eagerly load modules with a function reference when AOT enabled for Angular 7, you need to create an NgFactory module as you can see from this PR - https://github.com/angular/angular/pull/13909.

A working solution for me was creating a clone of my module and adding .ngfactory postfix to the filename and also adding NgFactory postfix to the module class name.

import { FirstPageModuleNgFactory } from '../pages/first-page.module.ngfactory';
import { SecondPageModuleNgFactory } from '../pages/second-page.module.ngfactory';

export function loadFirstPageModule() {
    return FirstPageModuleNgFactory;
}

export function loadSecondPageModule() {
    return SecondPageModuleNgFactory;
}

const routes: Routes = [
    {
        path: '',
        component: HomePageComponent,
        children: [
            {
                path: '',
                redirectTo: 'first',
                pathMatch: 'full',
            },
            {
                path: 'first',
                loadChildren: loadFirstPageModule,
            },
            {
                path: 'second',
                loadChildren: loadSecondPageModule,
            },
        ],
    },
];

Changed in Angular 8. Angular 7 docs still has that: https://v7.angular.io/guide/lazy-loading-ngmodules