Компилятор JIT недоступен после обновления angular

Я обновил приложение angular с angular 10 до 12. После обновления режим разработки работает нормально. Но в производственной сборке я получаю ошибку «JIT-компилятор недоступен». Я импортировал импорт '@angular/compiler'; также в файле main.ts. Я не смог найти возможной причины этой проблемы.

8 ответов

Фон

Ошибка может возникнуть при использовании устаревшего плагина (то есть того, который все еще использует View Engine вместо Ivy).

Согласно руководству Google по созданию библиотек с помощью Ivy , библиотеки могут распространяться в трех форматах: View Engine (теперь не рекомендуется), Partial-Ivy (рекомендуется) и Full-Ivy.

Приложения Ivy могут по-прежнему использовать формат View Engine с NGCC, но View Engine планируется удалить в Angular 13, поэтому авторы библиотеки должны использовать формат «частичного плюща» в дальнейшем.

Вот подробное описание изменений, если вам интересно.

Как исправить (3 шага)

1. Определите проблемный плагин.

Важно : если ваша конфигурация TerserPlugin использует ngDevMode: false, Angular выдаст общий JIT compiler unavailableошибка. Удаление флага (или использование ngDevMode: true) должен выявить более полезную ошибку, в которой плагин упоминается по имени. Если это не поможет, попробуйте мои советы по отладке в конце ответа.

2 . Попросите автора библиотеки обновить файл tsconfig.prod.json плагина:

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

3. Воспользуйтесь форматом, скомпилировав библиотеку с помощью Angular Linker, который в настоящее время доступен только как плагин Babel: @angular/compiler-cli/linker/babel

