JIT compiler unavailable after angular update

Viewed 13944

I have updated an angular application from angular 10 to angular 12. After updating development mode works fine. But in production build I am getting "JIT compiler unavailable" error. I have imported '@angular/compiler'; in the main.ts file also. I couldn't find any possible reason for this issue.

7 Answers

Background

The JIT compiler unavailable error can occur when using an outdated plugin (i.e. one that still the uses View Engine instead of Ivy).

According to Google's Building Libraries with Ivy guide, libraries can be distributed in 3 formats: View Engine (now deprecated), Partial-Ivy (recommended), and Full-Ivy.

Ivy apps can still consume the View Engine format with NGCC, but View Engine is slated to be removed in Angular 13, so library authors should use the "partial-Ivy" format moving forward. Here's a deep dive about the change.

How To Fix (3 steps)

1. Identify the problematic plugin.

Important: If your TerserPlugin config uses ngDevMode: false, Angular will throw a generic JIT compiler unavailable error. Removing the flag (or using ngDevMode: true) should reveal a more useful error that mentions the plugin by name. If that doesn't help, try my debugging tips at the end of the answer. Be sure to set ngDevMode back to false once the issue is fixed; it can have a large impact on bundle size.

2. Ask the library author to update the plugin's tsconfig.prod.json file:

"angularCompilerOptions": {
   "enableIvy": false // Remove this line or use true
   "compilationMode": "partial" // Add this line
}

3. Consume the format by compiling the library using the Angular Linker, which is currently only available as a Babel plugin: @angular/compiler-cli/linker/babel

In short, add this to your Webpack config and replace ng-click-outside with your plugin(s):

rules: [
{
  // Explicit rule to run the linker over partial libraries
  test: /.*\.js$/,
  include: /node_modules\/ng-click-outside/,
  use: [
    {
      loader: 'babel-loader',
      options: {
        configFile: false,
        plugins: ['@angular/compiler-cli/linker/babel'], // Required!
      }
    }
  ]
},
{
  // Regular rule for all non-library files
  test: /\.[jt]sx?$/,
  exclude: /node_modules/,
  use: [
    {loader: 'babel-loader'}, // Optional
    {
      loader: '@ngtools/webpack', // Required
      options: {
        directTemplateLoading: false, // See https://www.npmjs.com/package/@ngtools/webpack
      }
    },
    {loader: '@angular-devkit/build-optimizer/webpack-loader'}, // Optional
  ]
},

Credit for the webpack config goes to Robert van Hoesel from this Github issue.

Debugging Tips

1. While debugging the problem, you can add import '@angular/compiler'; in your main.ts file (as the OP has done), but this will output the JIT compiler in your prod build and isn't a real fix. Do not use the JIT compiler in production.

2. If you still don't see a useful error message, remove Terser completely and make sure you're not suppressing build errors.

3. When fixing Webpack issues in general, it can sometimes be useful to create a new Angular CLI project, add your plugins (or other code), and see if it builds. If it does, then you know your Webpack config is the problem, not Angular. I also find it useful to compare Angular CLI's config files with my own (though it's tedious).

We've faced similar issue while upgrading our Angular app to v12 from v11. The solution was to remove from tsconfig.json

"compilationMode": "partial" 

or set it to

"compilationMode": "full"

As "partial" value only required for the libraries and not the full angular apps.

I had the same issue, it worked for me that re-install all angular dependencies with 12 version:

NGV=12.2.9
npm i \
@angular-devkit/build-angular@$NGV \
@angular-devkit/core@$NGV \
@angular/animations@$NGV \
@angular/common@$NGV \
@angular/compiler@$NGV \
@angular/core@$NGV \
@angular/forms@$NGV \
@angular/platform-browser@$NGV \
@angular/platform-browser-dynamic@$NGV \
@angular/router@$NGV \
@angular/cli@$NGV \
@angular/compiler-cli@$NGV \
typescript@4.2.3 \
zone.js@~0.11.4 --force

The above update all dependencies for compiling like webpack and typescript

I have updated typescript and using Angular 13, actually all happened while I wanted to use mat-paginator and tables of material.

Solution that I found is to add code below to tsconfig.json file angularCompilerOptions :

  "enableIvy": false

My package.json configurations

{
"name": "client",
"version": "0.0.0",
"scripts": {
    "ng": "ng",
    "start": "ng build --watch",
    "build": "ng build --prod",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
},
"private": true,
"dependencies": {
    "@angular/animations": "~13.0.0",
    "@angular/cdk": "^13.1.3",
    "@angular/common": "~13.0.0",
    "@angular/compiler": "~13.0.0",
    "@angular/core": "~13.0.0",
    "@angular/forms": "~13.0.0",
    "@angular/material": "^13.1.3",
    "@angular/platform-browser": "~13.0.0",
    "@angular/platform-browser-dynamic": "~13.0.0",
    "@angular/router": "~13.0.0",
    "@fortawesome/angular-fontawesome": "^0.9.0",
    "@fortawesome/fontawesome-svg-core": "^1.2.36",
    "@fortawesome/free-solid-svg-icons": "^5.15.4",
    "@ng-bootstrap/ng-bootstrap": "^11.0.0-beta.2",
    "@ngx-loading-bar/core": "^5.1.1",
    "@ngx-loading-bar/http-client": "^5.1.1",
    "@ngx-loading-bar/router": "^5.1.1",
    "bootstrap": "^5.0.0",
    "bootstrap-icons": "^1.7.2",
    "moment": "^2.29.1",
    "rxjs": "~7.4.0",
    "tslib": "^2.3.0",
    "zone.js": "~0.11.4"
},
"devDependencies": {
    "@angular-devkit/build-angular": "~13.0.2",
    "@angular/cli": "~13.0.2",
    "@angular/compiler-cli": "~13.0.0",
    "@types/jasmine": "~3.10.0",
    "@types/node": "^12.11.1",
    "jasmine-core": "~3.10.0",
    "karma": "~6.3.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.0.3",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "~1.7.0",
    "typescript": "~4.4.3"
}

}

My app.module.ts configuration:

import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common

/http';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { LoadingBarModule } from '@ngx-loading-bar/core';
import { LoadingBarHttpClientModule } from '@ngx-loading-bar/http-client';
import { LoadingBarRouterModule } from '@ngx-loading-bar/router';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { LoginComponent } from './login/login.component';
import { Api } from './services/api.service';
import { BrowserInterceptor } from './services/browser.interceptor';
import { PublicVars } from './services/publicVars.service';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';




@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    HomeComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserModule,
    AppRoutingModule,
    NgbModule,
    HttpClientModule,
    FormsModule,
    ReactiveFormsModule,
    LoadingBarModule,
    LoadingBarRouterModule,
    LoadingBarHttpClientModule,
    FontAwesomeModule,
    BrowserAnimationsModule,


  ],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: BrowserInterceptor,
      multi: true,
    },
    Api,
    PublicVars,
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

I saw the following error after upgrading from Angular 11 to 13:

enter image description here

After investigating my code I found a couple of @Component {...} decorator and its elements (i.e. selector, template, and styles) in one of my components. It seems Angular 11 has no issues with this duplication.

I had the same error, in my case it was due to the tsconfig.app.json file with a wrong config.

I have created a new project with the last Angular version (v14), copy the new tsconfig.app.json inside my project. And it is working now.

Make sure you have already imported '@angular/compiler' at the very top of your main.ts file. After that run this in your package.json.

scripts{
 "postinstall": "ngcc --properties es5 browser module main --first-only"
}
Related