Компилятор 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 с теми, которые работали. Кроме того, я могу быстрее обрабатывать и тестировать изменения кода .
- При исправлении проблем с Webpack в целом иногда может быть полезно создать новый проект Angular CLI, добавить свои плагины (или другой код) и посмотреть, будет ли он собран. Если это так, то вы знаете, что проблема в вашей конфигурации Webpack, а не в Angular. Я также считаю полезным сравнить файлы конфигурации Angular CLI с моими собственными (хотя это утомительно).
Я добавил компилятор, чтобы увидеть работу приложения и другие вещи, а затем приступил к устранению причин, по которым нужен компилятор. После этого я удалил компилятор, и он работает.
Это моя конфигурация:
- Мой проект использует Websphere для обслуживания приложения, и итерация методом проб и ошибок в сборках AOT с websphere очень уныла.
- Цель состояла в том, чтобы перенести развертывание без AOT с angular v12 на сборку AOT v14. Но я получал много ошибок при выполнении.
- Поэтому я перешел на отдельное приложение, работающее с
ng serve
. - Я издевался над сервисами, которые производили json из веб-сферы, а затем мог выполнять его автономно.
- Я перенес образец приложения в версию v12 с помощью рекомендуемой команды angular
ng update @angular/core@14 @angular/cli@14
при обновлении angular v13 до v14 , чтобы увидеть изменения кода, поскольку UntypedFormBuilder импортирует одно из них. - Я также посмотрел на сгенерированный код webpack, чтобы проверить
ɵfac
,ɵcmp
,ɵinj
и другие методы, объявленные для сгенерированного javascript для аннотированных классов Component и NgModule. Некоторые компоненты не имели этих методов, что означает, что компилятор их не обрабатывал. - Перед удалением
angularCompilerOptions
скомпилированный класс для компонента начальной загрузки не имеет свойства шаблона. В скомпилированном коде это свойство содержит скомпилированный шаблон javascript. Что-то не так с моей сборкой. Удаление angularCompilerOptions и копирование tsconfig.json плюс tsconfig.app.json в мое целевое приложение частично помогло. - У меня также есть для полного приложения работающая сборка без AOT с использованием JIT-компилятора для v14 со всеми модулями, импортированными с использованием systemjs с прокладками systemjs.babel и картой импорта для решения путей импорта. Но эта сборка очень медленно запускает приложение в браузере (10 секунд на локальном хосте и 315 плюс запросы GET) и в любом случае предназначена только для рабочих процессов разработки. Поэтому сборка AOT обязательна. Теперь время запуска приложения на локальном хосте составляет менее 1 секунды.
Когда автономное приложение работало, я сравнил его с предыдущими файлами конфигурации и кода репо. После этого я исправил исходные коды и смог заставить проект работать.
Некоторые важные изменения:
- Я удалил специализированные angularCompilerOptions из tsconfig.app.json .
- Я добавил импорт CommonModule в каждый модуль, включающий мои компоненты. Без него вроде не работает. Браузер сообщает, что не может понять «ngIf», и это является следствием этого. Он работал на v12 без AOT.
- Я добавил импорт 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
внутри моего проекта. И это работает сейчас.