Короче говоря, добавьте это в конфигурацию Webpack и замените ng-click-outside с вашим собственным плагином:

      rules: [
{
  // Explicit rule to run the linker over partial libraries
  test: /.*\.(js|ts)$/,
  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: /.*\.(js|ts)$/,
  exclude: /node_modules/,
  use: [
    {loader: 'babel-loader'}, // Optional
    {loader: '@ngtools/webpack'}, // Required
    {loader: '@angular-devkit/build-optimizer/webpack-loader'}, // Optional
  ]
},

Благодарность за это решение принадлежит Роберту ван Хуселю из этого выпуска Github .

Советы по отладке

1. При отладке проблемы можно добавить import '@angular/compiler';в вашем файле main.ts (как это сделал OP), но это приведет к выводу JIT-компилятора в вашей сборке prod и не является настоящим исправлением. Не используйте JIT-компилятор в производстве.

2. Если вы по-прежнему не видите полезного сообщения об ошибке, полностью удалите Terser и убедитесь, что вы не подавляете ошибки сборки.

3. При исправлении проблем с Webpack в целом иногда может быть полезно создать новый проект Angular CLI, добавить свои плагины (или другой код) и посмотреть, будет ли он компилироваться. Если это так, то вы знаете, что проблема в вашей конфигурации Webpack, а не в Angular. Я также считаю полезным сравнить файлы конфигурации Angular CLI с моими собственными (хотя это утомительно).

Мы столкнулись с аналогичной проблемой при обновлении нашего приложения Angular до версии 12 с версии 11. Решение состояло в том, чтобы удалить из tsconfig.json

      "compilationMode": "partial" 

или установите его на

      "compilationMode": "full"

Поскольку «частичное» значение требуется только для библиотек, а не для полных угловых приложений.

У меня была такая же ошибка дляng buildпоколение. Приложение будет запускаться, но не будет работать с компонентами со стеком вызовов, сообщающим «Jit-компилятор не найден». Раньше у меня также были проблемы с компонентами, которые не были полностью созданы AOT, и я сохранял ссылку templateUrl, сообщая, что компонент не был скомпилирован, и если я вызывалresolveComponentResources()и ждать его. Я сделал код для этого с включенным компилятором. Все еще не работает. Я не ожидал, что встроенные файлы нуждаются в этом. Поэтому я перешел к решению. Решение, которое сработало для меня, было советом, предложенным @Stevethemacguy, — создать работающее автономное приложение с помощью инструментов ng. Таким образом, я могу сравнить свои собственные angular.json и tsconfig.json с теми, которые работали. Кроме того, я могу быстрее обрабатывать и тестировать изменения кода .

  1. При исправлении проблем с Webpack в целом иногда может быть полезно создать новый проект Angular CLI, добавить свои плагины (или другой код) и посмотреть, будет ли он собран. Если это так, то вы знаете, что проблема в вашей конфигурации Webpack, а не в Angular. Я также считаю полезным сравнить файлы конфигурации Angular CLI с моими собственными (хотя это утомительно).

Я добавил компилятор, чтобы увидеть работу приложения и другие вещи, а затем приступил к устранению причин, по которым нужен компилятор. После этого я удалил компилятор, и он работает.

Это моя конфигурация:

  1. Мой проект использует Websphere для обслуживания приложения, и итерация методом проб и ошибок в сборках AOT с websphere очень уныла.
  2. Цель состояла в том, чтобы перенести развертывание без AOT с angular v12 на сборку AOT v14. Но я получал много ошибок при выполнении.
  3. Поэтому я перешел на отдельное приложение, работающее сng serve.
  4. Я издевался над сервисами, которые производили json из веб-сферы, а затем мог выполнять его автономно.
  5. Я перенес образец приложения в версию v12 с помощью рекомендуемой команды angularng update @angular/core@14 @angular/cli@14при обновлении angular v13 до v14 , чтобы увидеть изменения кода, поскольку UntypedFormBuilder импортирует одно из них.
  6. Я также посмотрел на сгенерированный код webpack, чтобы проверитьɵfac,ɵcmp,ɵinjи другие методы, объявленные для сгенерированного javascript для аннотированных классов Component и NgModule. Некоторые компоненты не имели этих методов, что означает, что компилятор их не обрабатывал.
  7. Перед удалениемangularCompilerOptionsскомпилированный класс для компонента начальной загрузки не имеет свойства шаблона. В скомпилированном коде это свойство содержит скомпилированный шаблон javascript. Что-то не так с моей сборкой. Удаление angularCompilerOptions и копирование tsconfig.json плюс tsconfig.app.json в мое целевое приложение частично помогло.
  8. У меня также есть для полного приложения работающая сборка без AOT с использованием JIT-компилятора для v14 со всеми модулями, импортированными с использованием systemjs с прокладками systemjs.babel и картой импорта для решения путей импорта. Но эта сборка очень медленно запускает приложение в браузере (10 секунд на локальном хосте и 315 плюс запросы GET) и в любом случае предназначена только для рабочих процессов разработки. Поэтому сборка AOT обязательна. Теперь время запуска приложения на локальном хосте составляет менее 1 секунды.

Когда автономное приложение работало, я сравнил его с предыдущими файлами конфигурации и кода репо. После этого я исправил исходные коды и смог заставить проект работать.

Некоторые важные изменения:

  1. Я удалил специализированные angularCompilerOptions из tsconfig.app.json .
  2. Я добавил импорт CommonModule в каждый модуль, включающий мои компоненты. Без него вроде не работает. Браузер сообщает, что не может понять «ngIf», и это является следствием этого. Он работал на v12 без AOT.
  3. Я добавил импорт UntypedFormBuilder в каждый используемый компонент, поскольку мой устаревший код еще не использует Typed FormBuilder, что является новой функцией для angular v14.

Я обновил машинописный текст и использовал Angular 13, на самом деле все произошло, пока я хотел использовать мат-пагинатор и таблицы материалов.

Решение , которое я нашел, состоит в том, чтобы добавить код ниже в tsconfig.jsonфайл angularCompilerOptions:

        "enableIvy": false

Мои конфигурации package.json

      {
"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"
}

}

Моя конфигурация app.module.ts :

      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 {}

Я увидел следующую ошибку после обновления с Angular 11 до 13:

Изучив свой код, я обнаружил два декоратора в одном из своих компонентов. С Angular 11 два@Componentв одном компоненте не было создано никаких ошибок. Это выглядело примерно так:

      import { Component, OnInit } from '@angular/core'.

@Component({
  selector: 'app-landing',
  templateUrl: './landing.component.html',
  styleUrls: ['./landing.component.scss']
})

@Component({
  selector: 'app-landing',
  templateUrl: './landing.component.html',
  styleUrls: ['./landing.component.scss']
})

export class LandingComponent implements OnInit {
....

После удаления доп.@Component {...}, ошибка в Angular 13 была исправлена.

У меня была такая же проблема, у меня сработало переустановка всех угловых зависимостей с версией 12:

      NGV=12
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

Вышеупомянутое обновление всех зависимостей для компиляции, таких как веб-пакет и машинописный текст.

Убедитесь, что вы уже импортировали '@angular/compiler' на самом верху вашего main.tsфайл. После этого запустите это в своем package.json.

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

У меня была такая же ошибка, в моем случае это было из-за файла с неправильным конфигом.

Я создал новый проект с последней версией Angular (v14), скопировал новыйtsconfig.app.jsonвнутри моего проекта. И это работает сейчас.

Другие вопросы по тегам